搜索
bottom↓
回复: 9

ucos多任务单串口打印遇到的问题

[复制链接]

出0入0汤圆

发表于 2017-2-22 16:09:38 | 显示全部楼层 |阅读模式
目前正在学习ucos,使用的代码版本为ucos 2.92,现在使用多任务单串口打印的时候,发现容易丢字符的现象,即使使用互斥信号量依旧存在该问题,话不多说,上代码给大家看看

main函数代码
  1. int main(void)
  2. {
  3.         CPU_INT08U  err;

  4.         Bsp_Init();
  5.        
  6.         OSInit();                                                   /* Initialize "uC/OS-II, The Real-Time Kernel"              */
  7.         OSMutexCreate(3, &err);

  8.         OSTaskCreateExt(LED1TaskStart,                               /* Create the start task                                    */
  9.                                         (void *)0,
  10.                                         (OS_STK *)&LED1TaskStartStk[TASK_START_STK_SIZE - 1],
  11.                                         LED1_TASK_START_PRIO,
  12.                                         LED1_TASK_START_PRIO,
  13.                                         (OS_STK *)&LED1TaskStartStk[0],
  14.                                         TASK_START_STK_SIZE,
  15.                                         (void *)0,
  16.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  17.         OSTaskNameSet(LED1_TASK_START_PRIO, "LED1 Task", &err);

  18.         OSTaskCreateExt(LED2TaskStart,                               /* Create the start task                                    */
  19.                                         (void *)0,
  20.                                         (OS_STK *)&LED2TaskStartStk[TASK_START_STK_SIZE - 1],
  21.                                         LED2_TASK_START_PRIO,
  22.                                         LED2_TASK_START_PRIO,
  23.                                         (OS_STK *)&LED2TaskStartStk[0],
  24.                                         TASK_START_STK_SIZE,
  25.                                         (void *)0,
  26.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  27.         OSTaskNameSet(LED2_TASK_START_PRIO, "LED2 Task", &err);

  28.         OSTaskCreateExt(LED3TaskStart,                               /* Create the start task                                    */
  29.                                         (void *)0,
  30.                                         (OS_STK *)&LED3TaskStartStk[TASK_START_STK_SIZE - 1],
  31.                                         LED3_TASK_START_PRIO,
  32.                                         LED3_TASK_START_PRIO,
  33.                                         (OS_STK *)&LED3TaskStartStk[0],
  34.                                         TASK_START_STK_SIZE,
  35.                                         (void *)0,
  36.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  37.         OSTaskNameSet(LED3_TASK_START_PRIO, "LED3 Task", &err);

  38.         OSTaskCreateExt(LED4TaskStart,                               /* Create the start task                                    */
  39.                                         (void *)0,
  40.                                         (OS_STK *)&LED4TaskStartStk[TASK_START_STK_SIZE - 1],
  41.                                         LED4_TASK_START_PRIO,
  42.                                         LED4_TASK_START_PRIO,
  43.                                         (OS_STK *)&LED4TaskStartStk[0],
  44.                                         TASK_START_STK_SIZE,
  45.                                         (void *)0,
  46.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  47.         OSTaskNameSet(LED4_TASK_START_PRIO, "LED4 Task", &err);

  48.         OSTaskCreateExt(LED5TaskStart,                               /* Create the start task                                    */
  49.                                         (void *)0,
  50.                                         (OS_STK *)&LED5TaskStartStk[TASK_START_STK_SIZE - 1],
  51.                                         LED5_TASK_START_PRIO,
  52.                                         LED5_TASK_START_PRIO,
  53.                                         (OS_STK *)&LED5TaskStartStk[0],
  54.                                         TASK_START_STK_SIZE,
  55.                                         (void *)0,
  56.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  57.         OSTaskNameSet(LED5_TASK_START_PRIO, "LED5 Task", &err);

  58.         OSTaskCreateExt(LED6TaskStart,                               /* Create the start task                                    */
  59.                                         (void *)0,
  60.                                         (OS_STK *)&LED6TaskStartStk[TASK_START_STK_SIZE - 1],
  61.                                         LED6_TASK_START_PRIO,
  62.                                         LED6_TASK_START_PRIO,
  63.                                         (OS_STK *)&LED6TaskStartStk[0],
  64.                                         TASK_START_STK_SIZE,
  65.                                         (void *)0,
  66.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  67.         OSTaskNameSet(LED6_TASK_START_PRIO, "LED6 Task", &err);

  68.         OSTaskCreateExt(LED7TaskStart,                               /* Create the start task                                    */
  69.                                         (void *)0,
  70.                                         (OS_STK *)&LED7TaskStartStk[TASK_START_STK_SIZE - 1],
  71.                                         LED7_TASK_START_PRIO,
  72.                                         LED7_TASK_START_PRIO,
  73.                                         (OS_STK *)&LED7TaskStartStk[0],
  74.                                         TASK_START_STK_SIZE,
  75.                                         (void *)0,
  76.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  77.         OSTaskNameSet(LED7_TASK_START_PRIO, "LED7 Task", &err);

  78.         OSTaskCreateExt(LED8TaskStart,                               /* Create the start task                                    */
  79.                                         (void *)0,
  80.                                         (OS_STK *)&LED8TaskStartStk[TASK_START_STK_SIZE - 1],
  81.                                         LED8_TASK_START_PRIO,
  82.                                         LED8_TASK_START_PRIO,
  83.                                         (OS_STK *)&LED8TaskStartStk[0],
  84.                                         TASK_START_STK_SIZE,
  85.                                         (void *)0,
  86.                                         OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);

  87.         OSTaskNameSet(LED8_TASK_START_PRIO, "LED8 Task", &err);

  88.         OSStart();
  89. }
复制代码


任务代码
  1. static void LED1TaskStart(void * p_arg)
  2. {
  3.         INT8U err;
  4.         (void)p_arg;

  5.         while (1)
  6.         {                                          /* Task body, always written as an infinite loop.           */
  7.                 BSP_LED_Toggle(0);
  8.                 OSMutexPend(ResourceMutex, 0, &err);
  9.                 UsartPrintf(USART1, "LED1TaskStart\n");
  10.                 OSMutexPost(ResourceMutex);
  11.                 OSTimeDlyHMSM(0, 0, 1, 0);
  12.         }
  13. }

  14. static void LED2TaskStart(void * p_arg)
  15. {
  16.         INT8U err;
  17.         (void)p_arg;

  18.         while (1)
  19.         {                                          /* Task body, always written as an infinite loop.           */
  20.                 BSP_LED_Toggle(1);
  21.                 OSMutexPend(ResourceMutex, 0, &err);
  22.                 UsartPrintf(USART1, "LED2TaskStart\n");
  23.                 OSMutexPost(ResourceMutex);
  24.                 OSTimeDlyHMSM(0, 0, 2, 0);
  25.         }
  26. }

  27. static void LED3TaskStart(void * p_arg)
  28. {
  29.         INT8U err;
  30.         (void)p_arg;

  31.         while (1)
  32.         {                                          /* Task body, always written as an infinite loop.           */
  33.                 BSP_LED_Toggle(2);
  34.                 OSMutexPend(ResourceMutex, 0, &err);
  35.                 UsartPrintf(USART1, "LED3TaskStart\n");
  36.                 OSMutexPost(ResourceMutex);
  37.                 OSTimeDlyHMSM(0, 0, 3, 0);
  38.         }
  39. }

  40. static void LED4TaskStart(void * p_arg)
  41. {
  42.         INT8U err;
  43.         (void)p_arg;

  44.         while (1)
  45.         {                                          /* Task body, always written as an infinite loop.           */
  46.                 BSP_LED_Toggle(3);
  47.                 OSMutexPend(ResourceMutex, 0, &err);
  48.                 UsartPrintf(USART1, "LED4TaskStart\n");
  49.                 OSMutexPost(ResourceMutex);
  50.                 OSTimeDlyHMSM(0, 0, 4, 0);
  51.         }
  52. }

  53. static void LED5TaskStart(void * p_arg)
  54. {
  55.         INT8U err;
  56.         (void)p_arg;

  57.         while (1)
  58.         {                                          /* Task body, always written as an infinite loop.           */
  59.                 BSP_LED_Toggle(4);
  60.                 OSMutexPend(ResourceMutex, 0, &err);
  61.                 UsartPrintf(USART1, "LED5TaskStart\n");
  62.                 OSMutexPost(ResourceMutex);
  63.                 OSTimeDlyHMSM(0, 0, 5, 0);
  64.         }
  65. }

  66. static void LED6TaskStart(void * p_arg)
  67. {
  68.         INT8U err;
  69.         (void)p_arg;

  70.         while (1)
  71.         {                                          /* Task body, always written as an infinite loop.           */
  72.                 BSP_LED_Toggle(5);
  73.                 OSMutexPend(ResourceMutex, 0, &err);
  74.                 UsartPrintf(USART1, "LED6TaskStart\n");
  75.                 OSMutexPost(ResourceMutex);
  76.                 OSTimeDlyHMSM(0, 0, 6, 0);
  77.         }
  78. }

  79. static void LED7TaskStart(void * p_arg)
  80. {
  81.         INT8U err;
  82.         (void)p_arg;

  83.         while (1)
  84.         {                                          /* Task body, always written as an infinite loop.           */
  85.                 BSP_LED_Toggle(6);
  86.                 OSMutexPend(ResourceMutex, 0, &err);
  87.                 UsartPrintf(USART1, "LED7TaskStart\n");
  88.                 OSMutexPost(ResourceMutex);
  89.                 OSTimeDlyHMSM(0, 0, 7, 0);
  90.         }
  91. }

  92. static void LED8TaskStart(void * p_arg)
  93. {
  94.         INT8U err;
  95.         (void)p_arg;

  96.         while (1)
  97.         {                                          /* Task body, always written as an infinite loop.           */
  98.                 BSP_LED_Toggle(8);
  99.                 OSMutexPend(ResourceMutex, 0, &err);
  100.                 UsartPrintf(USART1, "LED8TaskStart\n");
  101.                 OSMutexPost(ResourceMutex);
  102.                 OSTimeDlyHMSM(0, 0, 8, 0);
  103.         }
  104. }
复制代码


打印函数
  1. void UsartPrintf(USART_TypeDef * USARTx, const char * fmt, ...)
  2. {
  3.         va_list args;

  4.         char printf_buffer[256];
  5.         char * ptr = printf_buffer;

  6.         va_start(args, fmt);

  7.         vsprintf(printf_buffer, fmt, args);

  8.         va_end(args);
  9. /**查询发送************************************************************************/
  10.         while (*ptr != '\0')
  11.         {
  12.                 USART_SendData(USARTx, *(ptr++));
  13.                 while (!(USARTx->SR & USART_FLAG_TXE));
  14.         }
  15. }
复制代码


我的疑问如下:
1、我加入了互斥型信号量,为何打印任务仍然被打断了;
2、字符为何丢失,有什么方法可以解决;
请各位高手指点迷津............

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2017-2-22 16:17:05 | 显示全部楼层
附上软件代码,以供大家测试。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2017-2-23 09:13:36 | 显示全部楼层
任务堆栈给大点试试呢

没用过ucos,不知道UsartPrintf里的那个256的数组是不是在任务堆栈里申请

出0入8汤圆

发表于 2017-2-23 09:51:21 | 显示全部楼层
本帖最后由 security 于 2017-2-23 09:54 编辑

逻辑没有错,退一步说,就算被抢占,也不应该丢失字符。
出现此情况有两种可能:
一是, PC 端的串口软件有 bug。
二是,你的栈溢出了。

你的栈太小了。
  1. #define  TASK_START_STK_SIZE                    216
复制代码

再看看 UsartPrintf 函数里面,看看那个 printf_buffer 的 size。
正确的做法是:将 printf_buffer  定义为 static 类型吧,减少对宿主 thread 栈的依赖。

出0入0汤圆

 楼主| 发表于 2017-2-23 12:05:52 | 显示全部楼层
security 发表于 2017-2-23 09:51
逻辑没有错,退一步说,就算被抢占,也不应该丢失字符。
出现此情况有两种可能:
一是, PC 端的串口软件有 ...

您好,感谢您的回复。我将TASK_START_STK_SIZE设置为416,并且将printf_buffer  定义为 static 类型后,问题依旧存在。还恳请指点一下。

出0入0汤圆

发表于 2017-2-23 13:54:50 | 显示全部楼层
本帖最后由 w282529350 于 2017-2-23 13:56 编辑
w282529350 发表于 2017-2-23 09:13
任务堆栈给大点试试呢

没用过ucos,不知道UsartPrintf里的那个256的数组是不是在任务堆栈里申请 ...


还有一个错误,你创建的信号量返回值没有给变量

出0入8汤圆

发表于 2017-2-23 13:59:14 | 显示全部楼层
dmzy 发表于 2017-2-23 12:05
您好,感谢您的回复。我将TASK_START_STK_SIZE设置为416,并且将printf_buffer  定义为 static 类型后, ...

那你就要检查下互斥量是否有效,
你有初始化 ResourceMutex 吗?往这边看看。

出0入0汤圆

发表于 2017-2-23 14:27:52 | 显示全部楼层
我感觉不是栈的问题,我曾看到过这样的问题,串口打印输出乱码,原因是printf函数打印输出时,被别的任务抢占,而抢占任务也用到了printf,最后解决是将打印输出放在临界段里面,或者加任务锁。你可以这么试一下,看看管不管用,只是个猜测。

出0入0汤圆

 楼主| 发表于 2017-2-24 09:15:45 | 显示全部楼层
w282529350 发表于 2017-2-23 13:54
还有一个错误,你创建的信号量返回值没有给变量

我检查了下,的确是的,改成如下代码,经测试过后就没有问题了。感谢指点,错误太低级了.........
  1. ResourceMutex = OSMutexCreate(10, &err);
复制代码

出0入0汤圆

 楼主| 发表于 2017-2-24 09:17:00 | 显示全部楼层
security 发表于 2017-2-23 13:59
那你就要检查下互斥量是否有效,
你有初始化 ResourceMutex 吗?往这边看看。 ...

问题是互斥变量忘记初始化了,改成如下就好了,测试没问题,谢谢指点。
  1. ResourceMutex = OSMutexCreate(10, &err);
复制代码
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 12:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表