硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3145|回复: 8
收起左侧

[有问必答] 使用 RTXos  任务执行一次就挂了

[复制链接]

5

主题

109

回帖

124

积分

初级会员

积分
124
发表于 2017-8-25 14:47:55 | 显示全部楼层 |阅读模式
使用 RTXos  任务执行一次就挂了 ,请教各位帮忙分析[s:130]

部分代码如下
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart1.h"
  4. #include "led.h"
  5. #include "esp8266.h"
  6. #include "RTL.h"
  7. u8 *str = "我就是esp8266!\n";
  8. static uint64_t AppTaskLEDStk[256/8*5];
  9. static uint64_t AppTaskStartStk[256/8*5];
  10. OS_TID HandleTaskLED = 0;
  11. __task void AppTaskStart(void);
  12. int main()
  13. {
  14.         Stm32_Clock_Init(9);
  15.         delay_init(72);
  16.         LED_Init();        
  17.         usart1_init(460800);
  18.         esp8266_apsta_mode1();
  19.         esp8266_echo(OFF);
  20.         
  21.         os_sys_init_user( AppTaskStart,
  22.                        3,
  23.                        &AppTaskStartStk,
  24.                        sizeof(AppTaskStartStk));
  25.         
  26.         while(1);
  27. }
  28. __task void AppTaskLED(void)
  29. {
  30.         while(1)
  31.         {
  32.                 LED1 = !LED1;
  33.                      esp8266_apsta_test(str);
  34.                 os_dly_wait(100);
  35.         }
  36. }
  37. static void AppTaskCreate(void)
  38. {
  39.         HandleTaskLED = os_tsk_create_user( AppTaskLED,
  40.                                     5,
  41.                                     &AppTaskLEDStk,
  42.                                     sizeof(AppTaskLEDStk));
  43. }
  44. __task void AppTaskStart(void)
  45. {
  46.         AppTaskCreate();
  47.         
  48.         while(1)
  49.         {
  50.                 LED0 = !LED0;            
  51.                 os_dly_wait(50);
  52.         }
  53. }
复制代码
  1. void esp8266_apsta_test(u8 *p)
  2. {
  3.         while(esp8266_send_cmd("AT+CIPSEND=15",">",20));//send a fixed-length data
  4.         esp8266_send_data(p,"SEND OK",200);
  5. }
复制代码

【问题描述】

问题出在第 41 行代码  esp8266_apsta_test(str);
    [li]工程中未加入 该函数,即未加入函数 esp8266_apsta_test(str) 到 AppTaskLED() 或 AppTaskStart() 任务中[/li]

                1)整个工程运行正常, LED 闪烁。


      2.将函数 esp8266_apsta_test(str) 放入 AppTaskLED() 或 AppTaskStart() 任务中

                1)把任务延时函数os_dly_wait(n) 注释掉,则该函数所在任务运行正常,其他任务不执行。不论 AppTaskLED() 或 AppTaskStart()
                     哪个优先级高哪个低,但调试结果是高优先级任务并未打断低优先级任务而执行。

                2)不注释任务延时函数os_dly_wait(n),从调试结果看所有的任务包括空闲任务依次执行一遍,然后系统就挂了。

【分析】

    [li]由未加入函数 esp8266_apsta_test(str) 前调试结果,LED 闪烁工作正常,说明操作系统任务切换无问题[/li][li]由加入函数 esp8266_apsta_test(str) 后调试结果,推出函数 esp8266_apsta_test(str) 所在任务空间足够或系统栈空间不够[/li]



【已采取的解决办法】

    [li]改变栈空间大小,系统栈和任务栈改变均无作用,结果依旧[/li]
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2017-8-26 01:44:04 | 显示全部楼层
进入函数  esp8266_apsta_test(str);里面逐步排查。
回复

使用道具 举报

5

主题

109

回帖

124

积分

初级会员

积分
124
 楼主| 发表于 2017-8-26 16:50:38 | 显示全部楼层

回 eric2013 的帖子

eric2013:进入函数  esp8266_apsta_test(str);里面逐步排查。 (2017-08-26 01:44)
多任务中单步调试 esp8266_apsta_test(str) 函数是执行完毕后,执行下一句延时函数时系统才挂的,这应该说明 esp8266_apsta_test(str) 函数并无问题,esp8266_apsta_test(str) 函数放于 RTXOS 中的执行单独任务中也并无问题,就是多个任务间切换只执行一次,单步调试到延时函数内系统就挂了。


并且将该工程移植进 FreeRTOS 系统,出现的结果跟 RTXRTOS 一样,这样的结果表明问题就在 esp8266_apsta_test(str) 函数,但是 esp8266_apsta_test(str) 函数在裸机下是执行正常的,也用了一段时间了并无问题,我分析应该是栈空间的不够,所以改大了,但结果依旧。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2017-8-28 01:51:19 | 显示全部楼层

回 打洞者 的帖子

打洞者:多任务中单步调试 esp8266_apsta_test(str) 函数是执行完毕后,执行下一句延时函数时系统才挂的,这应该说明 esp8266_apsta_test(str) 函数并无问题,esp8266_apsta_test(str) 函数放于 RTXOS 中的执行单独任务中也并无问题,就是多个任务间切换只执行一次,单步调试到延时函数内 .. (2017-08-26 16:50) 
把系统堆栈也加大下看看,即xxx.s文件中stack大小。

另外就是采用这种方式测试下,将main函数中所有代码注释掉,测试你的这个函数,看看是否正常,这样就排查了是否是你的工程有问题。
回复

使用道具 举报

5

主题

109

回帖

124

积分

初级会员

积分
124
 楼主| 发表于 2017-8-28 10:11:53 | 显示全部楼层
