参考教程

[野火]《uCOS-III内核实现与应用开发实战指南》
开发板---->野火MINI_STM32F103RCT6

1.轮询系统
2.前后台系统
3.多任务系统

事件的响应和处理方式
轮询系统 在主程序响应和处理
前后台系统 中断响应,在主程序处理
多任务系统 中断响应,在任务中处理

堆栈的认识

我们所说的堆栈其实是两个东西,分别是堆和栈,当然如果有人给你说起堆栈这个名词,那他想要表达的一定是栈这个概念。除了放置全局变量是在堆区,其他像局部变量,函数参数全部分配在栈区,栈是由高地址向低地址生长的。这一点与堆不一样,堆由低地址向高地址生长。
分配方式:堆都是动态分配的,没有静态分配的堆。

cpu.h程序

/*cpu.h头文件内容*/
#ifndef CPU_H
#define CPU_Htypedef unsigned short CPU_INT16U;
typedef unsigned int   CPU_INT32U;
typedef unsigned char  CPU_INT08U;typedef CPU_INT32U CPU_ADDR;/*堆栈数据类型重定义*/typedef CPU_INT32U CPU_STK;
typedef CPU_ADDR   CPU_STK_SIZE;
typedef volatile CPU_INT32U CPU_REG32;#endif

结构体能不能作为参数传入函数?

os_task.c程序

