野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 6957|回复: 3

[ucos] uCOSIII的延时随机失效问题,不知道是系统BUG还是其他原因

[复制链接]
发表于 2016-1-18 01:28:26 | 显示全部楼层 |阅读模式
在uCOSIII移植到STM32后可以正常执行多任务,让三个LED以不同频率闪烁。

后来我在此基础上加入emWin522,测试正常,可以正常显示画面,包括emWin的自带DEMO能正常运行。

然后我加入自己写的触摸屏校准程序,经过调试后可以正常校准并把校准数据写入到外部SPI FLASH里面,然后再测试DEMO可以正常触摸控制DEMO例程。


可是问题来了,首先我说明一下,我使用的是emWin522多任务版的OSlib,和官方GUI_X_UCOS.C文件,能够正常使用emWin,但是我发现我的校准程序延时出现了一个问题----延时随机失效,就是明明延时5秒,可是1秒没有到就直接过去了。

刚开始我使用的是GUI_Delay来延时的,我以为是GUI_Delay出了问题(GUI_X_UCOS是官方实例的应该不会出问题的),然后我改用UCOS的OSTimeDly来延时,发现问题还是存在,出现随机性的延时失效,就是有时候校准成功或者失败后延时
正常5秒,有时候直接1秒不到就跳过,连个校准成功的文字都没有看到就直接跳到其他的多任务里面去了。(我目前让系统执行的任务是首先优先级最高的获取触摸屏位置任务,然后是三个LED的各个任务闪烁,本来是加入触摸屏校准任务的,后来发现触摸屏校准任务会出现问题,我就没有将触摸屏校准单独生成一个任务,而是将其放在BSP_Init里面进行初始化,而为了让其能使用OSTimeDly,所以我在板载初始化之前先开启滴答。)


后来关闭#define OS_CFG_ISR_POST_DEFERRED_EN     0u   /* Enable (1) or Disable (0) Deferred ISR posts */    还是一样会出现问题,延时随机失效。我用了好几天的时间都没有找到出现问题的原因,利用仿真查看也没有查出个所以然来。
但是有点可以肯定,第一、GUI_Delay调用的就是GUI_X_UCOS里面的OSTimeDly,而GUI_Delay出现问题后,换成OSTimeDly也还是有一样的问题,那就说明就是OSTimeDly出现延时失效的问题,而OS_CFG_ISR_POST_DEFERRED_EN是可以修改
OSTimeDly延时方式的,修改与不修改都不会解决延时失效的问题。第二、使用for函数自减制作的延时函数替代OSTimeDly后可以正常稳定的延时,不会出现任何失效,说明我写的触摸校准程序是没有问题的。
有以上几点我大概得出:要么是其他地方导致OSTimeDly延时随机性失效,要么就是UCOS有BUG,当然我相信应该是前者的问题。以下是我触摸校准函数的程序源码,直接以emwin为基础写的。


触摸屏校准程序(实际测试并不是备份域影响延时)wudaxstudio发布
  1. <blockquote><blockquote>void Display_LineX(uint16_t x,uint16_t y)//设置一个十字型的图案用于触摸校正的,中心点为原点
