OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3087|回复: 4

一个ucosii菜鸟关于任务堆栈的小问题

[复制链接]

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2016-9-11
在线时间
22 小时
发表于 2016-11-28 12:52:34 | 显示全部楼层 |阅读模式
1金钱
今天实验了一下ucos开发手册里的一个例子,发现一个问题,当任务堆栈大小为128的时候,led和串口三个任务都能运行,如果把任务堆栈的大小改为64,代码烧到板子上没反应,但是如果把串口的任务隐去,led任务能运行,哪个大神能告告我这是为啥?以下是代码。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "includes.h"
#define START_TASK_PRIO     10
#define START_STK_SIZE      128
OS_STK START_TASK_STK[START_STK_SIZE];
void start_task(void *pdata);
#define LED0_TASK_PRIO     7
#define LED0_STK_SIZE      128
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
void led0_task(void *pdata);
#define LED1_TASK_PRIO     6
#define LED1_STK_SIZE      128
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
void led1_task(void *pdata);
#define FLOAT_TASK_PRIO   5
#define FLOAT_STK_SIZE     128
__align(8) OS_STK FLOAT_TASK_STK[FLOAT_STK_SIZE];
void float_task(void *pdata);
int main()
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
LED_Init();

OSInit();
OSTaskCreate(start_task,
        (void *)0,
        (OS_STK *)&START_TASK_STK [START_STK_SIZE-1],
        START_TASK_PRIO
        );
OSStart();
}
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr = 0;
pdata = pdata;
OS_ENTER_CRITICAL();
OSTaskCreate(led0_task,//创建任务的名称
        (void *)0,//创建任务的参数
        (OS_STK *)&LED0_TASK_STK[LED0_STK_SIZE-1],//任务的堆栈
        LED0_TASK_PRIO //任务优先级
       );
OSTaskCreate(led1_task,
        (void *)0,
        (OS_STK *)&LED1_TASK_STK[LED1_STK_SIZE-1],
        LED1_TASK_PRIO
       );
  OSTaskCreate(float_task,
        (void *) pdata,
        (OS_STK *)&FLOAT_TASK_STK[FLOAT_STK_SIZE-1],
        FLOAT_TASK_PRIO
        );
OSTaskSuspend(START_TASK_PRIO);
OS_EXIT_CRITICAL();
}
void led0_task(void *pdata)
{
while(1)
{
  LED0 = 0;
  delay_ms(80);
  LED0 = 1;
  delay_ms(920);
}
}
void led1_task(void *pdata)
{
while(1)
{
  LED1 = 0;
  delay_ms(300);
  LED1 = 1;
  delay_ms(300);
}
}
void float_task(void *pdata)
{
OS_CPU_SR cpu_sr = 0;
static int float_num = 0;
while(1)
{
  float_num += 1;
  OS_ENTER_CRITICAL();
  printf("第%4d秒\r\n", float_num);
  OS_EXIT_CRITICAL();
  delay_ms(1000);
}
}


最佳答案

