最近在做的一个项目,由于系统需要对通信数据的无丢包执行(即便由于前面的指令而较晚执行),通信指令又可能会有间隔很短的接收情况(间隔50ms以内),因此FREERTOS的队列传递数据方式我认为很适合这个系统,进而进行了尝试。这里会将途中遇到的任务优先级分配问题、结束任务时系统卡死、CAN总线通信问题、GD32F103替代方案尝试问题、系统中断使用二值信号量卡死问题、系统断连仿真器时无法正常启动问题,及其解决方法进行说明。
一、生成系统初始化代码
利用STM32CUBEIDE可以很方便地生成初始化代码,少去了很多移植freertos系统的麻烦,很大程度上也减少了一部分BUG。
1.系统设置:
Debug使用serial wire(SW)模式——这个根据自己的调试习惯进行设置即可。时基选择一个没用到的定时器。
2.配置FREERTOS
API接口我用的是CMSIS_V1。 下面是参数设置: 需要注意的参数: TICK_RATE_HZ:FREERTOS tick中断频率 MINIMAL_STACK_SIZE:设置分配给空闲任务的堆栈大小,其他TASK的堆栈大小设置不可小于该值。 MAX_PRIORITIES:设置可分配给任务的最大优先级。
TOTAL_HEAP_SIZE:RTOS内核可用的RAM总量。(此参数可以在配置好所有需要初始化的任务、队列和信号量之后再进行设置,比FreeRTOS Heap Usage选项卡中的TOTAL HEAP USED值大即可)
其他参数保持默认即可。
3.规划任务功能及优先级
要遵循一个原则:使用越频繁的任务设置的优先级应当越低,对实时性要求越高的任务优先级应该越高。 如果程序烧录之后有些任务总是执行不到,那么首先应当考虑是不是任务优先级设置有问题。 本次项目一共建立了8个任务(包括默认任务),任务功能及优先级设计如下(优先级高低遵循STM32优先级规则,数字越小优先级越高):
4.根据任务功能规划队列
注意!:队列数据类型一定要填写要传递的数据类型,如传递结构体,则需要填写结构体名称,如 否则无法顺利传递数据。
二、调试中遇到的问题及解决方案
1.结束任务时系统卡死
调试中发现运行过初始化代码后默认任务控制的LED频闪会失效变为常亮,因此判断系统在某点卡死了,因为最高优先级的任务不应该出现等待其他任务的情况,单步调试后最后锁定在SM45BLTask执行完成后,经查发现是结尾的一个函数使用了HAL_Delay() 函数,在FREERTOS系统中使用HAL库延时函数会导致系统卡死情况。 解决方案:如需要延时应当使用osDelay() 函数,该函数在延时时会将当前任务阻塞并推迟至延时时间到达再执行。
2.系统断连仿真器时无法正常启动问题
现象为连接仿真器能够正常执行程序,拔下仿真器重新上电,系统运行LED状态灯常亮而非设置的频闪。经查是由于其中一个外设(RS485连接的电机驱动板)启动较慢导致的,不给该驱动板供电下系统正常启动。 解决方案:在系统时钟初始化后、外设初始化前加HAL_Delay(1000); 延时。此时未启动任务调度器故要用HAL延时函数。
3.CAN总线通信问题
现象为CAN总线通信异常,必须在上电启动后再给CAN通信的外设上电才能正常通信。经查原因为上一个问题添加的启动1s延时,导致CAN设备在此期间给控制器发送了数据,而控制器的接收中断还未初始化,故后面的通信都无法正常进行。这里的CAN设备是我做的另一个执行外设。 解决方案:改变CAN通信策略,上电后由控制器主动下发通信报文,而非can设备主动上报状态信息。
4.系统中断使用二值信号量卡死问题
我在系统外部中断中使用了osSemaphoreRelease(); 函数,后发现在出现中断后系统会卡死在执行完中断服务函数之后。由于二值信号量函数并没有区分出中断中使用的版本,所以我决定采用其他方式传递数据。 解决方案:在系统中断中不要使用osSemaphoreRelease(); 函数,如有需要可以使用中断专用的队列函数xQueueSendFromIS(); 或全局变量。
5.GD32F103替代方案尝试问题
由于STM32最近数量紧张价格飞涨等问题,尝试使用GD32同型号芯片进行替代,目前测试遇到的问题主要是CAN总线初始化无法通过,故先暂时放弃该替换方案。
三、根据项目整理的可用Freertos空白例程
由于项目特点无法公开代码,故整理了一个包含所有初始化和串口、can通信数据处理的空白例程,有兴趣的小伙伴可以下载尝试一下多任务实时系统。 芯片:stm32f103c8t6 环境:STM32CUBEIDE,使用Keil的小伙伴新建好工程后,将FreeRTOS_default/Core/Src 文件夹和FreeRTOS_default/Core/Inc 文件夹复制到工程目录下并添加至工程即可。 文件链接:https://download.csdn.net/download/weixin_44087298/34800461 该FreeRTOS例程包含CAN通信、串口空闲中断接收、串口DMA收发、DMA采集ADC、上下沿均触发式外部中断及其状态判断、4通道PWM输出电机控制、队列传递结构体、FreeRTOS保证串口传输数据完整的任务及其优先级规划。具体I/O定义可以通过文件夹中的FreeRTOS_default.ioc 文件查看,打开方式——STM32CubeIDE。 软件获取地址:https://www.st.com/zh/development-tools/stm32cubeide.html
|