背景
通过STM32 的学习,我们可以往更深层次的地方走,尝试系统上的一些开发。
STM32: F429(StdPeriph)
uCos-III : v3.04 + 3.03
有关说明:
在移植 3.04 版本 UCOSIII 的时候遇到了这样一个问题:一旦调用 OSStatTaskCPUUsageInit()函数就会进入 hardfault,(如果这时选择-O1 或者-O2 优化的话就没有问题),不知是 KEIL 问题还是 UCOSIII 3.04 版本的问题。
另外,目前 UCOSIII 的资料基本都是基于 UCOSIII 3.03 版本的。
如果一定要使用 UCOSIII 3.04 的话,使用 KEIL 时一定要 选择-O1 或者-O2 优化。
其实 uCos-III 3.04 与 3.03 的移植之间就差一步,因为 uCos-III 3.04 中源码有STM32F4的BSP,而 uCos-III 3.03 中没有;
为了达到STM32F4移植3.03的目的,可以这么做:
1)移植uCos-III 3.04 中的有关文件
2)再将uCos-III 3.03 中的有关的文件替换进去即可。
如何移植不同版本的uCos系统?:只需要将源码的UCOSIIIuCOS-III下的Source文件夹,直接替换掉移植好后的Source,就可以了。
uCos 介绍
什么是 uC/OS-III? uC/OS-III(Micro C OS Three 微型的 C语言编写的操作系统第 3 版)是一个可升级的,可固化的,基于优先级的实时内核。它对任务的个数无限制。uC/OS-III 是一个第 3 代的系统内核,支持现代的实时内核所期待的大部分功能。例如资源管理,同步,任务间的通信等等。然而,uC/OS-III 提供的特色功能在其它的实时内核中是找不到的,比如说完备的运行时间测量性能,直接地发送信号或者消息到任务,任务可以同时等待多个内核对象等。
为什么命名一个新的版本? uC/OS 系列,第一代产生于 1992。经过了多年的使用和上千人的反馈,已经产生了很多的进化版本。 uC/OS-III 是这些反馈和经验的总结。在 uC/OS-II 中很少使用的功能已经被删除或者被更新,添加了更高效的功能和服务。其中最有用的功能应该是时间片轮转法(round robin),这个是 uC/OS-II 中不支持的,但是现在已经是 uC/OS-III 的一个功能了。 uC/OS-III 会提供新的功能以更好地适应新出现的处理器。特别的,uC/OS-III 被设计用于 32 位处理器,但是它也能在 16 位或 8 位处理器中很好地工作。
uC/OS-III 的目标 uC/OS-III 最主要的目标是提供一流的实时内核以适应更新很快的嵌入式产品。使用像 uC/OS-III 那样具有雄厚的基础和稳定的框架的商业实时内核,能够帮助设计师们处理日益复杂的嵌入式设计。
各目录以及关键文件说明
# Schips @ SCHIPS-L in UCOSIII 3.04 [9:55:00]
$ tree -d
.
└── Micrium
└── Software
├── EvalBoards
├── uC-CPU
├── uC-LIB
└── uCOS-III
下面我们分别对 Software
下的不同目录进行说明
EvalBoards
在默认情况下,uCos已经在EvalBoards
目录为我们准备好了STM32F429II-SK
移植。
uC-CPU
这个文件里面是与 CPU 相关的代码
# Schips @ SCHIPS-L in UCOSIII 3.04/Micrium/Software/uC-CPU [10:09:39]
.
├── ARM-Cortex-M4
│ ├── GNU
│ │ ├── cpu.h
│ │ ├── cpu_a.s
│ │ └── cpu_c.c
│ ├── IAR
│ │ ├── cpu.h
│ │ ├── cpu_a.asm
│ │ └── cpu_c.c
│ └── RealView
│ ├── cpu.h
│ ├── cpu_a.asm
│ └── cpu_c.c
├── cpu_core.c
├── cpu_core.h
└── cpu_def.h
cpu_core.c
该文件包含了适用于所有 CPU 架构的 C 代码。该文件包含了用来测量中断关闭事件 的函数(中断关闭和打开分别由 CPU_CRITICAL_ENTER()和 CPU_CRITICAL_EXIT()两个宏实现),还包含一个可模仿前导码零计算的函数(以防止 CPU 不提供这样的指令),以及一些其他的 函数。
cpu_core.h
包含 cpu_core.c 中函数的原型声明,以及用来测量中断关闭时间变量的定义。
cpu_def.h
包含 uC/CPU 模块使用的各种#define 常量。
详细大家也注意到目录(GNU、IAR、RealView)中都有 cpu.h
、cpu_a.asm
和 cpu_c.c
这三个文件。GNU、IAR、RealView
对应了不同的编译器,这是为了根据不同的编译平台有不同的处理。我们使用的是 KEIL,所以我们在移植时选择 RealView
中的文件。
cpu.h
包含了一些类型的定义,使 UCOSIII 和其他模块可与 CPU 架构和编译器字宽度无关。 在该文件中用户能够找到 CPU_INT16U、CPU_INT32U、CPU_FP32 等数据类型的定义。该文 件还指定了 CPU 使用的是大端模式还是小端模式,定义了 UCOSIII 使用的 CPU_STK 数据 类型,定义了 CPU_CRITICAL_ENTER()和 CPU_CRITICAL_EXTI(),还包括一些与 CPU 架构相关 的函数的声明。
cpu_a.asm
该文件包含了一些用汇编语言编写的函数,可用来开中断和关中断,计算前导零(如果 CPU 支持这条指令),以及其他一些只能用汇编语言编写的与 CPU 相关的函数,这个文件中 的函数可以从 C 代码中调用。
cpu_c.c
包含了一些基于特定 CPU 架构但为了可移植而用 C 语言编写的函数 C 代码。作为一个普通原则,除非汇编语言能显著提高性能,否则尽量用 C 语言编写函数。
uC-LIB
uC-LIB 是由一些可移植并且与编译器无关的函数组成,UCOS III 不使用 uC-LIB 中的函 数,但是 UCOS-III 和 uC-CPU 假定 lib_def.h 是存在的。
# Schips @ SCHIPS-L in UCOSIII 3.04/Micrium/Software/uC-LIB [10:16:04]
$ tree
.
├── lib_ascii.c
├── lib_ascii.h
├── lib_def.h
├── lib_math.c
├── lib_math.h
├── lib_mem.c
├── lib_mem.h
├── lib_str.c
├── lib_str.h
└── Ports
└── ARM-Cortex-M4
├── GNU
│ └── lib_mem_a.s
├── IAR
│ └── lib_mem_a.asm
└── RealView
└── lib_mem_a.asm
lib_ascii.h 和 lib_ascii.c
提供 ASCII_ToLower()、ASCII_ToUpper()、ASCII_IsAlpha()和 ASCII_IsDig()等函数,它们可 以分别替代标准库函数 tolower()、toupper()、isalpha()和 isdigit()等。
lib_def.h
定义了许多常量,如 RTUE/FALSE、YES/NO、ENABLE/DISABLE,以及各种进制的常量。 但是,该文件中所有#define 常量都以 DEF_打头,所以上述常量的名字实际上为 DEF_TRUE/DEF_FALSE、DEF_YES/DEF_NO、DEF_ENABLE/DEF_DISABLE 等。该文件还为常用数 学计算定义了宏。
lib_math.h 和 lib_math.c
包含了 Math_Rand()、Math_SetRand()等函数的源代码,可用来替代标准库函数 rand()、
srand()。
lib_mem.c 和 lib_mem.h
包含了 Mem_Clr()、Mem_Set()、Mem_Copy()和 Mem_Cmp()等函数的源代码,可用来 替代标准库函数 memclr()、memset()、memcpy()和 memcmp()等。
lib_str.c 和 lib_str.h
包含了 Str_Lenr()、Str_Copy()和 Str_Cmp()等函数的源代码,可用于替代标准库函数 srtlen()、strcpy()和 strcmp()等。
lib_mem_a.asm (Ports下面)
包含了 lib_mem.c 函数的汇编优化版。
uCOS-III
这个文件夹中有两个文件 Ports 和 Sourec,Ports 文件为与 CPU 平台有关的文件, Source 文件夹里面为 UCOSIII 3.04 的源码
UCOSIII 3.04 和 UCOSIII 3.03 源码的文件都是一样的,不同的是各个文件里面的有些函 数做了修改
# Schips @ SCHIPS-L in UCOSIII 3.04/Micrium/Software/uCOS-III [10:24:31]
$ tree
.
├── Ports
│ └── ARM-Cortex-M4
│ └── Generic
│ ├── GNU
│ │ ├── os_cpu.h
│ │ ├── os_cpu_a.S
│ │ └── os_cpu_c.c
│ ├── IAR
│ │ ├── os_cpu.h
│ │ ├── os_cpu_a.asm
│ │ └── os_cpu_c.c
│ └── RealView
│ ├── os_cpu.h
│ ├── os_cpu_a.asm
│ └── os_cpu_c.c
└── Source
├── os.h
├── os_cfg_app.c
├── os_core.c
├── os_dbg.c
├── os_flag.c
├── os_int.c
├── os_mem.c
├── os_msg.c
├── os_mutex.c
├── os_pend_multi.c
├── os_prio.c
├── os_q.c
├── os_sem.c
├── os_stat.c
├── os_task.c
├── os_tick.c
├── os_time.c
├── os_tmr.c
├── os_type.h
└── os_var.c
UCOSIII 源码各个文件内容:
- os.h : uCos-III 主要头文件,声明了常量、宏、全局变量、函数原型等
- os_Cfs_app.c : 根据 os_cfg_app.h 中的宏定义声明变量和数组
- os_core.c : uCos-III 内核功能模块
- os_dbg.c : 内核调试或uC/Probe 使用的常量的声明
- os_flag.c : 事件标志的管理代码
- os_int.c : 中断处理任务的代码
- os_mem.c : uCos-III固定大小的储存分区管理代码
- os_msg.c : 消息处理代码
- os_mutex.c : 互斥信号量的管理代码
- os_pend_multi.c : 允许任务同时等待多个信号量或多个消息队列的代码
- os_prio.c : 位映射表的管理代码(用来追踪已经就绪的任务)
- os_q.c : 包含消息队列的管理代码
- os_sem.c : 信号量的管理代码
- os_stat.c : 统计任务的代码
- os_task.c : 任务的管理代码
- os_tick.c : 可管理正在延迟和超时等待的任务的代码
- os_time.c : 时间调度任务的延迟管理代码
- os_tmr.c : 软件定时器的管理代码
- os_type.h : uCos-III的数据类型的声明
- os_var.c : 包含uCos-III全局变量
uCosIII 文件移植
假设项目名称为:Project_StdPeriph_F429_uCosIII
,且 目录树如下:
关于构建 STM32 标准库工程可以参考:STM32学习笔记:创建工程模板
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII
$ tree -d
.
├── CMSIS
├── Driver
├── Library
│ ├── inc
│ └── src
├── Project
│ ├── Listings
│ └── Objects
└── User
在项目中新建目录:uCosIII
,并将uC-CPU、uC-LIB 和 uCOS-III
目录复制到uCosIII
中
拷贝 EvalBoards 下的文件
1)在uCosIII
文件中新建两个目录:uCOS_BSP 和 uCOS_CONFIG
。
2)拷贝文件到 uCOS_CONFIG
路径:UCOSIII 3.04/Micrium/Software/EvalBoards/ST/STM32F429II-SK/uCOS-III
对应文件: app_cfg.h, cpu_cfg.h, lib_cfg.h, os_app_hooks.c, os_app_hooks.h, os_cfg.h, os_cfg_app.h
3)拷贝文件到 uCOS_BSP
路径:UCOSIII 3.04/Micrium/Software/EvalBoards/ST/STM32F429II-SK/BSP
对应文件:bsp.c, bsp.h
最终效果
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII
$ tree # 由于篇幅限制,这里省略了 STM32 标准库的文件
.
├── CMSIS
├── Driver
├── Library
│ ├── inc
│ └── src
├── Project
│ ├── Listings
│ └── Objects
├── uCosIII
│ ├── uC-CPU
│ │ ├── ARM-Cortex-M4
│ │ │ └── RealView
│ │ │ ├── cpu.h
│ │ │ ├── cpu_a.asm
│ │ │ └── cpu_c.c
│ │ ├── cpu_core.c
│ │ ├── cpu_core.h
│ │ └── cpu_def.h
│ ├── uC-LIB
│ │ ├── lib_ascii.c
│ │ ├── lib_ascii.h
│ │ ├── lib_def.h
│ │ ├── lib_math.c
│ │ ├── lib_math.h
│ │ ├── lib_mem.c
│ │ ├── lib_mem.h
│ │ ├── lib_str.c
│ │ ├── lib_str.h
│ │ └── Ports
│ │ └── ARM-Cortex-M4
│ │ ├── GNU
│ │ │ └── lib_mem_a.s
│ │ ├── IAR
│ │ │ └── lib_mem_a.asm
│ │ └── RealView
│ │ └── lib_mem_a.asm
│ ├── uCOS_BSP
│ │ ├── bsp.c
│ │ └── bsp.h
│ ├── uCOS_CONFIG
│ │ ├── app_cfg.h
│ │ ├── cpu_cfg.h
│ │ ├── includes.h
│ │ ├── lib_cfg.h
│ │ ├── os_app_hooks.c
│ │ ├── os_app_hooks.h
│ │ ├── os_cfg.h
│ │ └── os_cfg_app.h
│ └── uCOS-III
│ ├── Ports
│ │ └── ARM-Cortex-M4
│ │ └── Generic
│ │ └── RealView
│ │ ├── os_cpu.h
│ │ ├── os_cpu_a.asm
│ │ └── os_cpu_c.c
│ └── Source
│ ├── os.h
│ ├── os_cfg_app.c
│ ├── os_core.c
│ ├── os_dbg.c
│ ├── os_flag.c
│ ├── os_int.c
│ ├── os_mem.c
│ ├── os_msg.c
│ ├── os_mutex.c
│ ├── os_pend_multi.c
│ ├── os_prio.c
│ ├── os_q.c
│ ├── os_sem.c
│ ├── os_stat.c
│ ├── os_task.c
│ ├── os_tick.c
│ ├── os_time.c
│ ├── os_tmr.c
│ ├── os_type.h
│ └── os_var.c
└── User
├── main.c
└── main.h
在Keil 中 新建 分组
1)添加 工程目录下 uCosIII 目录中的 uC_CPU, uC_LIB, uCOS_BSP, uCOS_CONFIG, uCOS_III
到 分组 中。
2)添加对应的.asm,.c
文件到 组中
uC_CPU: 添加 下面的 .c 与 .asm
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII/uCosIII/uC-CPU
$ tree
.
├── ARM-Cortex-M4
│ └── RealView
│ ├── cpu_a.asm
│ └── cpu_c.c
└── cpu_core.c
uC_LIB: 添加 下面的 .c 与 .asm
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII/uCosIII/uC-LIB
$ tree
.
├── lib_ascii.c
├── lib_math.c
├── lib_mem.c
├── lib_str.c
└── Ports
└── ARM-Cortex-M4
└── RealView
└── lib_mem_a.asm
uCOS_BSP:添加下面的 .c
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII/uCosIII/uCOS_BSP
$ tree
.
└── bsp.c
uCOS_CONFIG:添加下面的 .c
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII/uCosIII/uCOS_CONFIG
$ tree
.
└── os_app_hooks.c
uCOS_III:添加下面的 .c
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII/uCosIII/uCOS-III
$ tree | grep -v ".h"
.
├── Ports
│ └── ARM-Cortex-M4
│ └── Generic
│ └── RealView
│ ├── os_cpu_a.asm
│ └── os_cpu_c.c
└── Source
├── os_cfg_app.c
├── os_core.c
├── os_dbg.c
├── os_flag.c
├── os_int.c
├── os_mem.c
├── os_msg.c
├── os_mutex.c
├── os_pend_multi.c
├── os_prio.c
├── os_q.c
├── os_sem.c
├── os_stat.c
├── os_task.c
├── os_tick.c
├── os_time.c
├── os_tmr.c
└── os_var.c
3)最终效果
Keil 添加头文件
将 ucos有关组 中的 .h 的所在路径添加到 头文件路径 中
# Schips @ SCHIPS-L in Project_StdPeriph_F429_uCosIII/uCosIII
$ find .. | grep ".h" | grep -v "GNU" | grep -v "IAR" | xargs -i dirname {} | uniq
..uCosIIIuC-CPUARM-Cortex-M4RealView
..uCosIIIuC-CPU
..uCosIIIuC-LIB
..uCosIIIuCOS-IIIPortsARM-Cortex-M4GenericRealView
..uCosIIIuCOS-IIISource
..uCosIIIuCOS_BSP
..uCosIIIuCOS_CONFIG
uCos-III 代码修改
编译后,一般会出现这样的错误:提示我们在 bsp.c 文 件中 BSP_IntInit()和 BSP_PeriphEn()这两个函数未定义,这里我们先不管这两个错误。
compiling os_time.c...
compiling os_tmr.c...
compiling os_var.c...
assembling os_cpu_a.asm...
compiling os_cpu_c.c...
linking...
.ObjectsProject_StdPeriph_F429.axf: Error: L6218E: Undefined symbol BSP_IntInit (referred from bsp.o).
.ObjectsProject_StdPeriph_F429.axf: Error: L6218E: Undefined symbol BSP_PeriphEn (referred from bsp.o).
Not enough information to list image symbols.
Finished: 1 information, 0 warning and 2 error messages.
".ObjectsProject_StdPeriph_F429.axf" - 2 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed: 00:00:38
下载修改以后的代码:uCos-III需要修改的文件.zip,里面包括了一个基础的uCosIII项目以外还有为了方便调试而调好的串口打印程序。
为了确保排除所有的问题,代码包中除了 uCos-III 以外的其他文件也加进项目中。
# Schips @ SCHIPS-L in uCos-III需要修改的文件
$ tree
.
├── bsp.c
├── bsp.h
├── main.c
├── os_cfg_app.h
├── os_cpu_a.asm
├── os_cpu_c.c
└── SYSTEM
├── delay
│ ├── delay.c
│ └── delay.h
├── sys
│ ├── sys.c
│ └── sys.h
└── usart
├── usart.c
└── usart.h
uCOS_BSP
替换 bsp.c和bsp.h文件,这里直接下载已经修改好的文件
修改 bsp.c 在修改之前,我们稍微讲解一下 Cortex-M3/M4 的跟踪组件。
在 bsp.c 文件里面有很多的代码,我们只需要其中的很少一部分关于 DWT 的代码,因此我们要做相应的修改。
在 CM3/CM4 中有 3 种跟踪源:ETM、ITM 和 DWT,要想使用 ETM、ITM 和 DWT 的 话,要将 DEMCR(* 0XE000EDFC) 寄存器的 TRCENA 位(bit24)置 1。
感兴趣的朋友可以自行查阅:《Cortex-M3 与 M4 权威指南》(英文名为《The DefinitiveGuide to ARM Cortex-M3 and Cortex-M4 Processors, 3rd Edition》)的 501 页有详细的讲解。
在 DWT 组件中有一个 CYCCNT 寄存器,这个寄存器用来对时钟周期计数,我们可以使用这个寄存器来测量执行某个任务所花费的时间。
DWT 组件有多个寄存器,我们这里只使用 DWT 的控制寄存器 CTRL(
0XE0001000
)、CYCCNT 寄存器(0XE0001004
)。如果我们要使用时 钟计数功能需要将 CTRL 寄存器的 bit0 置 1。
uCOS_CONFIG
修改os_cfg_app.h文件,系统裁剪和内核有关的,这里直接下载已经修改好的文件
uCOS-III
进入 uCosIIIuCOS-IIIPortsARM-Cortex-M4GenericRealView
替换 os_cpu_a.asm汇编文件,这里直接下载已经修改好的文件
替换os_cpu_c.c文件,这个主要是修改堆栈函数,这里直接下载已经修改好的文件
编译
编译以后,发项提示 PendSV_Handler(负责上下文切换) 在 os_cpu_a.o 与 stm32f4xx_it.o
重复定义。
assembling os_cpu_a.asm...
compiling os_cpu_c.c...
linking...
.ObjectsProject_StdPeriph_F429.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by os_cpu_a.o and stm32f4xx_it.o).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 1 error messages.
".ObjectsProject_StdPeriph_F429.axf" - 1 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed: 00:00:02
找到 STM32F4xx_it.c
中的PendSV_Handler
,屏蔽掉即可;或者添加 __weak 关键字
同理,由于delay.c中实现了SysTick_Handler ,所以要把 stm32f4xx_it.c 中的 SysTick_Handler 屏蔽掉。
Build target 'f429'
compiling usart.c...
compiling sys.c...
compiling delay.c...
linking...
.ObjectsProject_StdPeriph_F429.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by stm32f4xx_it.o and delay.o).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 1 error messages.
".ObjectsProject_StdPeriph_F429.axf" - 1 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed: 00:00:03
附录:参考的修改过程
本文档基于 uCOS-III 3.04 与 最终结果之间的差异。
os_cpu_a.asm 修改的地方:
1)函数 OS_CPU_PendSVHandler ,改名为 PendSV_Handler。
2)函数 OS_CPU_PendSVHandler_nosave 改名为 PendSVHandler_nosave
2)NVIC_PENDSV_PRI EQU 0xFF 改为 NVIC_PENDSV_PRI EQU 0xFFFF
3)PendSV_Handler中
PendSV_Handler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, PendSVHandler_nosave ; Skip register save the first time
;Is the task using the FPU context? If so, push high vfp registers.
TST R14, #0X10
IT EQ
VSTMDBEQ R0!,{S16-S31}
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] ; R0 is SP of process being switched out
; At this point, entire context of process has been saved
4)PendSVHandler_nosave 中
PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20
;Is the task using the FPU context? If so, push high vfp registers.
TST R14, #0x10
IT EQ
VLDMIAEQ R0!, {S16-S31}
MSR PSP, R0 ; Load PSP with new process SP
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
CPSIE I
BX LR ; Exception return will restore remaining context
END
os_cpu_.c 改动的地方
1)引入了一个新的头文件:#include "includes.h"
2)OSTaskSwHook 函数中,屏蔽了 此段
#if (OS_CPU_ARM_FP_EN == DEF_ENABLED)
// if ((OSTCBCurPtr->Opt & OS_OPT_TASK_SAVE_FP) != (OS_OPT)0) {
// OS_CPU_FP_Reg_Push(OSTCBCurPtr->StkPtr);
// }
// if ((OSTCBHighRdyPtr->Opt & OS_OPT_TASK_SAVE_FP) != (OS_OPT)0) {
// OS_CPU_FP_Reg_Pop(OSTCBHighRdyPtr->StkPtr);
// }
#endif
3)OSTaskStkInit,新的内容如下:
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)opt; /* Prevent compiler warning */
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
/* Align the stack to 8-bytes. */
p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8);
#if (__FPU_PRESENT==1)&&(__FPU_USED==1) /* Registers stacked as if auto-saved on exception */
*(--p_stk) = (CPU_STK)0x00000000u; //No Name Register
*(--p_stk) = (CPU_STK)0x00001000u; //FPSCR
*(--p_stk) = (CPU_STK)0x00000015u; //s15
*(--p_stk) = (CPU_STK)0x00000014u; //s14
*(--p_stk) = (CPU_STK)0x00000013u; //s13
*(--p_stk) = (CPU_STK)0x00000012u; //s12
*(--p_stk) = (CPU_STK)0x00000011u; //s11
*(--p_stk) = (CPU_STK)0x00000010u; //s10
*(--p_stk) = (CPU_STK)0x00000009u; //s9
*(--p_stk) = (CPU_STK)0x00000008u; //s8
*(--p_stk) = (CPU_STK)0x00000007u; //s7
*(--p_stk) = (CPU_STK)0x00000006u; //s6
*(--p_stk) = (CPU_STK)0x00000005u; //s5
*(--p_stk) = (CPU_STK)0x00000004u; //s4
*(--p_stk) = (CPU_STK)0x00000003u; //s3
*(--p_stk) = (CPU_STK)0x00000002u; //s2
*(--p_stk) = (CPU_STK)0x00000001u; //s1
*(--p_stk) = (CPU_STK)0x00000000u; //s0
#endif
*(--p_stk) = (CPU_STK)0x01000000u; /* xPSR */
*(--p_stk) = (CPU_STK)p_task; /* Entry Point */
*(--p_stk) = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
*(--p_stk) = (CPU_STK)0x12121212u; /* R12 */
*(--p_stk) = (CPU_STK)0x03030303u; /* R3 */
*(--p_stk) = (CPU_STK)0x02020202u; /* R2 */
*(--p_stk) = (CPU_STK)p_stk_limit; /* R1 */
*(--p_stk) = (CPU_STK)p_arg; /* R0 : argument */
#if (__FPU_PRESENT==1)&&(__FPU_USED==1)
*(--p_stk) = (CPU_STK)0x00000031u; //s31
*(--p_stk) = (CPU_STK)0x00000030u; //s30
*(--p_stk) = (CPU_STK)0x00000029u; //s29
*(--p_stk) = (CPU_STK)0x00000028u; //s28
*(--p_stk) = (CPU_STK)0x00000027u; //s27
*(--p_stk) = (CPU_STK)0x00000026u; //s26
*(--p_stk) = (CPU_STK)0x00000025u; //s25
*(--p_stk) = (CPU_STK)0x00000024u; //s24
*(--p_stk) = (CPU_STK)0x00000023u; //s23
*(--p_stk) = (CPU_STK)0x00000022u; //s22
*(--p_stk) = (CPU_STK)0x00000021u; //s21
*(--p_stk) = (CPU_STK)0x00000020u; //s20
*(--p_stk) = (CPU_STK)0x00000019u; //s19
*(--p_stk) = (CPU_STK)0x00000018u; //s18
*(--p_stk) = (CPU_STK)0x00000017u; //s17
*(--p_stk) = (CPU_STK)0x00000016u; //s16
#endif
/* Remaining registers saved on process stack */
*(--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; /* R4 */
return (p_stk);
}
bsp.h 修改的地方
删除了所有的函数声明。
bsp.c 修改的地方
主要是在于头部的改动。
1)删除了关于LED有关字段的宏。
2)宏BSP_REG_DBGMCU_CR 与 宏BSP_BIT_DEM_CR_TRCENA 之间的内容全部删除
3)从 宏BSP_BIT_DWT_CR_CYCCNTENA 开始的下面 与 BSP_Init 的声明与实现函数之间的所有内容全部删除
os_cfg_app.h 的改动
主要是值的改动