完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
请教一个问题,最近在学习使用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个回答
|
|
这是你没移植好延时。跟FreeRTOS没关系。给你发一份我们自己F429的的FreeRTOS版本的SYSTEM文件夹,你可以参考一下。F429用的HAL库。
SYSTEM.rar (8.88 KB ) |
|
|
|
调度器没启动前是不能调用系统延时的,因为调度器在启动时才开始初始化SysTick,也就是说系统定时器在调度器启动后才开始运行
|
|
|
|
这样说来,串口中断处理等操作也是要调度器启动了才能开始运行?
|
|
|
|
根据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,但信号量创建后中断就被关闭了,如果串口中断也在操作系统的管辖范围内 那么意味着串口中断也被屏蔽了,你说还能正常使用么? |
|
|
|
十分感谢,还没看过F429的资料,想不到已经做出来了
|
|
|
|
原来是自己没有深入理解FreeRTOS,感谢版主耐心回答
|
|
|
|
感谢@zuozhongkai @FreeRTOS 的提示和解答,今天再修改了一下delay.c函数,在SysTick_Handler()里加入系统启动判断:
[AppleScript] 纯文本查看 复制代码 //systick中断服务函数,使用ucos时用到void SysTick_Handler(void){ #ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.OSIntEnter();//进入中断 OSTimeTick(); //调用ucos的时钟服务程序 OSIntExit(); //触发任务切换软中断#endif#ifdef FreeRTOSif(OSRunning==1)//系统在运行{xPortSysTickHandler();}#endif} 这样系统就能在没有启动调度器的情况下,调用延时和串口打印函数也能正常运行。 新的问题又来了: USART1_IRQHandler()里模仿ucos调用了taskENTER_CRITICAL_FROM_ISR(),taskEXIT_CRITICAL_FROM_ISR()作为中断屏蔽,追踪源码,是一段汇编,,, [AppleScript] 纯文本查看 复制代码 //taskENTER_CRITICAL_FROM_ISR()__asm uint32_t ulPortSetInterruptMask( void ){PRESERVE8mrs r0, baseprimov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITYmsr basepri, r1bx r14}/*-----------------------------------------------------------*///portCLEAR_INTERRUPT_MASK_FROM_ISR()__asm void vPortClearInterruptMask( uint32_t ulNewMask ){PRESERVE8msr basepri, r0bx r14}/*----------------------------- 能指点迷津? 附:修正后的工程 FreeRTOS V2.rar (337.33 KB ) |
|
|
|
关于 configMAX_SYSCALL_INTERRUPT_PRIORITY 和 BASEPRI 寄存器的用法请参考我的另一个帖子:
http://www.openedv.com/thread-77593-1-1.html 帖子中间部分对这两者进行了一个比较详细的解释 |
|
|
|
请问楼主问题解决了吗?
|
|
|
|
嗯?是指哪方面问题?
|
|
|
|
没启用调度前delay_ms和串口不能打印的问题。
|
|
|
|
|
|
|
|
|
|
|
|
1、delay_ms 函数里有一个 OSRunning==1 的判断,它是启用了任务调度函数才为真。在调度使用前,延时都用 delay_us 来实现。比如说 delay_ms(2) 实际就是 delay_us(2000) 。
2、中断使用的4组,4位抢占优先级,0位响应优先级。然后抢占优先级的范围是0~2^4-1,就是0~15。数值越小越优先,所以设一个15 |
|
|
|
多谢谢指教,从回贴的时间不难看出你是8点上班然后5:30下班,我猜的没错吧。
|
|
|
|
哈哈,这都可以看出来。
|
|
|
|
只有小组成员才能发言,加入小组>>
798 浏览 0 评论
1154 浏览 1 评论
2531 浏览 5 评论
2863 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2713 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1081浏览 3评论
195浏览 2评论
461浏览 2评论
374浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
455浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 16:40 , Processed in 1.466097 second(s), Total 79, Slave 70 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号