/*实现任务创建函数*/void OSTaskCreate(OS_TCB       *p_tcb,OS_TASK_PTR   p_task,void         *p_arg,CPU_STK      *p_stk_base,CPU_STK_SIZE  stk_size,OS_ERR       *p_err)
{CPU_STK  *p_sp;p_sp = OSTaskStkInit( p_task, p_arg,p_stk_base,stk_size);p_tcb->StkPtr = p_sp;p_tcb->StkSize = stk_size;*p_err = OS_ERR_NONE;//执行到这一步,表示没有错误!}
/*(1)p_tcb是任务控制块TCB指针(2)p_task是任务函数名,类型为OS_TASK_PTR,原型声明在os.h  typedef void  (*OS_TASK_PTR)(void *p_arg);(3)p_arg是任务形参,用于传递任务参数(4)p_stk_base 用于指向任务堆栈的起始地址(5)stk_size 表示任务堆栈的大小(6)p_err用于存放错误码,这个错误码是uC/OS-III已经预定义好的,错误码是枚举类型
*//*错误码枚举类型*/typedef enum os_err {OS_ERR_NONE = 0u,OS_ERR_A = 10000u,OS_ERR_ACCEPT_ISR = 10001u,OS_ERR_B = 11000u,OS_ERR_C = 12000u,OS_ERR_CREATE_ISR = 12001u,/* 篇幅限制,中间部分删除,具体的可查看本章配套的例程 */OS_ERR_X = 33000u,OS_ERR_Y = 34000u,OS_ERR_YIELD_ISR = 34001u,OS_ERR_Z = 35000u
} OS_ERR;

-------------------------------写于2022.1.10 晚上12.25,明天再继续看

1.10 下午7.10 Hello!兄弟们,继续啃!
在OSTaskCreate()函数中我们调用了OSTaskStkInit()函数,我们来看看OSTaskStkInit()的函数原型:

CPU_STK *OSTaskStkInit(OS_TASK_PTR   p_task,)void         *p_arg,CPU_STK      *p_stk_base,CPU_STK_SIZE  stk_size)
{CPU_STK *p_stk;p_stk = &p_stk_base[stk_size];//异常发生时自动保存的寄存器*--p_stk = (CPU_STK)0x01000000u;  //xPSR的bit24必须置1*--p_stk = (CPU_STK)p_task;       //R15(PC)任务的入口地址*--p_stk = (CPU_STK)0x14141414u;  //R14(LR)                *--p_stk = (CPU_STK)0x12121212u;  //R12*--p_stk = (CPU_STK)0x03030303u;  //R3*--p_stk = (CPU_STK)0x02020202u;  //R2*--p_stk = (CPU_STK)0x01010101u;  //R1*--p_stk = (CPU_STK)p_arg;        //R0:任务参数//异常发生时需手动保存的寄存器R4~R11*--p_stk = (CPU_STK)0x11111111u;   //R11*--p_stk = (CPU_STK)0x10101010u;   //R10*--p_stk = (CPU_STK)0x09090909u;   //R9*--p_stk = (CPU_STK)0x08080808u;   //R8*--p_stk = (CPU_STK)0x07070707u;   //R7*--p_stk = (CPU_STK)0x06060606u;   //R6*--p_stk = (CPU_STK)0x05050505u;   //R5*--p_stk = (CPU_STK)0x04040404u;   //R4return (p_stk);}

刚开始我发现寄存器号与16进制数”居然一样“,疑惑下,不会这么巧?看到后面发现处于调试方便,故意这样做的
给出程序的解释:
(1)p_task 是任务名,指示着任务的入口地址,在任务切换的时候,
需要加载到 R15,即 PC 寄存器,这样 CPU 就可以找到要运行的任务。
(2)p_arg 是任务的形参,用于传递参数,在任务切换的时候,需要
加载到寄存器 R0。R0 寄存器通常用来传递参数。
(3)p_stk_base 表示任务堆栈的起始地址。
(4)stk_size 表示任务堆栈的大小,数据类型为 CPU_STK_SIZE,在
Cortex-M3 内核的处理器中等于 4 个字节,即一个字。

typedef unsigned int      CPU_INT32U;
typedef CPU_INT32U        CPU_ADDR;
typedef CPU_ADDR          CPU_STK_SIZE;

(5)获取栈顶地址,前面我们说过栈有个特殊的地方,就是由高地址向低地址生长,
参考博客:手撕startup_stm32f10x_hd.s启动文件源码
(6)任务第一次运行,加载到CPU寄存器的环境参数我们要预先初始化好。初始化的顺序固定(这个是为什么?我认为xPSR,PC,LR固定顺序就OK啊?其他的没必要啊)
异常发生时自动保存的8个寄存器,即xPSR,PC,LR,R12,R3,R2,R1,R0(这个为什么就是自动保存的?其他为什么又要手动的?)
xPSR寄存器的位24又为什么必须为1?
(7)手动加载的R11~R4CPU寄存器参数
(8)return返回栈顶指针,赋值给p_sp,然后p_sp保存在TCB结构体的第一个成员StkPtr。
stk_size任务堆栈的大小保存在TCB第二个成员StkSize

//在函数OSTaskStkInit中
return (p_stk);
//在函数OSTaskCreate中
p_sp = OSTaskStkInit( p_task, p_arg, p_stk_base,stk_size);
p_tcb->StkPtr = p_sp;
p_tcb->StkSize = stk_size;

--------------------------------------分割线------------------------------------------------------
1.走在这一步,我又去查阅资料,参考这篇博客ARM Cortex -M 体系结构————————ARM微控制器与嵌入式系统
发现这来自于Joseph Yiu ,宋岩 译著《Cortex M3权威指南》,哈哈,差点忘了这本经典的工具书!如本书所述:

(1)R0-R7 也被称为低组寄存器。所有指令都能访问它们。它们的字长全是 32 位,复位后的初始值是不可预料的
(2)R8-R12 也被称为高组寄存器。这是因为只有很少的 16 位 Thumb 指令能访问它们,32 位的thumb-2 指令则不受限制。它们也是 32 位字长,且复位后的初始值是不可预料的。

对xPSR寄存器的解答:
这个xPSR中的x代表“任意不定状态”,可分为三个子状态寄存器APSR,IPSR,EPSR。

xPSR寄存器的位24又为什么必须为1?
—>Thumb状态,总是1,清楚此位会引起错误异常。
下面一张图我没有在《Cortex M3权威指南》,为什么会没有呢?而是在一篇博客找到答案:《嵌入式 - 嵌入式大杂烩》深入理解ARM寄存器

--------------------------------------分割线------------------------------------------------------

uC/OS-III 内核实现与应用开发实战学习(一)相关推荐

  1. “物联网开发实战”学习笔记-(四)智能音箱制作和语音控制

    "物联网开发实战"学习笔记-(四)智能音箱制作和语音控制 这次来造一个属于自己的智能音箱,这里详细介绍了智能音箱的语音控制的实现. 智能音箱的技术架构 智能音箱主要涉及拾音.前端信 ...

  2. “物联网开发实战”学习笔记-(二)手机控制智能电灯

    "物联网开发实战"学习笔记-(二)手机控制智能电灯 如果搭建好硬件平台后,这一次我们的任务主要是调试好智能电灯,并且连接到腾讯云的物联网平台. 腾讯云物联网平台 腾讯物联网平台的优 ...

  3. Oracle开发实战学习

    Oracle开发实战学习 文章目录 Oracle开发实战学习 第1章 Oracle关系数据库 作业: 第2章Oracle数据库的体系结构 2.1 Oracle的物理存储结构 2.2 Oracle的逻辑 ...

  4. “物联网开发实战”学习笔记-(五)根据土壤湿度、环境温湿度和光照强度自动浇花

    "物联网开发实战"学习笔记-(五)根据土壤湿度.环境温湿度和光照强度自动浇花 研究场景需求 自动浇花这个场景,很明显是为了自动控制水泵,及时给植物补充水分.同时用户的目的并不只是浇 ...

  5. 唐金州的Vue开发实战学习笔记(基础篇)

    Vue开发实战学习笔记 简易的Vue程序 组件 事件 插槽 单文件组件 双向绑定 虚拟DOM与key属性 组件更新 状态data与属性props vue的响应式更新 计算属性和侦听器 计算属性 com ...

  6. 唐金州的Vue开发实战学习笔记(生态篇)

    Vue开发实战学习笔记 Vuex Why Vuex How Vuex Vuex的核心概念和底层原理 Vuex的最佳实践 Vue Router Why Vue Router 路由类型及底层原理 Nuxt ...

  7. UC/OS III操作系统学习笔记

    UCOS操作系统学习笔记 1.UCOSIII任务 1.1任务管理 1.2 任务创建和删除.挂起和恢复 1.3 系统内部任务 2.UCOSIII中断和时间管理 2.1 中断管理 2.2 时间管理 3.U ...

  8. linux底层驱动内核,Linux底层驱动开发需要学习哪些内容

    Linux底层驱动开发需要学习哪些内容想必这是很多学习Linux的朋友十分头疼的问题,今天就让我来告诉大家我们到底该学习哪些内容呢? 1. 要会一些硬件知识,比如Arm接口编程 2. 学会写简单的ma ...

  9. python3网络爬虫开发实战学习笔记(二)------python3 XPATH爬 猫眼电影排名

    我最近在看崔庆才老师的<python3 网络爬虫开发实战>觉得挺不错的,上面还有一个 用正则表达式爬取猫眼电影的电影排行榜 我练了一下,感觉不会很难,后来学到了xpath,就想用xpath ...

最新文章

  1. 10个linux awk文本处理经典案例,关于AWK的10个经典案例
  2. jenkins运行日志时间与linux,持续集成之Jenkins结合脚本实现代码自动化部署及一键回滚至上一版本...
  3. WCF学习笔记之可靠会话
  4. dbcp连接mysql,8小时会自动断开连接
  5. 反序列化 还是记一下吧
  6. 软件工程测试旅游管理系统,旅游管理系统的设计与实现
  7. python flask和django_真正搞明白Python中Django和Flask框架的区别
  8. 【转】用C#获取浏览文件夹对话框
  9. SQL注入 时间延时注入语句
  10. android英文菜单,安卓recovery菜单中英文对照
  11. Centos Piranha安装过程
  12. c语言cout函数,c++中cin与cout 详解
  13. Proxifier代理指定程序到fiddler
  14. WordPress批量修改数据库内文章内容文字关键字标题
  15. linux重启关机命令
  16. android smallestWidth 限定符屏幕适配方案dimens.xml
  17. hue数据导出到hdfs_如何将智能灯泡迁移到新的Philips Hue Bridge
  18. text-decoration
  19. 云仓系统或者一件代发系统
  20. 学术交流站点–小木虫论坛

热门文章

  1. 第一,永远不要跟银行借钱;第二,永远不要向民间借贷;第三,量力而行(转)...
  2. 【速度最快的浏览器】Chrome for Mac V75.0
  3. EV代码签名证书对可执行文件进行签名
  4. java软件开发面试常见问题,java面试技巧和注意事项
  5. 变焦和对焦_变焦疲劳和远程工作
  6. matlab函数randi,Matlab之rand(), randn(), randi()函数的使用方法
  7. 挂载虚拟机映像文件img
  8. HDU-1728---逃离迷宫(BFS)
  9. 基于Qt开发的网络诊断工具
  10. android开发方向知乎,Android开发者必看:知乎开源的图片选择库