复制代码
多任务中:
  1. static  void  AppTaskStart (void *p_arg)
  2. {
  3.     CPU_INT32U  cpu_clk_freq;
  4.     CPU_INT32U  cnts;
  5.     OS_ERR      err;


  6.    (void)p_arg;



  7.     cpu_clk_freq = BSP_CPU_ClkFreq();                           /* Determine SysTick reference freq.                    */
  8.     cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz;        /* Determine nbr SysTick increments                     */
  9.     OS_CPU_SysTickInit(cnts);                                   /* Init uC/OS periodic time src (SysTick).              */
  10.    
  11.     CPU_Init();
  12.                 BSP_Init();                                                 /* Initialize BSP functions                             */
  13. //    Mem_Init();                                                 /* Initialize Memory Management Module                  */

  14. //#if OS_CFG_STAT_TASK_EN > 0u
  15. //    OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
  16. //#endif

  17. //    CPU_IntDisMeasMaxCurReset();

  18.     OSTaskCreate((OS_TCB     *)&AppTouchPositionTCB,                /* Create the TouchPosition                                */
  19.                  (CPU_CHAR   *)"App TouchPosition",
  20.                  (OS_TASK_PTR ) AppTouchPosition,
  21.                  (void       *) 0,
  22.                  (OS_PRIO     ) APP_TouchPosition_PRIO,
  23.                  (CPU_STK    *)&AppTouchPositionStk[0],
  24.                  (CPU_STK_SIZE) APP_TouchPosition_STK_SIZE / 10,
  25.                  (CPU_STK_SIZE) APP_TouchPosition_STK_SIZE,
  26.                  (OS_MSG_QTY  ) 0u,
  27.                  (OS_TICK     ) 0u,
  28.                  (void       *) 0,
  29.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  30.                  (OS_ERR     *)&err);

  31.     OSTaskCreate((OS_TCB     *)&AppTouchpointTCB,                /* Create the Touchpoint                                */
  32.                  (CPU_CHAR   *)"App Touchpoint",
  33.                  (OS_TASK_PTR ) AppTouchpoint,
  34.                  (void       *) 0,
  35.                  (OS_PRIO     ) APP_Touchpoint_PRIO,
  36.                  (CPU_STK    *)&AppTouchpointStk[0],
  37.                  (CPU_STK_SIZE) APP_Touchpoint_STK_SIZE / 10,
  38.                  (CPU_STK_SIZE) APP_Touchpoint_STK_SIZE,
  39.                  (OS_MSG_QTY  ) 0u,
  40.                  (OS_TICK     ) 0u,
  41.                  (void       *) 0,
  42.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  43.                  (OS_ERR     *)&err);




  44.     OSTaskCreate((OS_TCB     *)&AppLedTask1TCB,                /* Create the led1                                */
  45.                  (CPU_CHAR   *)"App LedTask1",
  46.                  (OS_TASK_PTR ) AppLedTask1,
  47.                  (void       *) 0,
  48.                  (OS_PRIO     ) APP_LedTask1_PRIO,
  49.                  (CPU_STK    *)&AppLedTask1Stk[0],
  50.                  (CPU_STK_SIZE) APP_LedTask1_STK_SIZE / 10,
  51.                  (CPU_STK_SIZE) APP_LedTask1_STK_SIZE,
  52.                  (OS_MSG_QTY  ) 0u,
  53.                  (OS_TICK     ) 0u,
  54.                  (void       *) 0,
  55.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  56.                  (OS_ERR     *)&err);

  57.     OSTaskCreate((OS_TCB     *)&AppLedTask2TCB,                /* Create the led1                                */
  58.                  (CPU_CHAR   *)"App LedTask2",
  59.                  (OS_TASK_PTR ) AppLedTask2,
  60.                  (void       *) 0,
  61.                  (OS_PRIO     ) APP_LedTask2_PRIO,
  62.                  (CPU_STK    *)&AppLedTask2Stk[0],
  63.                  (CPU_STK_SIZE) APP_LedTask2_STK_SIZE / 10,
  64.                  (CPU_STK_SIZE) APP_LedTask2_STK_SIZE,
  65.                  (OS_MSG_QTY  ) 0u,
  66.                  (OS_TICK     ) 0u,
  67.                  (void       *) 0,
  68.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  69.                  (OS_ERR     *)&err);

  70.     OSTaskCreate((OS_TCB     *)&AppLedTask3TCB,                /* Create the led1                                */
  71.                  (CPU_CHAR   *)"App LedTask3",
  72.                  (OS_TASK_PTR ) AppLedTask3,
  73.                  (void       *) 0,
  74.                  (OS_PRIO     ) APP_LedTask3_PRIO,
  75.                  (CPU_STK    *)&AppLedTask3Stk[0],
  76.                  (CPU_STK_SIZE) APP_LedTask3_STK_SIZE / 10,
  77.                  (CPU_STK_SIZE) APP_LedTask3_STK_SIZE,
  78.                  (OS_MSG_QTY  ) 0u,
  79.                  (OS_TICK     ) 0u,
  80.                  (void       *) 0,
  81.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  82.                  (OS_ERR     *)&err);
  83.                                                                  
  84.                 OSTaskDel(&AppTaskStartTCB,&err);
  85. }


  86. //各个任务的实体函数
  87. void  AppTouchPosition  (void *p_arg)
  88. {
  89.         OS_ERR      err;
  90.         uint16_t    Touch_X,Touch_Y;
  91.        
  92.         while (DEF_TRUE)
  93.         {
  94.                 //GUI_Exec();//刷新屏幕
  95.                 if (Get_Position(&Touch_X,&Touch_Y))//获取当前触摸值对应的像素坐标
  96.                         GUI_TOUCH_StoreState(Touch_X,Touch_Y);//将坐标储存在emWin的TouchPID里面,方便GUI系统调用
  97.                 else
  98.                         GUI_TOUCH_StoreState(-1,-1);//将坐标储存在emWin的TouchPID里面,方便GUI系统调用
  99.                 OSTimeDly(10,OS_OPT_TIME_DLY,&err);//每隔10MS获取一次触摸值
  100.         }
  101. }



  102. void  AppTouchpoint (void *p_arg)
  103. {
  104.         OS_ERR      err;
  105.         uint16_t    Touch_X,Touch_Y;
  106.        
  107.         GUI_CURSOR_Select(&GUI_CursorCrossM);        //设置游标为十字形
  108.         GUI_CURSOR_SetPosition(-1,-1);                //设置游标的位置
  109.         GUI_CURSOR_Show();                        //显示游标
  110.         GUI_SetPenSize(6);
  111.         while (DEF_TRUE)
  112.         {
  113.                 if (Get_Position(&Touch_X,&Touch_Y))
  114.                 {
  115.                         GUI_CURSOR_SetPosition(Touch_X,Touch_Y);
  116.                         GUI_DrawPoint(Touch_X,Touch_Y);
  117.                 }
  118.                 OSTimeDly(60,OS_OPT_TIME_DLY,&err);//每隔10MS获取一次触摸值
  119.         }
  120. }





  121. void  AppLedTask1(void *p_arg)
  122. {
  123.                 OS_ERR      err;
  124.        
  125.                 (void)p_arg;
  126.        
  127.     while (DEF_TRUE)
  128.                 {                                          /* Task body, always written as an infinite loop.       */
  129.                         LED1(1);
  130.                         OSTimeDly(500,OS_OPT_TIME_DLY,&err);
  131.                         LED1(0);
  132.                         OSTimeDly(500,OS_OPT_TIME_DLY,&err);
  133.                 }
  134. }

  135. void  AppLedTask2(void *p_arg)
  136. {
  137.                 OS_ERR      err;
  138.        
  139.                 (void)p_arg;
  140.        
  141.     while (DEF_TRUE)
  142.                 {                                          /* Task body, always written as an infinite loop.       */
  143.                         LED2(1);
  144.                         OSTimeDly(500,OS_OPT_TIME_DLY,&err);
  145.                         LED2(0);
  146.                         OSTimeDly(500,OS_OPT_TIME_DLY,&err);
  147.                 }
  148. }

  149. void  AppLedTask3(void *p_arg)
  150. {
  151.                 OS_ERR      err;
  152.        
  153.                 (void)p_arg;
  154.        
  155.     while (DEF_TRUE)
  156.                 {                                          /* Task body, always written as an infinite loop.       */
  157.                         LED3(1);
  158.                         OSTimeDly(1000,OS_OPT_TIME_DLY,&err);
  159.                         LED3(0);
  160.                         OSTimeDly(1000,OS_OPT_TIME_DLY,&err);
  161.                 }
  162. }
