RTOS必备基础

一、ARM基础知识

1、ARM架构

  1. 程序编译后生成 .bin、.hex文件,(汇编代码)烧入Flash中。
  2. 启动设备,程序在Flash中一条一条执行。
  3. 程序告诉CPU执行操作,如分配内存、分配栈、计算。
  4. CPU操作,如从内存中某个地址读写数据、开辟空间,GPIO的读写等。
    在这里插入图片描述

CPU运行时,先去取得指令,再执行指令:
① 把内存a的值读入CPU寄存器R0
② 把内存b的值读入CPU寄存器R1
③ 把R0、R1累加,存入R0(对于数据的运算是在cpu内部执行)
④ 把R0的值写入内存a

2、重要寄存器

R#APCS别名意义
R0a1参数/结果/scratch 寄存器1
R1a2参数/结果/scratch 寄存器2
R2a3参数/结果/scratch 寄存器3
R3a4参数/结果/scratch 寄存器4
R4v1arm 状态局部变量寄存器1
R5v2arm 状态局部变量寄存器2
R6v3arm 状态局部变量寄存器3
R7v4 / wrarm 状态局部变量寄存器4 / thumb状态工作寄存器
R8v5arm 状态局部变量寄存器5
R9v6 / sbarm 状态局部变量寄存器6 / 在支持RWPI的ATPCS中作为静态基址寄存器
R10v7 / slarm 状态局部变量寄存器7 / 在支持数据栈检查的ATPCS中作为数据栈限制指针
R11v8 / fparm 状态局部变量寄存器8 / 帧指针
R12ip内部过程调用 scratch寄存器
R13sp栈指针
R14lr链接寄存器
R15pc程序计数器

高编号的寄存器保存在高地址,低编号的寄存器保存在低地

  1. R0-R12:数据寄存器
    调用C函数时 第一个参数保存在R0中 第二个参数保存在R1中
  2. R13:SP:栈
  3. R14:LR
    跳转到子过程的时候,r14保存了返回地址,可以在调用过程结尾恢复。
    异常中断发生时,这个异常模式特定的物理R14被设置成该异常模式将要返回的地址
  4. R15:PC
    存放指令(函数)的地址 (后续会放入R0寄存器中)

3、汇编指令详解

读:load

LDR R0, [addr A]

将addr A的值读到 R0寄存器

LDR:将 存储器地址 所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中。

写: store

STR R0,[addr A]

将addr A的值写到 R0寄存器

STR:用于从源寄存器中将一个32位的字数据传送到存储器

加: ADD

ADD  R0,R1,R2

R0=R1+R2

ADD:两数相加

减: SUB

SUB A,B //A=A-B;

功能: 两个操作数的相减,即从A中减去B,其结果放在A中.

出栈: push

push    {R3,LR}//括号中的顺序不强制规定

作用: push寄存器:将一个寄存器中的数据入栈(写入内存)

  1. 写入内存的位置由SP指定

  2. 高编号的寄存器保存在高地址,低编号的寄存器保存在低地址

出栈:pop

pop  {R3,PC}//读数据赋值给RC和PC

读数据从SP指向的位置读取数据

在这里插入图片描述

  1. R3=[SP]:读取R3中的数据
  2. SP递增
  3. PC=[SP]:读取LR (函数返回地址)

在这里插入图片描述

4、栈和堆:

1. 栈

发生中断时,会保存现场:值保存在栈中
栈的整体作用
(1)保存现场/上下文
(2)传递参数:汇编代码调用c函数时,需传递参数
(3)保存临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

需要保存哪些数值

C程序中的保存数值
1.任务切换的时候 寄存器都要保护
2.函数调用的时候只保存改变后的值

用于传参的寄存器则不需要保存如上面的R0 R1 R2

内核中的中断保存数值
cortex M3和M4

  1. 硬件保存一部分 R0 R1 R2 入栈
  2. 软件就保存用到的值

栈的大小取决于

  1. 局部变量的多少
  2. 调用深度

栈的内存从哪里分配

  1. freertos的栈 由一个巨大的 全局数组 分配
  2. 调用深度

2. 堆

一块空闲内存,可以使用malloc/free函数来管理

volatile char my_buf[20*1024];
volatile int index = 0;

void *malloc(int size)
{
	char *ret = &my_buf[index];
	index += size;
	return ret;
}

5、 局部变量和全局变量的分配与初始化

1. 局部变量初始化

C语言:

void my_main(void)
{
	int a = 456;

汇编:

//  执行my_main()
PUSH	{r3,lr}			//进入函数,寄存器r3、lr的值,都存入内存的栈中(lr保存程序返回地址)

//	执行 int a = 456
MOV		r0,#0x1C8		//0x1c8 = 456
STR		r0,[sp,#0x00]

在这里插入图片描述

2. 全局变量、静态变量初始化

在调用main函数之前,使用copy、SetZero函数对全局变量、静态变量初始化

6、 函数是什么

二、RTOS系统注意事项

  1. 对于实时操作系统 高优先级的任务 永远优先执行(如果没有delay 将程序进入阻塞态 那实时操作系统就一直执行高优先级)
  2. 空闲任务(优先级通常较低)由调度器创建 会影响同样是0的优先级任务(相同优先级 空闲任务最后创建 所以最先执行)
  3. 空闲任务礼让:同等优先级 先等其他任务运行一次后 再运行空闲任务
  4. 在大于或 等于 优先级的时 如果任务1先创建 任务2后创建 就会先执行任务2 ​​​​​​​​​​​​​​​​​在这里插入图片描述
  5. 当任务 配置成 不抢占 不轮流 不礼让的时候
    创建 顺序从左到右: 任务①<<任务②<<任务③<<空闲任务A
    执行顺序如下:空闲任务 A 执行释放内存后 会礼让
    空闲任务A << 任务① << 任务① << 任务①
    一直会执行 任务①(可设置主动放弃入 即加入delay进入阻塞态就可以运行任务②)
    不抢占就不会轮流执行 中断的优先级>任务优先级

参考:散文诗

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值