系统堆栈 任务堆栈之前都已改大测试过,结果依旧
系统栈      
0x0000 0400            --->                     0x0000 4000
任务栈      
static uint64_t AppTaskLEDStk[256/8*2];
static uint64_t AppTaskStartStk[256/8*8*8];


测试工程正确性
  1. int main()
  2. {
  3.         Stm32_Clock_Init(9);
  4.         delay_init(72);
  5.         LED_Init();        
  6.         usart1_init(460800);
  7.         esp8266_apsta_mode1();
  8.         esp8266_echo(OFF);
  9.                
  10. //        os_sys_init_user(        AppTaskStart,
  11. //                                 3,
  12. //                                 &AppTaskStartStk,
  13. //                                 sizeof(AppTaskStartStk));
  14.         
  15.         while(1)
  16.         {
  17.                 esp8266_apsta_test(str);
  18.                 delay_ms(100);
  19.         };
  20. }
复制代码
工作正常
QQ拼音截图未命名00.png
回复

使用道具 举报

5

主题

109

回帖

124

积分

初级会员

积分
124
 楼主| 发表于 2017-8-28 10:45:31 | 显示全部楼层

回 eric2013 的帖子

eric2013:

把系统堆栈也加大下看看,即xxx.s文件中stack大小。

另外就是采用这种方式测试下,将main函数中所有代码注释掉,测试你的这个函数,看看是否正常,这样就排查了是否是你的工程有问题。
情况1

条件
系统栈
Stack_Size      EQU     0x00000400
Heap_Size       EQU     0x00000200
任务栈

static uint64_t AppTaskLEDStk[256/8];static uint64_t AppTaskStartStk[256/8*8];

我将 esp8266_apsta_test(str) 函数屏蔽,加入 u1_printf("%s\\r\\n",str) 函数,运行正常 (工程还是原来的,多任务切换 一切都没变化)
  1. __task void AppTaskLED(void)
  2. {
  3. //       esp8266_trans();
  4.        while(1)
  5.        {
  6.                LED1 = !LED1;
  7. //              esp8266_apsta_test(str);
  8.                u1_printf("%s\\r\\n",str);
  9.                os_dly_wait(1000);
  10.        }
  11. }
复制代码
QQ拼音截图未命名001.png

情况2
条件
系统栈
Stack_Size      EQU     0x00000400
Heap_Size       EQU     0x00000200
任务栈

static uint64_t AppTaskLEDStk[256/8];
static uint64_t AppTaskStartStk[256/8*8];

我将 os_dly_wait(100) 函数屏蔽,加入 delay_ms(100) 函数,运行正常 (工程还是原来的,多任务切换 一切都没变化)
  1. __task void AppTaskLED(void)
  2. {
  3. //      esp8266_trans();
  4.        while(1)
  5.        {
  6.                LED1 = !LED1;
  7.                esp8266_apsta_test(str);
  8. //              u1_printf("%s\\r\\n",str);
  9.                delay_ms(100);
  10. //              os_dly_wait(100);
  11.         }
  12. }
复制代码
QQ拼音截图未命名002.png

情况3

条件
系统栈
Stack_Size      EQU     0x00000400
Heap_Size       EQU     0x00000200
任务栈
static uint64_t AppTaskLEDStk[256/8];
static uint64_t AppTaskStartStk[256/8*8];

刚刚单步调试发现,程序不是执行一次就挂了,而是一直在执行空闲任务
  1. /*--------------------------- os_idle_demon ---------------------------------*/
  2. __task void os_idle_demon (void) {
  3.   /* The idle demon is a system task, running when no other task is ready */
  4.   /* to run. The 'os_xxx' function calls are not allowed from this task.  */
  5.   for (;;) {
  6.   /* HERE: include optional user code to be executed when no task runs.*/
  7.     LED1 = !LED1;
  8. //os_dly_wait(100);
  9.       u1_printf("in idle now\\r\\n");
  10.   }
  11. }
复制代码
将代码第 10 行屏蔽,第 10行加入,则系统阻塞在 10 行处
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2017-8-29 02:43:24 | 显示全部楼层
你测试的三种情况里面没有见加大LED任务。将LED任务也加大,直接两个任务都设置成4096字节

static uint64_t AppTaskLEDStk[4096/8];
static uint64_t AppTaskStartStk[4096/8];

另外你的这些初始化,全部搞到任务AppTaskStar里面搞,这个里面没有设置滴答定时器吧,将设置滴答定时器的,关闭掉。

   Stm32_Clock_Init(9);
        delay_init(72);
        LED_Init();        
        usart1_init(460800);
        esp8266_apsta_mode1();
        esp8266_echo(OFF);
回复

使用道具 举报

5

主题

109

回帖

124

积分

初级会员

积分
124
 楼主| 发表于 2017-8-30 17:02:27 | 显示全部楼层

回 eric2013 的帖子

eric2013:你测试的三种情况里面没有见加大LED任务。将LED任务也加大,直接两个任务都设置成4096字节

static uint64_t AppTaskLEDStk[4096/8];
static uint64_t AppTaskStartStk[4096/8];

....... (2017-08-29 02:43) 
delay_init() 函数中使用了 systick 做延时,且未针对操作系统做修改,导致了这样的结果。
修改之后工作正常了    感谢[s:142][s:151]
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107034
QQ
发表于 2017-8-31 01:37:30 | 显示全部楼层

回 打洞者 的帖子

打洞者:delay_init() 函数中使用了 systick 做延时,且未针对操作系统做修改,导致了这样的结果。
修改之后工作正常了    感谢[s:142][s:151] (2017-08-30 17:02) 
[s:130]
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 07:09 , Processed in 0.239300 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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