背景

通过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系统?:只需要将源码的UCOSIII\uCOS-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.hcpu_a.asmcpu_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 ..\uCosIII\uC-CPU\ARM-Cortex-M4\RealView
..\uCosIII\uC-CPU
..\uCosIII\uC-LIB
..\uCosIII\uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView
..\uCosIII\uCOS-III\Source
..\uCosIII\uCOS_BSP
..\uCosIII\uCOS_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...
.\Objects\Project_StdPeriph_F429.axf: Error: L6218E: Undefined symbol BSP_IntInit (referred from bsp.o).
.\Objects\Project_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.
".\Objects\Project_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

进入 uCosIII\uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView

替换 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...
.\Objects\Project_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.
".\Objects\Project_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...
.\Objects\Project_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.
".\Objects\Project_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 的改动

主要是值的改动

移植 uCos-III 3.03 到 STM32F429 上的更多相关文章

  1. zju(11)在IAR中移植ucos到msp430

    准备材料 1.在TI官网上下载430的固件库,我用的是msp430f5528的板子,下载的是F5xx_F6xx_Core_Lib 地址http://www.ti.com/tool/msp-exp430 ...

  2. 研究了3天,终于将 Shader 移植到 Cocos Creator 2.2.0 上了!

    预览 扫光特效-Fluxay2 马赛克像素特效-Mosaic 过渡效果-Transfer Shawn 花了3天时间,研究了Cocos Creator 2.2.0 的 Effect 语法,终于在1024 ...

  3. LwIP移植uCos+stm32f407

    LwIP同操作系统一起工作的时候模型如下: 1.TCP/IP协议栈和应用程序以分离的任务运行 2.应用同协议栈沟通是通过API函数调用(API函数调用事实上就是通过OS自带的进程间通信机制,由应用程序 ...

  4. UCOS III的时间片轮转调度的一个问题

    1. 如果当前一个任务A在时间片未到来之前,主动放弃剩下的时间片,进入下一个任务B,那么下一个任务的的执行时间是多久? 书上说,是重置时间片,也就是说任务B也运行一个完整的时间片.

  5. 推荐一个快速了解移植uboot以及linux到新板子上的ppt教程

    链接地址在此: https://elinux.org/images/2/2a/Schulz-how-to-support-new-board-u-boot-linux.pdf

  6. ucos III中任务之间的数据通信和任务划分

    1. 如果将关系密切(比如两个任务之间需要经常收发数据)的若干功能分别用不同的任务来实现,则需要进行大量的任务之间数据通信和同步通信,这系统来说是一个很大的负担.因此应该将关系密切的若干功能组合成一个 ...

  7. 关于STM32F103系列从大容量向中容量移植的若干问题

    一.把STM32F103大容量移植到STM32F103C8T6上的步骤: 1.换启动文件 startup_stm32f10x_cl.s           ——互联型的器件 包括:STM32F105x ...

  8. 二维码开源库ZBar-MDK STM32F429移植

    前两篇文章已经实现ZBar在Windows平台下的编译和使用,本文将介绍如何把ZBar移植到STM32F429,IDE使用MDK. 1. MDK工程设置 (1)不勾选Use MicroLIB ,使用I ...

  9. UCOS移植心得(

    移植UCOS之前,你首先应该做好三件事: 1.弄懂UCOS,这是谁都知道的哦 ^_^ 2. 弄懂你想要移植到的硬件平台 3. 清楚你使用的编译器是如何处理函数的局部变量和怎么样处理函数间的参数传递 这 ...

  10. 树莓派3b在rt-thread上移植LittlevGL

    树莓派3b在rt-thread上移植LittlevGL 目录 树莓派3b在rt-thread上移植LittlevGL 1.本文概述 2.资源准备 3.上手体验 4.rt-thread与lvgl进行无缝 ...

随机推荐

  1. [Java]线程生命周期与线程通信

    [版权声明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18162522 出自[进步*于辰的博客] 线程生命周期与 ...

  2. 手把手搭建WebSocket多人在线聊天室(SpringBoot+WebSocket)

    前言 本文中搭建了一个简易的多人聊天室,使用了WebSocket的基础特性. 源代码来自老外的一篇好文: https://www.callicoder.com/spring-boot-websocke ...

  3. Rust中的并发性:Sync 和 Send Traits

    在并发的世界中,最常见的并发安全问题就是数据竞争,也就是两个线程同时对一个变量进行读写操作.但当你在 Safe Rust 中写出有数据竞争的代码时,编译器会直接拒绝编译.那么它是靠什么魔法做到的呢? ...

  4. 【GUI软件】小红书指定博主批量采集笔记,支持多博主同时采集!

    目录 一.背景介绍 1.1 爬取目标 1.2 演示视频 1.3 软件说明 二.代码讲解 2.1 爬虫采集模块 2.2 软件界面模块 2.3 日志模块 三.获取源码及软件 一.背景介绍 1.1 爬取目标 ...

  5. MacOS M1芯片openmp库出现mach-o file, but is an incompatible architecture (have ‘arm64‘, need ‘x86_64‘问题解决

    目录 1. 问题描述 2. 问题出现原因 3. 解决方案 编译安装 使用Homebrew安装 Reference 1. 问题描述 报错如下所示: ImportError: dlopen(/Users/ ...

  6. gin-vue-admin开发教程 02 了解项目目录结构和代码执行的流程

    学习目标: 介绍项目 项目目录(2.0) 后台的启动过程 前台的启动过程 前后台交互的流程 视频学习地址: https://www.bilibili.com/video/BV1Rz4y1X7Zr (海 ...

  7. 一文搞懂 ARM 64 系列: ADC

    1 指令语法 adc <Xd>, <Xn>, <Xm> 2 指令语义 adc就是带「进位」加法,指令中的c就是英文carry. 整个指令等价于: (Xd, _) = ...

  8. vueJs开发音乐播放器第二篇(点击歌单跳出详情页)

    继上一篇开发音乐播放器歌单列表页 (1.使用router定义跳转链接,2. 使用axios得到音乐第三方数据,并渲染到页面上,3.组件之间传值(props)) 1.接下来使用了vue-router路由 ...

  9. 纯JavaScript实现“返回顶部”和“评分”,“分享”等小功能

    1.返回顶部功能的实现 <!DOCTYPE html> <html> <head> <title>Back to Top</title> & ...

  10. IPv6 — 实践

    目录 文章目录 目录 前文列表 常用命令 开启/关闭 IPv6 支持 在 CentOS7 上配置 IPv6 地址 自动获取链路本地地址 配置静态全球唯一地址 配置临时 IPv6 地址 添加 IPv6 ...