查看完整内容[请看2#楼]

1.没看到串口函数 2.后面发的demo中都是简单的led功能,所需栈空间小,所以可以成功 3.怀疑你的floattask,关于float占用空间较大,去查查 4.建议开始学习的时候,使用OSTaskCreateExt新建任务,监控实时的栈空间使用情况 5.在关键的地方加入测试点,以便后期打桩测试
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2015-3-31
在线时间
1 小时
发表于 2016-11-28 12:52:35 | 显示全部楼层
1.没看到串口函数
2.后面发的demo中都是简单的led功能,所需栈空间小,所以可以成功
3.怀疑你的floattask,关于float占用空间较大,去查查
4.建议开始学习的时候,使用OSTaskCreateExt新建任务,监控实时的栈空间使用情况
5.在关键的地方加入测试点,以便后期打桩测试
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2016-11-28 14:12:46 | 显示全部楼层
明显的堆栈溢出了
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2016-9-11
在线时间
22 小时
 楼主| 发表于 2016-11-28 14:39:08 | 显示全部楼层

但是实验例程里也有个类似的,也是三个任务,当它的任务堆栈大小就是64,可以运行,为啥呢?
#include "led.h"
#include "beep.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"         
#include "includes.h"          

#define START_TASK_PRIO                              10
#define START_STK_SIZE                                  64
OS_STK START_TASK_STK[START_STK_SIZE];
void start_task(void *pdata);       
                          


#define LED_TASK_PRIO                               7
#define LED_STK_SIZE                                      64
OS_STK LED_TASK_STK[LED_STK_SIZE];
void led_task(void *pdata);


#define BEEP_TASK_PRIO                               5
#define BEEP_STK_SIZE                                          64
OS_STK BEEP_TASK_STK[BEEP_STK_SIZE];
void beep_task(void *pdata);


#define KEY_TASK_PRIO                               3
#define KEY_STK_SIZE                                          64
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
void key_task(void *pdata);
                       
int main(void)
{         
  

        delay_init();                     //延时函数初始化          
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级   
        uart_init(9600);
        LED_Init();                                  //初始化与LED连接的硬件接口
        BEEP_Init();                        //蜂鸣器初始化       
        KEY_Init();                                //按键初始化
        OSInit();                                   //初始化UCOSII                                           
        OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
        OSStart();            
}

//开始任务
void start_task(void *pdata)
{
    OS_CPU_SR cpu_sr=0;
        pdata = pdata;                                                              
        OSStatInit();                                        //初始化统计任务.这里会延时1秒钟左右       
        OS_ENTER_CRITICAL();                        //进入临界区(无法被中断打断)   
        OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);                                                                                      
        OSTaskCreate(beep_task,(void *)0,(OS_STK*)&BEEP_TASK_STK[BEEP_STK_SIZE-1],BEEP_TASK_PRIO);                                                                              
        OSTaskCreate(key_task,(void *)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);                                           
        OSTaskSuspend(START_TASK_PRIO);        //挂起起始任务.
        OS_EXIT_CRITICAL();                                //退出临界区(可以被中断打断)
}          
//LED任务
void led_task(void *pdata)
{   
        while(1)
        {  
             LED0=!LED0;
                 LED1=!LED1;
                           delay_ms(500);
        }                                                                         
}          

//蜂鸣器任务
void beep_task(void *pdata)
{
        while(1)
        {         
           if(OSTaskDelReq(OS_PRIO_SELF)==OS_ERR_TASK_DEL_REQ) //判断是否有删除请求
                 {
                 OSTaskDel(OS_PRIO_SELF);                                                   //删除任务本身TaskLed
                 }
                 BEEP=1;
                   delay_ms(60);
             BEEP=0;
                 delay_ms(940);
        }                                                                         
}

//按键扫描任务
void key_task(void *pdata)
{       
        u8 key;                                                                     
        while(1)
        {
                key=KEY_Scan(0);
                if(key==KEY0_PRES)
                {
                  OSTaskSuspend(LED_TASK_PRIO);//挂起LED任务,LED停止闪烁
                }
                else if (key==KEY2_PRES)
                {
                  OSTaskResume(LED_TASK_PRIO);        //恢复LED任务,LED恢复闪烁
                }
                else if (key==WKUP_PRES)
                {
                  OSTaskDelReq(BEEP_TASK_PRIO);        //发送删除BEEP任务请求,任务睡眠,无法恢复
                }
                else if(key==KEY1_PRES)
                {
                 OSTaskCreate(beep_task,(void *)0,(OS_STK*)&BEEP_TASK_STK[BEEP_STK_SIZE-1],BEEP_TASK_PRIO);//重新创建任务beep                                                                              
                }   
                delay_ms(10);
        }
}


回复

使用道具 举报

5

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
229
金钱
229
注册时间
2016-7-30
在线时间
82 小时
发表于 2016-11-29 16:49:33 | 显示全部楼层
每个任务运行所需的堆栈空间不同吧
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-1 22:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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