uC/OS如何保存局部变量到任务堆栈中

今天有人跟我请教RTOS任务的切换问题,堆栈部分我发现自己也不是太明白,遂google之,得到一篇很好的文章,分享给大家;(以uC/OS为例说明)
转载自:http://www.cnblogs.com/mojietuyoudianleng/p/4189464.html

1.没有OS时,任务如何保存局部变量

在我的知识体系里,我一直以为单片机中就只有一个栈,以stm32为例,在启动文件中有怎么一段:

; Amount of memory (in bytes) allocated for Stack

; Tailor this value to your application needs

; Stack Configuration

; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>

;

Stack_Size EQU 0x00000400

                  AREA    STACK, NOINIT, READWRITE, ALIGN=3

Stack_Mem SPACE Stack_Size

__initial_sp

假设stm32的内存有16Kb,起始地址为,栈向下生长,从启动文件中可以看到,栈的大小为0x400,我称之为系统栈,系统栈的范围为0x0x20000000~0x20000400 。在没有OS的应用中(裸奔),cpu其实有两个任务,一个是中断任务,一个是main函数中的后台任务。当函数调用或者发生中断时,就使用系统栈保存局部变量和寄存器状态,也就是SP指向0x0x20000000~0x20000400。

2.ucos中如何保存局部变量

 其实有没有操作系统都一样,都把任务中的局部变量和当前的寄存器状态保存在栈中,在UCOS中一个任务就分配一个栈,假设有两个任务,申请分配对应的任务栈如下:

static OS_STK Task1Stk[128]; //假设任务1的堆栈地址为0x20000500,那么任务1中的局部变量和寄存器状态将保存在0x20000500~0x20000580

static OS_STK Task2Stk[256]; //假设任务1的堆栈地址为0x20000600,那么任务2中的局部变量和寄存器状态将保存在0x20000600~0x20000700

当任务1运行时,系统使用的栈不再是0x0x20000000~0x20000400,而是0x20000500~0x20000580,任务2运行时,系统中的栈指向0x20000600~0x20000700。那么如何切换SP呢?假设切换到任务1SP:
;保存任务1SP

LDR     R1, =Task1Stk        ; 把SP存在R1中,在任务1中R1等于0x20000500~0x20000580
LDR     R1, [R1]
STR     R0, [R1]             ; R0 is SP of process being switched out

;切换到任务1的SP

MSR     PSP, R0              ; Load PSP with new process SP

就这样,在UCOS中的模拟系统栈,生成任务栈,局部变量在任务栈中的分配,而非在系统栈中。而我之前的困惑是以为任务中的局部变量是分配到系统栈中,待任务切换中把系统栈中的内容负责到任务栈中。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值