自己写的类UCOS操作系统内核(源码)

必备知识:

PendSV是什么?
根据 权威指南。为系统设备而设的“可悬挂请求”(pendable request)。
1.上下文切换 不能在中断中进行,会导致中断延期。为了解决这个问题,使用 PendSV。PendSV可以挂起,也就是等到别的 ISR结束后 缓期执行。
2.所以 PendSV是一个最低优先级的异常。
 
Cortex-M3内核有两个堆栈指针 :MSP-主堆栈指针和PSP-进程堆栈指针,在任何一个时刻只能有一个堆栈指针起作用,也就是说任何一个时刻只能使用一个堆栈指针,要么使用MSP,要么使用PSP。何为堆栈指针,其实就是普通的指针,只是他们指向两个不同的堆栈。

MSP:主堆栈指针 ,当程序复位后(开始运行后),一直到第一次任务切换完成前,使用的都是MSP,即:main函数运行时用的是MSP,运行OSStartHighRdy,运行PendSV程序,用的都是MSP。当main函数开始运行前,启动文件会给这个函数分配一个堆栈空间,像ucos给任务分配堆栈空间一样,用于保存main函数运行过程中变量的保存。此时MSP就指向了该堆栈的首地址。

PSP:进程堆栈指针 ,切换任务之后PendSV服务程序中有ORR LR, LR, #0x04这句,意思就是PendSV中断返回后使用的PSP指针,此时PSP已经指向了所运行任务的堆栈,所以返回后就可以就接着该任务继续运行下去了。
由于任何一个时刻都只能使用一个堆栈指针(SP),所以,如果在某一个时刻,需要读取或者改变另外一个堆栈指针的内容就得使用特定的指令:MSR和MRS

lr就是连接寄存器(Link Register, LR) ,在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。

PC(R15) 是当前地址,把LR给PC就是从子程序返回


源码: https://github.com/0Hellc0/Elmer-MayDayOS

设计思路:

 
一个最基本的内核,只有task switch功能。

三个任务设计成 开led 左,开led 右,全关.

执行流程
  1. 初始化 TCB[3]
TCB-taskaddr = 0 TCB-status TCB-stackP = 0
相关的几个全局变量 NowTaskNum = 0
创建空转任务,cur next TCB 都是空转,cur TCB = idle, next TCB =idle
  1. 创建任务,其实就是把任务放到TCB中, task1{}task2{}task3{},,空任务
task1stack[20]
TCB[0]-taskaddr = task1
TCB[0]-stackP = task1stack
对任务堆栈 初始化  entry point  = task 地址
xPSR
R0   任务函数参数的所在地址   暂时为 0
其他随机值
  1. System init
  2. Hardware init
  3. OSStart
TCB 里面指向的都是空转任务,开始空转任务
当前执行在 PC OSStart 这个函数,
  1. 第一次  进入pendsv中断,进行切换到 task1PendSV中断处理:
    1. 进入临界区
    2. 判断 NowTaskNum +1 是否正确
    3. curTCB  = TCB[ NowTaskNum +1];
    4. curTCB 里面的堆栈值取出来,加载到 R4~R11寄存器,最后加载pc
    5. PSP = R0
    6. CPU会自动从PSP保存和加载8个量至R0~R3,R12,LR,程序入口(这个是理解的关键)和xPSR,我们无需动手
    7. 退出临界区
    8. 开始执行 curTCB 指向的任务地址。
  2. 正常的进入PendSV中断
    1. 进入临界区
    2. 保存现在的task 相关寄存器
    3. R4-R11保存在当前TCB 指向的栈顶
    4. 保存完毕,切换到下个task,同上
 

 
PendSV是什么?
根据 权威指南。为系统设备而设的“可悬挂请求”(pendable request)。
1.上下文切换 不能在中断中进行,会导致中断延期。为了解决这个问题,使用 PendSV。PendSV可以挂起,也就是等到别的 ISR结束后 缓期执行。
2.所以 PendSV是一个最低优先级的异常。
 
Cortex-M3内核有两个堆栈指针 :MSP-主堆栈指针和PSP-进程堆栈指针,在任何一个时刻只能有一个堆栈指针起作用,也就是说任何一个时刻只能使用一个堆栈指针,要么使用MSP,要么使用PSP。何为堆栈指针,其实就是普通的指针,只是他们指向两个不同的堆栈。

MSP:主堆栈指针 ,当程序复位后(开始运行后),一直到第一次任务切换完成前,使用的都是MSP,即:main函数运行时用的是MSP,运行OSStartHighRdy,运行PendSV程序,用的都是MSP。当main函数开始运行前,启动文件会给这个函数分配一个堆栈空间,像ucos给任务分配堆栈空间一样,用于保存main函数运行过程中变量的保存。此时MSP就指向了该堆栈的首地址。

PSP:进程堆栈指针 ,切换任务之后PendSV服务程序中有ORR LR, LR, #0x04这句,意思就是PendSV中断返回后使用的PSP指针,此时PSP已经指向了所运行任务的堆栈,所以返回后就可以就接着该任务继续运行下去了。
由于任何一个时刻都只能使用一个堆栈指针(SP),所以,如果在某一个时刻,需要读取或者改变另外一个堆栈指针的内容就得使用特定的指令:MSR和MRS

lr就是连接寄存器(Link Register, LR) ,在ARM体系结构中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。

PC(R15) 是当前地址,把LR给PC就是从子程序返回
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值