复制代码
请教高手,请教野火@fire ,到底应该是什么原因导致我写的触摸屏校准程序无法正常延时,不可能真有BUG吧?在下载此感谢! 无大侠工作室发布

多任务LED正常闪烁

多任务LED正常闪烁

触摸屏校准,使用OSTimeDly延时随机失效

触摸屏校准,使用OSTimeDly延时随机失效
回复

使用道具 举报

 楼主| 发表于 2016-1-18 01:35:25 | 显示全部楼层
触摸屏校准程序wudaxsutdio

  1. void Display_LineX(uint16_t x,uint16_t y)//设置一个十字型的图案用于触摸校正的,中心点为原点
  2. {
  3.         GUI_CURSOR_Select(&GUI_CursorCrossM);        //设置游标为十字形
  4.         GUI_CURSOR_SetPosition(x,y);                //设置游标的位置
  5.         GUI_CURSOR_Show();                        //显示游标
  6. }


  7. void Show_Coordinate(uint8_t num)
  8. {
  9.         static uint8_t disp_flag=1;
  10.         if (disp_flag != num)
  11.         {
  12.                 GUI_SetBkColor(GUI_BLACK);//背景色黑色
  13.                 GUI_SetColor(GUI_WHITE);//前景色白色
  14.                 GUI_SetFont(&GUI_Font8x16);//设置标题字体
  15.                 GUI_SetColor(GUI_RED);//设置标题字体颜色
  16.                 GUI_DispStringHCenterAt("Touch_Calibration",120,6);//标题
  17.                 GUI_SetFont(&GUI_Font6x8);//设置默认字体
  18.                 GUI_SetColor(GUI_YELLOW);//前景色白色
  19.                 //GUI_GetClientRect(&rClient);//获取当前矩形尺寸
  20.                 switch(num)
  21.                 {
  22.                         case 0:
  23.                                         Display_LineX(Pos_0_x,Pos_0_y);
  24.                                         GUI_DispStringInRect("Set Pos 1 piont", &rClient, GUI_TA_HCENTER | GUI_TA_VCENTER);//在矩形中间处显示
  25.                                         break;
  26.                         case 1:
  27.                                         Display_LineX(Pos_1_x,Pos_1_y);
  28.                                         GUI_DispStringInRect("Set Pos 2 piont", &rClient, GUI_TA_HCENTER | GUI_TA_VCENTER);//在矩形中间处显示
  29.                                         break;
  30.                         case 2:
  31.                                         Display_LineX(Pos_2_x,Pos_2_y);
  32.                                         GUI_DispStringInRect("Set Pos 3 piont", &rClient, GUI_TA_HCENTER | GUI_TA_VCENTER);//在矩形中间处显示
  33.                                         break;
  34.                         case 3:
  35.                                         Display_LineX(Pos_3_x,Pos_3_y);
  36.                                         GUI_DispStringInRect("Set Pos 4 piont", &rClient, GUI_TA_HCENTER | GUI_TA_VCENTER);//在矩形中间处显示
  37.                                         break;
  38.                         default:
  39.                                         GUI_DispStringInRect("SET ERROR", &rClient, GUI_TA_HCENTER | GUI_TA_VCENTER);//在矩形中间处显示
  40.                                         break;
  41.                 }
  42.                 disp_flag = num;
  43.         }
  44. }
  45. void Touch_CorrectionANDInit(void)
  46. {
  47.         Touch_XY Touch_st;
  48.         uint8_t flag;
  49.         OS_ERR err;
  50.         BKP_WriteBackupRegister(BKP_DR5,0xccce);
  51.         while(BKP_ReadBackupRegister(BKP_DR5) != 0xcccc)
  52.         {
  53.                 flag = 0;
  54.                 X_Y_Same = XYsame;//公共变量X_Y_Same初始化,用来判断坐标与触摸值是否成正比
  55.                 GUI_Clear();//清屏
  56.                 while(flag < Touval)
  57.                 {
  58.                         Show_Coordinate(flag);//显示触摸校准坐标
  59.                         if (Touch_Press)//等待触摸中断的发生
  60.                         {
  61.                                 if (Get_Average_TouchValue(&Touch_st,flag))//是否获取到有效的触摸数据,如果获取到则执行下一个点
  62.                                         flag++;
  63.                                 while(Touch_Press);//等待触摸中断结束
  64.                                 GUI_CURSOR_Hide();
  65.                                 //Delayms(50000);
  66.                                 //GUI_Delay(500);
  67.                                 OSTimeDly(500,OS_OPT_TIME_DLY,&err);
  68.                         }               
  69.                 }

  70.                 if (VHscreen(Touch_st.dx[0],Touch_st.dx[1],Touch_st.dy[0],Touch_st.dy[1]))
  71.                 {        //判断触摸屏的xy方向与液晶屏xy方向是否相反,可以对调XY的值来修正问题
  72.                         Coordinate_switch(&Touch_st);//X,Y的值进行对调
  73.                         XYchange = 1;//控制X,Y的变量是否进行对调
  74.                 }
  75.                
  76.                
  77.                 /*LCD的原点;
  78.                 .>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  79.                 ******************************
  80.                 ******************************
  81.                 *****XY点*********************这里假设的横纵值而言
  82.                 ******************************横向与触摸值成正比
  83.                 ******************************正向与触摸值成反比
  84.                 ******************************
  85.                 ******************************
  86.                 .>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  87.                 触摸值的原点;
  88.                 因为三点校准法的要求条件是XY的方向与触摸值的方向必须成正比,
  89.                 假设LCD屏点是XY,所以对于触摸值而言LCD点的值应该为横纵向值减去XY再加上1得到触摸原点到该点才是模拟的对于触摸值的点,
  90.                 这样,模拟的XY值正好与触摸值成正比,在获取点时,只要得到模拟的XY点,带入上面的方法中就可得出实际LCD的点值。
  91.                 */
  92.                 X_Y_Same = PlusInc(Touch_st.dx[0],Touch_st.dx[2],Touch_st.dy[0],Touch_st.dy[2]);//判断X,Y方向与触摸屏方向是否保持一致
  93.                
  94.                 if(Total_Touch_Function(&GetTouchval,&Touch_st))//获取函数方程变量,并且判断是否校准成功
  95.                 {
  96.                         Flash_Function(Write_f);//把函数写到备份域
  97.                 }
  98. //                GUI_SetFont(&GUI_Font6x8);//设置默认字体
  99. //                GUI_SetColor(GUI_WHITE);//前景色白色
  100.                 //Delayms(9999999);//延时5秒
  101.                 //GUI_Delay(5000);
  102.                 OSTimeDly(5000,OS_OPT_TIME_DLY,&err);
  103.                 GUI_SetFont(&GUI_Font6x8);//设置默认字体
  104.                 GUI_SetColor(GUI_WHITE);//前景色白色
  105.                 GUI_Clear();//延时结束后再清除屏幕
  106.         }
  107.         Flash_Function(Read_f);//读取备份域里的数据
  108. }


复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-18 01:40:29 | 显示全部楼层
bsp.c

  1. void  BSP_Init (void)
  2. {
  3.         LED_Init();
  4.         Backup_init();//备份域初始化
  5.         FSMC_SRAM_Init();//可以考虑直接放在EMWIN里面
  6.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE);//用于验证EMWIN,保证EMWIN正常运行
  7.         GUI_Init();
  8.         Touch_CorrectionANDInit();//触摸校准
  9. //        GUI_DispString("\r\nthis is demo!\r\n");
  10. //        GUI_Delay(2000);
  11. //        GPIO_SetBits(GPIOB,GPIO_Pin_1);//关屏
  12. //        GUI_Delay(2000);
  13. //        GPIO_ResetBits(GPIOB,GPIO_Pin_1);//开屏
  14. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-20 04:35:43 | 显示全部楼层
已经找到问题了!原来是在检测触摸屏是否按下时并没有使用OS来延时,这样可能会导致所有任务全部堵塞,造成延时计数异常等等情况!后来我在循环检测中加入OS延时后,延时失效的问题也就不复存在了!嘿嘿
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-16 00:03 , Processed in 0.030665 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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