ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:17.19KB ,
资源ID:7477350      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7477350.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(UCOS操作系统堆栈浅谈.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

UCOS操作系统堆栈浅谈.docx

1、UCOS操作系统堆栈浅谈UCOS操作系统堆栈浅谈 1 声明堆栈大小 在uc/osii操作系统的任务切换和中断处理过程中,需要保存处理器的内部寄存器和变量的值,这就 要求每个任务都有自己的堆栈空间。堆栈必须声明为OS_STK类型,并且由连续的内存空间组成,可以静态分配空间(在编译时分配),也可以动态分配堆栈空间(在运行时分配)。由于采用动态分配方式,会导致内存中含有大量内存碎片,因此不推荐使用动态分配方式。其两种声明方式如下:静态分配方式:static OS_STK TaskStkStkSize;或者OS_STK TaskStkStkSize;动态分配方式:OS_STK *pstk;pstk =

2、 (OS_STK*)malloc(StkSize);if(pstk != (OS_STK*)0) /判断堆栈分配是否成功printf("Create TaskStk Success");2 设置堆栈生产方向uc/osii操作系统支持2中堆栈生长方向。即可从高地址往低地址生长,也可以由低地址往高地址生长。在调用OSTaskCreate()或者OSTaskCreateExt()创建任务的时候由于必须知道堆栈的生长方向,所以要在OS_CPU.H文件中设置任务堆栈的生长方向。#define OS_STK_GROWTH 1 /设置堆栈是从上往下长的OSTaskCreate(Task,

3、pdata,&TaskStkStkSize - 1,prio);或者#define OS_STK_GROWTH 0 /设置堆栈是从下往上长的OSTaskCreate(Task,pdata,&TaskStk0,prio); 当然也可以这样编写创建任务的以支持堆栈的从上往下和从下往上生长 #if OS_STK_GROWTH = 1OSTaskCreate(Task,pdata,&TaskStkStkSize - 1,prio);#elseOSTaskCreate(Task,pdata,&TaskStk0,prio);#endif 3 堆栈检验 为控制产品成本,有时需要确定任务实际需要的堆栈空间的大

4、小,避免为任务分配过多的对战空间,从而减少应用程序代码所需的RAM数量。uc/osii系统提供OSTaskStkChk()函数用以确定任务实际需要的堆栈空间。使用堆栈检验功能必须做一下几点:1.在OS_CFG.H文件中设置OS_TASK_CREATE_EXT为 12.使用OSTaskCreateExt()创建任务,并且赋予任务比实际需要多一点的空间。可以在任何任务中调用STaskStkChk()函数,对任何用OSTaskCreateExt()建立的任务进行堆栈检验。3.在OSTaskCreateExt()中,将参数opt设置为:OS_TASK_OPT_STK_CHK + OS_TASK_OPT

5、_STK_CLR4.把需要进行检测的任务的优先级作为OSTaskStkChk()的参数并调用应使自己的应用程序运行足够长的时间,并且经历最坏的堆栈使用情况,这样才能得到正确的树木。一旦得到所需要的对单需求,就可以重新设置堆栈的最终大小了。在堆栈检验中,所得到的只是一个大智的堆栈使用情况,并不能说明堆栈的使用全部实际情况。4 堆栈溢出在实际的项目中,由于产品的升级需要可能一个任务会经常修改,所需要的实际堆栈大小并不能很好的确定,即便使用堆栈检验功能后,在后续产品的升级过程中变量的增加会导致堆栈不够用。而在调试的过程中,如果没有堆栈溢出的报警机制,一旦堆栈出现溢出,这个问题是很难一时被发现的。在这

6、里,我建议在系统开始运行前,把每个任务的堆栈栈顶初始化一个值,每次出现任务切换的时候就读取对应栈顶的值,如果和初始化栈顶值相同的话就说明没有问题,如果值出现改变的话那么出现堆栈溢出的概率至少达到90以上,这样可以避免出现堆栈溢出而不能发现的尴尬。下面是个项目的一部分,删了一些,可供参考。 #include "user/lc_sqce_aj.h" #include "include_all.h" /* size of each tasks stacks (# of WORDs) */ #define TASK_START_STK_SIZE 128#defi

7、ne BUZZER_STK_SIZE 128#define CTRLMSG_STK_SIZE 128#define STORDEV_MOUNT_STK_SIZE 512#define MODE_SWITCH_STK_SIZE 512#define MODE_EXE_STK_SIZE 2000#define TWO_CHANNEL_REC_SIZE 512#define ALARM_STK_SIZE 128#define TASK_STK_SIZE 512 /* application tasks */ #define TASK_START_ID 0#define TASK_1_ID 1#def

8、ine TASK_2_ID 2#define TASK_3_ID 3#define TASK_4_ID 4#define TASK_5_ID 5#define TASK_6_ID 6#define TASK_7_ID 7#define TASK_8_ID 8#define TASK_9_ID 9#define TASK_10_ID 10#define TASK_11_ID 11#define TASK_12_ID 12#define TASK_13_ID 13#define TASK_14_ID 14#define TASK_15_ID 15 /* application tasks prio

