新手上路
- 积分
- 48
- 金钱
- 48
- 注册时间
- 2019-7-19
- 在线时间
- 12 小时
|
发表于 2019-11-19 10:04:52
|
显示全部楼层
本帖最后由 社会如此多娇 于 2019-11-19 10:07 编辑
在FREERTOS实时操作系统下使用原子的USB读卡器实验首先需要修改USB_OTG_BSP_uDelay 和USB_OTG_BSP_mDelay 函数,将其换成软件延时,软件延时如下所示(系统时钟168hz)
void s_delay_us(u32 us)
{
u8 i = 0;
while(us--)
{
i = 42;
while(i--);
};
}
void s_delay_ms(u32 ms)
{
u16 i = 0;
while(ms--)
{
i = 41750;
while(i--);
};
}
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
s_delay_us(usec);
}
void USB_OTG_BSP_mDelay (const uint32_t msec)
{
s_delay_ms(msec);
}
但是修改之后还是不能正常运行,找了很长时间的原因,发现会进入hardfult异常,原因是“试图切入ARM状态”。
先说原因吧,是因为ftl.c文件里的NAND_EraseBlock(source_block)函数调用了delay_ms(NAND_TBERS_DELAY)函数造成的,下面分析原因。
在实时操作系统下使用原子的USB读卡器例程,接上串口会出打印Error:..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,441,看port.c文件的441行,提示在中断中调用了API函数要以FromISR结尾。分析441行程序,void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++; /*临界区嵌套*/
if( uxCriticalNesting == 1 )
{
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); /*判断有没有中断发生*/
}
}
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) 中断控制状态寄存器,低8位数据减16为当前发生的终端编号
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); 该语句表示进入临界区,有中断发生就报错。
以上分析可知,之所以报错,程序运行错误,是因为进入临界区发生了中断,反过来也可以为正在执行中断函数,运行了包含进入临界区的函数的程序。
分析USB读卡器程序可以看出,所有USB相关的程序都是在OTG_FS_IRQHandler(void)中断函数中执行的,仿真只有在写文件时会出现上述错误。USB读卡器
底层使用的时ftl.c文件里的读写,该文件里的FTL_WriteSectors()写函数会调用FTL_CopyAndWriteToBlock();
FTL_CopyAndWriteToBlock()会调用NAND_EraseBlock(source_block);
而NAND_EraseBlock(source_block)调用了delay_ms(NAND_TBERS_DELAY)函数,
delay_ms(NAND_TBERS_DELAY)会执行xAlreadyYielded = xTaskResumeAll();语句,
xTaskResumeAll()里包含taskENTER_CRITICAL();也就是进入临界区函数,也就是在这里报错的,将NAND_EraseBlock(source_block)调用了delay_ms(NAND_TBERS_DELAY)改为软件延时则可以正常运行。
|
|