背景
通過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.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
..\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 的改動
主要是值的改動