OpenEdv-开源电子网

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

请教下ucosiii例程中创建堆栈函数的详细解释

[复制链接]

83

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1987
金钱
1987
注册时间
2014-7-1
在线时间
188 小时
发表于 2015-11-6 10:33:28 | 显示全部楼层 |阅读模式
5金钱
例程中创建函数如下:
//创建开始任务

OSTaskCreate((OS_TCB * )&StartTaskTCB, //任务控制块
                (CPU_CHAR * )"start task", //任务名字
                 (OS_TASK_PTR )start_task, //任务函数
                 (void * )0, //传递给任务函数的参数
                 (OS_PRIO  )START_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&START_TASK_STK[0], //任务堆栈基地址
                 (CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位
                 (CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小
                 (OS_MSG_QTY  )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK  )0,//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   * )0, //用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR * )&err); //存放该函数错误时的返回值
我先说下自己的理解,请教下哪里理解错了,我不懂的地方也指点下
1、(OS_TCB * )&StartTaskTCB, //任务控制块
意思:将一个名为StartTaskTCB的任务控制块分配给start_task任务。
使用注意:StartTaskTCB需要先定义,定义为OS_TCB 类型。
2、
(CPU_CHAR * )"start task", //任务名字
意思:给
start_task任务起一个名字
使用注意:无
3、 (OS_TASK_PTR )start_task, //任务函数
意思:
start_task函数和start_task任务绑定,合二为一。
使用注意:无
4、(void * )0, //传递给任务函数的参数
意思:
传递给start_task函数一些参数
使用注意:无
5、(OS_PRIO  )START_TASK_PRIO,     //任务优先级
意思:设置
start_task任务的优先级
使用注意:无

6、(CPU_STK   * )&START_TASK_STK[0], //任务堆栈基地址
意思:设置任务堆栈的起始地址
使用注意:无
7、 (CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位
意思:检查任务堆栈是否为空,检查任务为START_STK_SIZE/10
使用注意:无
8、(CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小
意思:设置任务堆栈大小
使用注意:不明白设置多大为合适
9、 (OS_MSG_QTY  )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
意思:设置内部消息队列接收字节数
使用注意:无
10、(OS_TICK  )0,//当使能时间片轮转时的时间片长度,为0时为默认长度
意思:设置任务每次得到CUP使用权的运行时间
使用注意:注意最小单位
11、(void   * )0, //用户补充的存储区
意思:没想明白
使用
注意:无
12、(OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
意思:不知道。共有5个参数,英文虽然看的懂,但是意思不明白,想请教大家。
#define  OS_OPT_TASK_NONE                    (OS_OPT)(0x0000u)  /* No option selected  */没有选择选项
#define  OS_OPT_TASK_STK_CHK                 (OS_OPT)(0x0001u)  /* Enable stack checking for the task*/启动堆栈检测任务
#define  OS_OPT_TASK_STK_CLR                 (OS_OPT)(0x0002u)  /* Clear the stack when the task is create  */任务创建时清除堆栈
#define  OS_OPT_TASK_SAVE_FP                 (OS_OPT)(0x0004u)  /* Save the contents of any floating-point registers  */保存浮点寄存器的内容
#define  OS_OPT_TASK_NO_TLS                  (OS_OPT)(0x0008u)  /* Specifies the task DOES NOT require TLS support    */指定任务不需要TLS的支持
使用注意:不知道
13、(OS_ERR * )&err); //存放该函数错误时的返回值
意思:存放任务函数错误返回值
使用注意:无

最佳答案

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

UCOSIII原著所述:UC/OS-III在运行时能够计算一个任务实际使用的堆栈空间的大小以及剩余的堆栈空间的大小。这可由一个名为OSTaskStkChk()的函数完成。要计算堆栈的使用量,就必须在创建任务时把任务的堆栈清零。换句话说,当调用OSTaskCreate()时,应制定以下选项:OS_TASK_OPT_STK_CLR和OS_TASK_OPT_STK_CHK。这样,OSTaskCreate()函数就会把任务堆栈使用的RAM区清零。 在UC/OS-III中,有一个称为OS_StatTask()的系统任务,可 ...
做一个相信自己的人
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
232
金钱
232
注册时间
2014-8-6
在线时间
8 小时
发表于 2015-11-6 10:33:29 | 显示全部楼层
UCOSIII原著所述:UC/OS-III在运行时能够计算一个任务实际使用的堆栈空间的大小以及剩余的堆栈空间的大小。这可由一个名为OSTaskStkChk()的函数完成。要计算堆栈的使用量,就必须在创建任务时把任务的堆栈清零。换句话说,当调用OSTaskCreate()时,应制定以下选项:OS_TASK_OPT_STK_CLR和OS_TASK_OPT_STK_CHK。这样,OSTaskCreate()函数就会把任务堆栈使用的RAM区清零。

在UC/OS-III中,有一个称为OS_StatTask()的系统任务,可以在运行时检测每个任务的堆栈区。通常,OS_StatTask()会以一个很低的优先级运行,因此,它并不会干扰应用程序代码的正常运行。OS_StatTask()会把每个任务的计算结果写入每个任务的TCB中。  .StkUsed和 .StkFree分别表示该任务的堆栈空间中已使用和未使用的字节数。只有在编译时允许了统计任务(在os_cfg.h文件中,把OS_CFG_STAT_TASK_STK_CHK_EN设置为1),这两个成员才会出现在TCB中。

如上所述,楼主的第8条跟第12条密切相关。在程序设计之初,可将任务堆栈数值设的大一些,根据.StkUsed和 .StkFree的数值,确定最终的任务堆栈大小。程序产品化时,可将第12条设置为OS_OPT_TASK_NONE
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2015-11-8 23:17:40 | 显示全部楼层
帮顶.....
回复

使用道具 举报

83

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1987
金钱
1987
注册时间
2014-7-1
在线时间
188 小时
 楼主| 发表于 2015-11-9 19:15:26 | 显示全部楼层
回复【3楼】jnfxt95:
---------------------------------
含详细了,谢谢。
做一个相信自己的人
回复

使用道具 举报

83

主题

344

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1987
金钱
1987
注册时间
2014-7-1
在线时间
188 小时
 楼主| 发表于 2015-11-9 20:04:18 | 显示全部楼层
测试了下,2种方法都得到堆栈free和used的值,我把步骤写下。
1、建立一个任务。
/***************LED0任务************************/
//任务优先级
#define LED0_TASK_PRIO   4
//任务堆栈大小
#define LED0_TASK_SIZE   100//实际大小要乘 4
//任务控制块
OS_TCB Led0TaskTCB;//task control block
//任务堆栈
CPU_STK LED0_TASK_STK[LED0_TASK_SIZE];//task stack
//任务函数
void led0_task(void *p_arg);

//////////////////////////////////////////////////////////////////////////////////////
OS_CRITICAL_ENTER(); //进入临界区

OSTaskCreate((OS_TCB*)&Led0TaskTCB,//任务控制块地址
(CPU_CHAR*)"led0 task",//起一个任务名字
(OS_TASK_PTR)led0_task,//任务函数地址
(void *)0,//传递给任务函数的指针
(OS_PRIO )LED0_TASK_PRIO,//优先级
(CPU_STK *)&LED0_TASK_STK[0],//任务堆栈基地址
(CPU_STK_SIZE)LED0_TASK_SIZE/10,//任务堆栈深度
(CPU_STK_SIZE)LED0_TASK_SIZE,//任务堆栈大小
(OS_MSG_QTY)0,//消息队列大小
(OS_TICK)0,//时间片轮转
(void*)0,//用户补充的存储区
(OS_OPT)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,//任务选项
(OS_ERR*)&err);//存储错误返回值

OS_CRITICAL_EXIT(); //退出临界区
////////////////////////////////////////////////////////////////////////
2、编写测试函数
void led0_task(void* p_arg)
{
u8 i=0;
OS_ERR err;
CPU_STK_SIZE free,used;
p_arg=p_arg;
while(1)
{
//used=Led0TaskTCB.StkUsed;
//free=Led0TaskTCB.StkFree;
OSTaskStkChk (&Led0TaskTCB,&free,&used,&err);

LCD_ShowxNum(53,164,used,1,16,0);
LCD_ShowxNum(36,164,used/10,1,16,0);
LCD_ShowxNum(20,164,used/100,1,16,0);

LCD_ShowxNum(53,104,free,1,16,0);
LCD_ShowxNum(36,104,free/10,1,16,0);
LCD_ShowxNum(20,104,free/100,1,16,0);
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);
}
}
3、结果
都有结果输出,不过有些差别。
而且使用
used=Led0TaskTCB.StkUsed;
free=Led0TaskTCB.StkFree;
得按下按键,才会有结果。
做一个相信自己的人
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 16:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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