当前位置: 首页 > news >正文

RTOS之二环境搭建初识RTOS

参考:https://blog.csdn.net/kouxi1/article/details/123650688

视频:https://www.bilibili.com/video/BV1b14y1c783/

RTOS本质就是切换线程栈,栈换了环境就换了,一个重要的结构tcb(linux叫PCB或thread_info)

struct tcb{

int32_t *sp; // 重要的sp指针,其它寄存器保存在栈中

struct tcb *next; // 下一个tcb

};

采用Valvano教授的RoundRobin_4C123源码一张图解释线程调度

两个重要文件os.c osasm.s

  1. os.c

void StartOS(void);

#define NUMTHREADS 3 // maximum number of threads

#define STACKSIZE 100 // number of 32-bit words in stack

void SetInitialStack(int i){

tcbs[i].sp = &Stacks[i][STACKSIZE-16]; // thread stack pointer

//r0-r3 r12,LR XPSR发生中断时自动压栈

Stacks[i][STACKSIZE-1] = 0x01000000; // thumb bit xPSR

Stacks[i][STACKSIZE-3] = 0x14141414; // R14 LR

Stacks[i][STACKSIZE-4] = 0x12121212; // R12 ip

Stacks[i][STACKSIZE-5] = 0x03030303; // R3

Stacks[i][STACKSIZE-6] = 0x02020202; // R2

Stacks[i][STACKSIZE-7] = 0x01010101; // R1

Stacks[i][STACKSIZE-8] = 0x00000000; // R0

//r4-r11要求程序处理

Stacks[i][STACKSIZE-9] = 0x11111111; // R11

Stacks[i][STACKSIZE-10] = 0x10101010; // R10

Stacks[i][STACKSIZE-11] = 0x09090909; // R9

Stacks[i][STACKSIZE-12] = 0x08080808; // R8

Stacks[i][STACKSIZE-13] = 0x07070707; // R7

Stacks[i][STACKSIZE-14] = 0x06060606; // R6

Stacks[i][STACKSIZE-15] = 0x05050505; // R5

Stacks[i][STACKSIZE-16] = 0x04040404; // R4

}

void OS_Launch(uint32_t theTimeSlice){

STCTRL = 0; // disable SysTick during setup

STCURRENT = 0; // any write to current clears it

SYSPRI3 =(SYSPRI3&0x00FFFFFF)|0xE0000000; // priority 7

STRELOAD = theTimeSlice - 1; // reload value

STCTRL = 0x00000007; // enable, core clock and interrupt arm

StartOS(); // 第一次启动一个线程

}

void Scheduler(void){

RunPt = RunPt->next; // Round Robin

}

  1. osasm.s

SysTick_Handler ; 自动保存 R0-R3,R12,LR,PC,PSR

CPSID I ; Prevent interrupt during switch

PUSH {R4-R11} ; 保存 r4-r11在马上成为旧线程的sp中

LDR R0, =RunPt ; R0=pointer to RunPt, old thread

LDR R1, [R0] ; R1 = 当前线程,也马上成为旧线程

STR SP, [R1] ; 保存马上成为旧线程的sp到TCB

PUSH {R0,LR} ; Scheduler会改变r0, LR,所以先保存(发生中断时LR=0xfffffff9,以 后要通过它触发中断返回)

BL Scheduler 找到下一个新线程

POP {R0,LR} 恢复r0, LR,

LDR R1, [R0] ; R1 = 新线程

LDR SP, [R1] ; 新的线程的 SP = RunPt->sp;

POP {R4-R11} ; 恢复r4-r11从新的线程的sp中

CPSIE I ; 9) tasks run with interrupts enabled

BX LR ; 10) LR=0xfffffff9触发中断返回,恢复 R0-R3,R12,LR,PC,PSR(注意这里恢复的PC,PSR是任务函数task()对应的地方,BX LR 后执行的就是恢复的PC所指的task里面地方,这样就继续从task里面执行)

StartOS

//R0=pointer to RunPt, old thread伪指令,调试时发现r0=0x0000044

//runPt=0x0000054 而且0x0000054中的内容为tcb[0]

LDR R0, =RunPt ; currently running thread

LDR R2, [R0] ; R2 = value of RunPt

LDR SP, [R2] ; new thread SP; SP = RunPt->stackPointer;

POP {R4-R11} ; 恢复 regs r4-11

POP {R0-R3} ; 恢复 regs r0-3

POP {R12}

ADD SP,SP,#4 ; 第一次,不需要返回,丢弃LR

POP {LR} ; 把task()函数地址推送给LR

ADD SP,SP,#4 ;第一次,丢弃 PSR

CPSIE I ; Enable interrupts at processor level

BX LR ; start first thread

ALIGN

END

http://www.lryc.cn/news/3196.html

相关文章:

  • 【Java】 JAVA Notes
  • Java笔记-volatile和AtomicInteger
  • [标准库]STM32F103R8T6 高级定时器--PWM输出和带死区互补PWM输出
  • Camtasia2023最新版电脑视频录屏记录编辑软件
  • 管理用户安全性
  • 分享113个JS菜单导航,总有一款适合您
  • RuoYi-Cloud 部署
  • DockerFile文件详解
  • Java程序运行机制
  • LeetCode刷题------字符串
  • 区块链技术与应用2——BTC-数据结构
  • BiseNet v1论文及其代码详解
  • (超详细)Navicat的安装和激活,亲测有效
  • JDY-31蓝牙模块使用指南
  • 【2023】华为OD机试真题Java-题目0211-租车骑绿道
  • leetcode: 3Sum
  • 【Python学习笔记】26.Python3 输入和输出(2)
  • vue项目第二天
  • Python爬虫零基础到进阶(课程说明)
  • 《C++ Primer Plus》第16章:string类和标准模板库(13)
  • 材质笔记 - Simluate Solid Surface
  • 设计模式-值类型与引用类型、深拷贝与浅拷贝、原型模式详解
  • ssm高校功能教室预约系统java idea maven
  • C语言学习笔记-强制类型转换
  • docker数据卷插件
  • 第二章-线程(3)
  • C++学习记录——칠 类和对象(4)
  • Python-项目实战--飞机大战-碰撞检测(8)
  • T06 成绩排序
  • 【机器学习】Linear and Nonlinear Regression 线性/非线性回归讲解