根据FreeRTOS的设计,几乎可以认为系统没开跑前系统API都不能用
因为不管是信号量、队列、互斥锁还是任务结构体,使用前必须要创建,创建时一定会调用系统自带的内存管理,例如 heap_4只要调用了内存分配,必然会调用 vTaskSuspendAll(); 跟 xTaskResumeAll();
xTaskResumeAll() 最后调用了 taskEXIT_CRITICAL();
[AppleScript]
纯文本查看 复制代码
void vPortExitCritical( void ){configASSERT( uxCriticalNesting );uxCriticalNesting--;if( uxCriticalNesting == 0 ){portENABLE_INTERRUPTS();}}仔细看有一个操作系统的嵌套层数计数器进行了自减操作:uxCriticalNesting--;
这个变量在操作系统没开跑前的初始值并不是0: static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
问题就出在这了,因为初始值并不是0,所以 portENABLE_INTERRUPTS(); 是不会被执行的!!!
portENABLE_INTERRUPTS() 是啥?这是使能系统中断的接口,内存分配前系统屏蔽了中断,在操作系统启动后,内存分配完毕会重新开启中断
反之,在FreeRTOS的调度器没启动前,只要你调用了系统的内存管理,中断就会被关闭,而且关闭之后不会被打开!
我们一般都在串口中断里面调用了信号量API来通知APP,但信号量创建后中断就被关闭了,如果串口中断也在操作系统的管辖范围内
那么意味着串口中断也被屏蔽了,你说还能正常使用么?
根据FreeRTOS的设计,几乎可以认为系统没开跑前系统API都不能用
因为不管是信号量、队列、互斥锁还是任务结构体,使用前必须要创建,创建时一定会调用系统自带的内存管理,例如 heap_4只要调用了内存分配,必然会调用 vTaskSuspendAll(); 跟 xTaskResumeAll();
xTaskResumeAll() 最后调用了 taskEXIT_CRITICAL();
[AppleScript] 纯文本查看 复制代码
void vPortExitCritical( void ){configASSERT( uxCriticalNesting );uxCriticalNesting--;if( uxCriticalNesting == 0 ){portENABLE_INTERRUPTS();}}仔细看有一个操作系统的嵌套层数计数器进行了自减操作:uxCriticalNesting--;
这个变量在操作系统没开跑前的初始值并不是0: static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
问题就出在这了,因为初始值并不是0,所以 portENABLE_INTERRUPTS(); 是不会被执行的!!!
portENABLE_INTERRUPTS() 是啥?这是使能系统中断的接口,内存分配前系统屏蔽了中断,在操作系统启动后,内存分配完毕会重新开启中断
反之,在FreeRTOS的调度器没启动前,只要你调用了系统的内存管理,中断就会被关闭,而且关闭之后不会被打开!
我们一般都在串口中断里面调用了信号量API来通知APP,但信号量创建后中断就被关闭了,如果串口中断也在操作系统的管辖范围内
那么意味着串口中断也被屏蔽了,你说还能正常使用么?
举报