FreeRTOS系统下STM32F1芯片开启一个任务测试W25Q128异常
void xTaskFlashTest( void * pvParameters){
int32_t iTime1, iTime2;
printf("正在擦除整个芯片\r\n");
iTime1 = xTaskGetTickCount(); /* 记下开始时间 */
sf_EraseChip();
iTime2 = xTaskGetTickCount(); /* 记下结束时间 */
printf("擦除串行Flash完成!, 耗时: %dms\r\n", iTime2 - iTime1);
while(1)
{
}
}今天在调试W25Q128时候,开了一个任务用来测试擦写速度,任务优先级为1,按照历程上的现象SPI分频8的时候应该在50S左右擦完,
但是我在任务中擦除很快就擦完了,记录的时间是1600ms左右,再次复位就卡死(实则SPI在等待空闲位,因为任务调度前有读取ID的操作),后来和历程
一起测试了感觉是任务切换到导致的,就在擦除的时候加入了调度锁擦除正常了,但是还是不太清楚具体原因,是因为在擦除的时候任务切换导致读空闲
寄存器值没读到导致的么
static void sf_WaitForWriteEnd(void)
{
sf_SetCS(0); /* 使能片选 */
bsp_spiWrite1(CMD_RDSR); /* 发送命令, 读状态寄存器 */
while((bsp_spiRead1() & WIP_FLAG) == SET); /* 判断状态寄存器的忙标志位 */
sf_SetCS(1); /* 禁能片选 */
}
其它任务没有操作这个SPI总线吧,另外就是SPI是用的硬件SPI吧,别的没有要注意的了,如果仅只有这一个任务在操作,可以随意被抢占。 整个活,在while里加一句操作系统的延时,这样就不会浪费这种比较长时间,系统调度也不会出什么问题
/* 如果等待的时间比较短,参数填0,使用阻塞等待 */
/* 如果预估的时间较长,填入1,将使用操作的延时函数,这样在等待的时候可以做切走暂时做别的事 */
/* 像W25Q128JV给出的参数,4k擦除平均45ms,32k擦除平均120ms,64k擦除平均150ms,全片擦除40s */
static int32_t bsp_w25q128_wait_exit_busy ( uint32_t is_long )
{
volatile uint32_t t,k;
int32_t ret = 0;
bsp_w25q128_cs( 0 );
{
bsp_spi_rw( W25QXX_CMD_Read_Status_Register_1 );
k = 0xFFFFFFF;
while((bsp_spi_rw(0x00) & 0x01) != 0)
{
if ( is_long == 0 )
{
t = 0xFF;
while ( t-- );
}
else
{
osDelay( 2 );
}
k --;
if ( k == 0 )
{
ret = -1;
break;
}
}
}
bsp_w25q128_cs( 1 );
return ret;
}
eric2013 发表于 2023-3-15 00:25
其它任务没有操作这个SPI总线吧,另外就是SPI是用的硬件SPI吧,别的没有要注意的了,如果仅只有这一个任务 ...
没有,只有FLASH使用的硬件SPI总线,任务开了4个还有一个定时器的任务,因为SPI FLASH在擦除以及大数据读写的时候比较花费时间就把SPI读写任务放在比较低的优先级了,目前现象看上去就是因为切换导致的,在擦除的时候实际上一直在执行while((bsp_spiRead1() & WIP_FLAG) == SET);等待空闲标志,没太想清楚为啥任务切换会导致读取的返回出错 tovinz 发表于 2023-3-15 08:38
整个活,在while里加一句操作系统的延时,这样就不会浪费这种比较长时间,系统调度也不会出什么问题
意思就是在擦除的时候读取一次之后如果状态不符合就挂起任务一小会在读是吧,我下午试试 你说的这个调度锁是直接停止调度,直到你擦除完了再恢复调度的意思吗?
页:
[1]