前言
利用串口对基于FreeRTOS的多任务程序调试过程中,时常出现数据交叉打印,甚至出现乱码现象。这是因为通常情况下,串口打印函数所在任务的优先级不高,或者在程序中有多个任务均包含打印函数。此时,当发送数据时,容易被中断或者其它优先级更高的任务打断或抢占,在发送的数据量较大情况下,该现象尤为明显。
文本将介绍一种FreeRTOS的线程安全、中断安全的printf实现方式,并详细说明它是如何解决上述问题的。
一、问题描述
开发环境
平台:STM32Cube IDE,HAL库;
芯片:STM32L431CBT6;
串口设置
基于FreeRTOS的三任务程序,串口打印函数任务优先级最低,且在多个任务中均有打印函数。
串口设置如下:波特率115200;8位数据;一个停止位;一个起始位;无奇偶校验位;
输出展示
输出数据出现交叉打印现象,甚至出现乱码,如下图所示:
该程序下,串口的理想输出因该如下图所示:
二、解决方案
1. 线程安全、中断安全的printf实现方式
代码如下:
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
UART_HandleTypeDef huart1;
static int inHandlerMode(void);
void print_usart1(char *format, ...);
static int inHandlerMode(void)
{
return __get_IPSR();
}
void print_usart1(char *format, ...)
{
char buf[64];
if (inHandlerMode() != 0)
{
taskDISABLE_INTERRUPTS();
}
else
{
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)
{
osThreadYield();
}
}
va_list ap;
va_start(ap, format);
if (vsprintf(buf, format, ap) > 0)
{
HAL_UART_Transmit(&huart1, (uint8_t *)buf, strlen(buf), 100);
}
va_end(ap);
if (inHandlerMode() != 0)
{
taskENABLE_INTERRUPTS();
}
}
总结
1)程序开发过程中利用串口进行调试,是不少嵌入式程序员的首选调试方式;
2)在基于FreeRTOS等实时操作系统的多任务程序调试过程中,串口时常出现数据交叉打印,甚至乱码现象;
3)串口在发送数据时,容易被中断或者其它优先级更高的任务打断或抢占;
4)文本分享了一种FreeRTOS线程安全、中断安全的printf实现方式。
参考
https://wenku.baidu.com/view/bacd8e4ea75177232f60ddccda38376bae1fe05f.html;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)