ucos多任务单串口打印遇到的问题
目前正在学习ucos,使用的代码版本为ucos 2.92,现在使用多任务单串口打印的时候,发现容易丢字符的现象,即使使用互斥信号量依旧存在该问题,话不多说,上代码给大家看看main函数代码
int main(void)
{
CPU_INT08Uerr;
Bsp_Init();
OSInit(); /* Initialize "uC/OS-II, The Real-Time Kernel" */
OSMutexCreate(3, &err);
OSTaskCreateExt(LED1TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED1TaskStartStk,
LED1_TASK_START_PRIO,
LED1_TASK_START_PRIO,
(OS_STK *)&LED1TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED1_TASK_START_PRIO, "LED1 Task", &err);
OSTaskCreateExt(LED2TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED2TaskStartStk,
LED2_TASK_START_PRIO,
LED2_TASK_START_PRIO,
(OS_STK *)&LED2TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED2_TASK_START_PRIO, "LED2 Task", &err);
OSTaskCreateExt(LED3TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED3TaskStartStk,
LED3_TASK_START_PRIO,
LED3_TASK_START_PRIO,
(OS_STK *)&LED3TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED3_TASK_START_PRIO, "LED3 Task", &err);
OSTaskCreateExt(LED4TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED4TaskStartStk,
LED4_TASK_START_PRIO,
LED4_TASK_START_PRIO,
(OS_STK *)&LED4TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED4_TASK_START_PRIO, "LED4 Task", &err);
OSTaskCreateExt(LED5TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED5TaskStartStk,
LED5_TASK_START_PRIO,
LED5_TASK_START_PRIO,
(OS_STK *)&LED5TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED5_TASK_START_PRIO, "LED5 Task", &err);
OSTaskCreateExt(LED6TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED6TaskStartStk,
LED6_TASK_START_PRIO,
LED6_TASK_START_PRIO,
(OS_STK *)&LED6TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED6_TASK_START_PRIO, "LED6 Task", &err);
OSTaskCreateExt(LED7TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED7TaskStartStk,
LED7_TASK_START_PRIO,
LED7_TASK_START_PRIO,
(OS_STK *)&LED7TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED7_TASK_START_PRIO, "LED7 Task", &err);
OSTaskCreateExt(LED8TaskStart, /* Create the start task */
(void *)0,
(OS_STK *)&LED8TaskStartStk,
LED8_TASK_START_PRIO,
LED8_TASK_START_PRIO,
(OS_STK *)&LED8TaskStartStk,
TASK_START_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSTaskNameSet(LED8_TASK_START_PRIO, "LED8 Task", &err);
OSStart();
}
任务代码
static void LED1TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(0);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED1TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
static void LED2TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(1);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED2TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 2, 0);
}
}
static void LED3TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(2);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED3TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 3, 0);
}
}
static void LED4TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(3);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED4TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 4, 0);
}
}
static void LED5TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(4);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED5TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 5, 0);
}
}
static void LED6TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(5);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED6TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 6, 0);
}
}
static void LED7TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(6);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED7TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 7, 0);
}
}
static void LED8TaskStart(void * p_arg)
{
INT8U err;
(void)p_arg;
while (1)
{ /* Task body, always written as an infinite loop. */
BSP_LED_Toggle(8);
OSMutexPend(ResourceMutex, 0, &err);
UsartPrintf(USART1, "LED8TaskStart\n");
OSMutexPost(ResourceMutex);
OSTimeDlyHMSM(0, 0, 8, 0);
}
}
打印函数
void UsartPrintf(USART_TypeDef * USARTx, const char * fmt, ...)
{
va_list args;
char printf_buffer;
char * ptr = printf_buffer;
va_start(args, fmt);
vsprintf(printf_buffer, fmt, args);
va_end(args);
/**查询发送************************************************************************/
while (*ptr != '\0')
{
USART_SendData(USARTx, *(ptr++));
while (!(USARTx->SR & USART_FLAG_TXE));
}
}
我的疑问如下:
1、我加入了互斥型信号量,为何打印任务仍然被打断了;
2、字符为何丢失,有什么方法可以解决;
请各位高手指点迷津............ 附上软件代码,以供大家测试。 任务堆栈给大点试试呢
没用过ucos,不知道UsartPrintf里的那个256的数组是不是在任务堆栈里申请 本帖最后由 security 于 2017-2-23 09:54 编辑
逻辑没有错,退一步说,就算被抢占,也不应该丢失字符。
出现此情况有两种可能:
一是, PC 端的串口软件有 bug。
二是,你的栈溢出了。
你的栈太小了。
#defineTASK_START_STK_SIZE 216
再看看 UsartPrintf 函数里面,看看那个 printf_buffer 的 size。
正确的做法是:将 printf_buffer定义为 static 类型吧,减少对宿主 thread 栈的依赖。 security 发表于 2017-2-23 09:51
逻辑没有错,退一步说,就算被抢占,也不应该丢失字符。
出现此情况有两种可能:
一是, PC 端的串口软件有 ...
您好,感谢您的回复。我将TASK_START_STK_SIZE设置为416,并且将printf_buffer定义为 static 类型后,问题依旧存在。还恳请指点一下。 本帖最后由 w282529350 于 2017-2-23 13:56 编辑
w282529350 发表于 2017-2-23 09:13
任务堆栈给大点试试呢
没用过ucos,不知道UsartPrintf里的那个256的数组是不是在任务堆栈里申请 ...
还有一个错误,你创建的信号量返回值没有给变量 dmzy 发表于 2017-2-23 12:05
您好,感谢您的回复。我将TASK_START_STK_SIZE设置为416,并且将printf_buffer定义为 static 类型后, ...
那你就要检查下互斥量是否有效,
你有初始化 ResourceMutex 吗?往这边看看。 我感觉不是栈的问题,我曾看到过这样的问题,串口打印输出乱码,原因是printf函数打印输出时,被别的任务抢占,而抢占任务也用到了printf,最后解决是将打印输出放在临界段里面,或者加任务锁。你可以这么试一下,看看管不管用,只是个猜测。
w282529350 发表于 2017-2-23 13:54
还有一个错误,你创建的信号量返回值没有给变量
我检查了下,的确是的,改成如下代码,经测试过后就没有问题了。感谢指点,错误太低级了.........
ResourceMutex = OSMutexCreate(10, &err); security 发表于 2017-2-23 13:59
那你就要检查下互斥量是否有效,
你有初始化 ResourceMutex 吗?往这边看看。 ...
问题是互斥变量忘记初始化了,改成如下就好了,测试没问题,谢谢指点。
ResourceMutex = OSMutexCreate(10, &err);
页:
[1]