嵌入式学习小组
直播中

卜文月

7年用户 182经验值
私信 关注

FreeRTOS如何使用delay作为系统延时、任务调度

请教一个问题,最近在学习使用FreeRTOS,想像原子一样在delay.c里添加RTOS的系统支持,即使用tick时钟作延时。现在有几个问题:
1、在启动任务调度器前,如果调用了delay_ms()或者printf()(LCD_Init函数会用到这两个函数),系统就会进入HardFault_Handler状态
2、但当启动了vTaskStartScheduler()调度器后,延时和串口函数都能正常工作
3、相比ucosii,在初始化os前,调用了延时和串口打印却等正常运转。。。
以上初步怀疑是FreeRTOS的中断处理没配置好,系统的源代码、某开发板的FreeRTOS教程也看过好几遍,没找到办法。。
支招!!!
附:自己移植的工程代码,使用的是f103
FreeRTOS.rar (337.08 KB )

回帖(16)

倪梁靓

2020-6-10 08:19:52
这是你没移植好延时。跟FreeRTOS没关系。给你发一份我们自己F429的的FreeRTOS版本的SYSTEM文件夹,你可以参考一下。F429用的HAL库。
SYSTEM.rar (8.88 KB )
举报

李萌

2020-6-10 08:27:54
调度器没启动前是不能调用系统延时的,因为调度器在启动时才开始初始化SysTick,也就是说系统定时器在调度器启动后才开始运行
举报

冯金妮

2020-6-10 08:47:18
这样说来,串口中断处理等操作也是要调度器启动了才能开始运行?
举报

王桂芝

2020-6-10 09:03:06
根据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,但信号量创建后中断就被关闭了,如果串口中断也在操作系统的管辖范围内
那么意味着串口中断也被屏蔽了,你说还能正常使用么?
举报

更多回帖

发帖
×
20
完善资料,
赚取积分