9、rities */ #define TASK_START_PRIO 0#define TASK_1_PRIO 1#define TASK_2_PRIO 2#define TASK_3_PRIO 3#define TASK_4_PRIO 4#define TASK_5_PRIO 5#define TASK_6_PRIO 6#define TASK_7_PRIO 7#define TASK_8_PRIO 8#define TASK_9_PRIO 9#define TASK_10_PRIO 10#define TASK_11_PRIO 11#define TASK_12_PRIO 12#define

10、 TASK_13_PRIO 13#define TASK_14_PRIO 14#define TASK_15_PRIO 15 /*see task stacks*/ OS_STK TaskStartStkTASK_START_STK_SIZE;OS_STK BuzzerStkBUZZER_STK_SIZE;OS_STK CtrlmsgStkCTRLMSG_STK_SIZE;OS_STK StorDevStkSTORDEV_MOUNT_STK_SIZE;OS_STK ModeSwitchStkMODE_SWITCH_STK_SIZE;OS_STK ModeExeStkMODE_EXE_STK_S

11、IZE;static void TaskStart(void *p_arg); /函数声明static void TaskStartCreateTasks(void);void InitStackMark(void); /* /* 函数名 :main/* 返回值 :N/A/* 参数 :N/A/* 函数说明:主函数/* 作 者:啊呆/* void main(void) INT8U err; / initialize uC/OS-II OSInit(); / install uC/OS-IIs context switch vector IRQSetVect(uCOS, OSCtxSw); OST

12、askCreateExt(TaskStart, (void *)0, &TaskStartStkTASK_START_STK_SIZE - 1, TASK_START_PRIO, TASK_START_ID, &TaskStartStk0, TASK_START_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CLR + OS_TASK_OPT_STK_CHK); OSTaskNameSet(TASK_START_PRIO, "Start Task", &err); / start multitasking OSStart(); /* /* 函数名

13、 :TaskStart/* 返回值 :N/A/* 参数 :void *p_arg/* 函数说明:创建TaskStart任务/* 作 者:啊呆/*static void TaskStart(void *p_arg) #if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr; #endif / prevent compiler warning p_arg = p_arg; / install uC/OS-IIs clock tick ISR OS_ENTER_CRITICAL(); IRQSetVect(TMR1_VEC, OSTickISR); OSSetTickR

14、ate(lc_clk_get_freq(CLK_SYS_SEL), OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); / initialize uC/OS-IIs statistics OSStatInit(); TaskStartCreateTasks(); for (;) / clear the context switch counter OSCtxSwCtr = 0; / wait one second OSTimeDly(OS_TICKS_PER_SEC); /* /* 函数名 :TaskStartCreateTasks/* 返回值 :N/A/* 参数 :

15、N/A/* 函数说明:创建任务/* 作 者:啊呆/*static void TaskStartCreateTasks(void)/初始化,创建每个任务对应需要的信号量 init_buzzer_proc(); init_ModeEXE_proc(); init_ctrlmsg_get_proc(); init_twoChRec_proc(); InitStackMark(); /创建任务 OSTaskCreate(buzzer_proc, (void *)0, &BuzzerStkBUZZER_STK_SIZE-1, TASK_3_PRIO); OSTaskCreate(ctrlmsg_get_

16、proc, (void *)0, &CtrlmsgStkCTRLMSG_STK_SIZE-1, TASK_5_PRIO); OSTaskCreate(stordev_mount_proc, (void *)0, &StorDevStkSTORDEV_MOUNT_STK_SIZE-1, TASK_6_PRIO); OSTaskCreate(mode_switch_proc, (void *)0, &ModeSwitchStkMODE_SWITCH_STK_SIZE-1, TASK_7_PRIO); OSTaskCreate(ModeEXE_proc, (void *)0, &ModeExeStk

17、MODE_EXE_STK_SIZE-1, TASK_11_PRIO); /* /* 函数名 :InitStackMark/* 返回值 :N/A/* 参数 :N/A/* 函数说明:初始化堆栈栈顶/* 作 者:啊呆/*void InitStackMark(void)/初始化每个堆栈栈顶 BuzzerStk0=0x5153; BuzzerStk1=0xAA55; CtrlmsgStk0=0x5153; CtrlmsgStk1=0xAA55; StorDevStk0=0x5153; StorDevStk1=0xAA55; ModeSwitchStk0=0x5153; ModeSwitchStk1=0x

18、AA55; ModeExeStk0=0x5153; ModeExeStk1=0xAA55; /* /* 函数名 : CheckStkOverFlow/* 返回值 :BOOLEAN/* 参数 :INT8U TaskName/* 函数说明:初检测堆栈溢出/* 作 者:啊呆/*BOOLEAN CheckStkOverFlow(INT8U TaskName)/判断是否堆栈溢出 if(TaskName=buzzer) if(BuzzerStk0=0x5153 & BuzzerStk1=0xAA55) return FALSE; else if(TaskName=ctrlmsg) if(CtrlmsgSt

19、k0=0x5153 & CtrlmsgStk1=0xAA55) return FALSE; else if(TaskName=stordev_mount) if(StorDevStk0=0x5153 & StorDevStk1=0xAA55) return FALSE; else if(TaskName=mode_switch) if(ModeSwitchStk0=0x5153 & ModeSwitchStk1=0xAA55) return FALSE; else if(TaskName=ModeEXE) if(ModeExeStk0=0x5153 & ModeExeStk1=0xAA55) return FALSE; return TRUE;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1