日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

STM32迷你板UCOSII系统移植

發布時間:2025/4/5 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32迷你板UCOSII系统移植 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫在前面:
所需要下載的UCOSII代碼鏈接:https://pan.baidu.com/s/1D_IyXhODEa5oVUdDv-GJrQ 提取碼:mte3

本文結構

      • 1.UCOSII簡介
      • 2.UCOSII移植具體步驟
      • 3.移植后的測試
      • 4.總結

1.UCOSII簡介

UCOSII 是一個可以基于ROM 運行的、可裁減的、搶占式、實時多任務內核,具有高度可
移植性,特別適合于微處理器和控制器,是和很多商業操作系統性能相當的實時操作系統
(RTOS)。

UCOSII 是專門為計算機的嵌入式應用設計的, 絕大部分代碼是用C 語言編寫的。CPU 硬
件相關部分是用匯編語言編寫的、總量約200 行的匯編語言部分被壓縮到最低限度,為的是便
于移植到任何一種其它的CPU 上。用戶只要有標準的ANSI 的C 交叉編譯器,有匯編器、連
接器等軟件工具,就可以將UCOSII 嵌人到開發的產品中。UCOSII 具有執行效率高、占用空間
小、實時性能優良和可擴展性強等特點, 最小內核可編譯至 2KB 。UCOSII 已經移植到了幾
乎所有知名的CPU 上。

UCOSII體系結構如圖所示

從上圖可以看出,UCOSII 的移植,我們只需要修改:os_cpu.h、os_cpu_a.asm 和os_cpu.c
等三個文件,其中:os_cpu.h,進行數據類型的定義,以及處理器相關代碼和幾個函數原
型;os_cpu_a.asm,是移植過程中需要匯編完成的一些函數,主要就是任務切換函數;os_cpu.c,定義一些用戶HOOK函數。

2.UCOSII移植具體步驟

新建基礎工程,這里以跑馬燈工程為例。
UCOSII移植具體步驟
1.在基礎工程下建立相應的文件夾:CONFIG,CORE,PORT
新建UCOSII文件夾

UCOSII文件夾下新建三個文件夾

2.向core文件夾添加UCOSII的源碼
在這個路徑下,找到UCOSII的源碼,也就是正點原子所帶的軟件資料:

6,軟件資料\2,UCOS學習資料\UCOSII資料\UCOS II源碼\Micrium\Software\uCOS-II\Source


將上面所有文件復制到CORE文件夾下,復制完的CORE文件夾下內容:

3.向CONFIG文件添加內容
此處的內容需要在該路徑下找到,同樣為正點原子所帶的資料

4,程序源碼\3,擴展例程\4,UCOS擴展例程\例1-1 UCOSII移植\UCOSII\CONFIG

添加好文件的CONFIG文件夾

4.向PORT文件夾下添加文件
文件路徑:

4,程序源碼\3,擴展例程\4,UCOS擴展例程\例1-1 UCOSII移植\UCOSII\PORT

添加完的PORT文件夾

5.將上述三個文件添加到工程中
打開工程
點擊Manage Project Items,新建三個分組:UCOSII-CORE,UCOSII-CONFIG,UCOSII-PORT


向分組中添加文件
UCOSII-CORE分組添加如下,但是需要刪除掉ucos_ii.c文件,否則會報錯。

刪除掉ucos_ii.c文件之后

UCOSII-PORT分組添加如下
只需要添加如下三個文件os_cpu.h和os_cpu_a.asm和os_cpu_c.c

UCOSII-CONFIG分組添加如下
添加includes.h和os_cfg.h文件

添加完成后會發現工程目錄下多了三個文件夾

但是我們發現UCOSII-CORE文件下都是加鎖的

解決辦法是:找到CORE文件夾,更改文件夾屬性:去掉只讀

回過頭來查看發現文件枷鎖已經去掉

下面需要將路徑包含進來
點擊魔法棒,選擇C/C++,找到include paths

點擊后面的添加按鈕

添加進來CORE,PORT,CONFIG文件

下面進行編譯,發現報錯

..\UCOSII\CORE\ucos_ii.h(44): error: #5: cannot open source input file "app_cfg.h": No such file or directory


雙擊該錯誤,進入到ucos_ii.h文件,找到該頭文件,由于我們不需要該頭文件,注釋掉即可


然后再次編譯
又發現另一個錯誤:PendSV_Handler 函數被重定義

..\OBJ\LED.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by os_cpu_a.o and stm32f10x_it.o).


解決辦法:刪除其中一個定義,由于匯編語言執行起來更快,所以刪除stm32f10x_it.c文件下PendSV_Handler 函數的定義,這里采用注釋掉的方法

先找到重定義的地方
os_cpu_a.asm這是一個匯編文件

在stm32f10x_it.c文件下

解決:注釋掉

再次編譯,發現沒有錯誤

6.修改sys.h文件

打開該文件:位于SYSTEM文件夾下,找到sys.c文件

右擊sys.h選擇Open document sys.h

將SYSTEM_SUPPORT_OS 改為1,表示支持UCOS系統
修改前:

修改后:


再次編譯,有報錯:還是重定義的問題,同樣的,這里我們還是注釋掉stm32f10x_it.c文件下SysTick_Handler 函數

..\OBJ\LED.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by delay.o and stm32f10x_it.o).


再次編譯發現沒有錯誤
這里需要注意的是os_cpu_c.h文件夾下的OSTaskStkInit函數,當移植時發現和下面的不一致時,需要替換成下面的OSTaskStkInit函數。

/* ********************************************************************************************************* * INITIALIZE A TASK'S STACK * * Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the * stack frame of the task being created. This function is highly processor specific. * * Arguments : task is a pointer to the task code * * p_arg is a pointer to a user supplied data area that will be passed to the task * when the task first executes. * * ptos is a pointer to the top of stack. It is assumed that 'ptos' points to * a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then * 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if * OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address * of the stack. * * opt specifies options that can be used to alter the behavior of OSTaskStkInit(). * (see uCOS_II.H for OS_TASK_OPT_xxx). * * Returns : Always returns the location of the new top-of-stack once the processor registers have * been placed on the stack in the proper order. * * Note(s) : 1) Interrupts are enabled when your task starts executing. * 2) All tasks run in Thread mode, using process stack. ********************************************************************************************************* */ OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt) {OS_STK *stk;(void)opt; /* 'opt' is not used, prevent warning */stk = ptos; /* Load stack pointer *//* Registers stacked as if auto-saved on exception */*(stk) = (INT32U)0x01000000L; /* xPSR */*(--stk) = (INT32U)task; /* Entry Point */*(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will cause fault if ever used)*/*(--stk) = (INT32U)0x12121212L; /* R12 */*(--stk) = (INT32U)0x03030303L; /* R3 */*(--stk) = (INT32U)0x02020202L; /* R2 */*(--stk) = (INT32U)0x01010101L; /* R1 */*(--stk) = (INT32U)p_arg; /* R0 : argument *//* Remaining registers saved on process stack */*(--stk) = (INT32U)0x11111111L; /* R11 */*(--stk) = (INT32U)0x10101010L; /* R10 */*(--stk) = (INT32U)0x09090909L; /* R9 */*(--stk) = (INT32U)0x08080808L; /* R8 */*(--stk) = (INT32U)0x07070707L; /* R7 */*(--stk) = (INT32U)0x06060606L; /* R6 */*(--stk) = (INT32U)0x05050505L; /* R5 */*(--stk) = (INT32U)0x04040404L; /* R4 */return (stk); }

3.移植后的測試

下面進行UCOSII操作系統的測試
將下面代碼復制到main.c中,替換掉原來的代碼

#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "includes.h"//START 任務 //設置任務優先級 #define START_TASK_PRIO 10 ///開始任務的優先級為最低 //設置任務堆棧大小 #define START_STK_SIZE 128 //任務任務堆棧 OS_STK START_TASK_STK[START_STK_SIZE]; //任務函數 void start_task(void *pdata);//LED0任務 //設置任務優先級 #define LED0_TASK_PRIO 7 //設置任務堆棧大小 #define LED0_STK_SIZE 64 //任務堆棧 OS_STK LED0_TASK_STK[LED0_STK_SIZE]; //任務函數 void led0_task(void *pdata);//LED1任務 //設置任務優先級 #define LED1_TASK_PRIO 6 //設置任務堆棧大小 #define LED1_STK_SIZE 64 //任務堆棧 OS_STK LED1_TASK_STK[LED1_STK_SIZE]; //任務函數 void led1_task(void *pdata);//浮點測試任務 #define FLOAT_TASK_PRIO 5 //設置任務堆棧大小 #define FLOAT_STK_SIZE 128 //任務堆棧 //如果任務中使用printf來打印浮點數據的話一點要8字節對齊 __align(8) OS_STK FLOAT_TASK_STK[FLOAT_STK_SIZE]; //任務函數 void float_task(void *pdata);int main(void) {delay_init(); //延時初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷分組配置uart_init(115200); //串口波特率設置LED_Init(); //LED初始化OSInit(); //UCOS初始化OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); //創建開始任務OSStart(); //開始任務 }//開始任務 void start_task(void *pdata) {OS_CPU_SR cpu_sr=0;pdata=pdata;OSStatInit(); //開啟統計任務OS_ENTER_CRITICAL(); //進入臨界區(關閉中斷)OSTaskCreate(led0_task,(void*)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);//創建LED0任務OSTaskCreate(led1_task,(void*)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);//創建LED1任務OSTaskCreate(float_task,(void*)0,(OS_STK*)&FLOAT_TASK_STK[FLOAT_STK_SIZE-1],FLOAT_TASK_PRIO);//創建浮點測試任務OSTaskSuspend(START_TASK_PRIO);//掛起開始任務OS_EXIT_CRITICAL(); //退出臨界區(開中斷) }//LED0任務 void led0_task(void *pdata) {while(1){LED0=0; delay_ms(80);LED0=1;delay_ms(100);} }//LED1任務 void led1_task(void *pdata) {while(1){LED1=0;delay_ms(300);LED1=1;delay_ms(300);} }//浮點測試任務 void float_task(void *pdata) {OS_CPU_SR cpu_sr=0;static float float_num=0.01;while(1){float_num+=0.01f;OS_ENTER_CRITICAL(); //進入臨界區(關閉中斷)printf("float_num的值為: %.4f\r\n",float_num); //串口打印結果OS_EXIT_CRITICAL(); //退出臨界區(開中斷)delay_ms(500);} }

編譯之后沒有錯誤,下載到開發板上

開發板出現led燈的交替閃爍,
再進行串口測試,也就是浮點測試:每個500ms進行+0.01的操作

至此,UCOSII操作系統移植成功。

4.總結

1) 移植UCOSII

要想UCOSII在STM32正常運行,首先是需要移植UCOSII,正點原子提供的SYSTEM文件夾里面的系統函數直接支持UCOSII,只需要在sys.h文件里面將:SYSTEM_SUPPORT_UCOS宏定義改為1,即可通過delay_init函數初始化UCOSII的系統時鐘節拍,為UCOSII提供時鐘節拍。

2) 編寫任務函數并設置其堆棧大小和優先級等參數。
編寫任務函數,以便UCOSII調用。
設置函數堆棧大小,需要根據函數的需求來設置,如果任務函數的局部變量多,嵌套層數多,那么相應的堆棧就得大一些,如果堆棧設置小了,很可能出現的結果就是CPU進入HardFault,遇到這種情況,就必須把堆棧設置大一點了。另外,有些地方還需要注意堆棧字節對齊的問題,如果任務運行出現莫名其妙的錯誤(比如用到sprintf出錯),請考慮是不是字節對齊的問題。
設置任務優先級,這個需要根據任務的重要性和實時性設置,記住高優先級的任務有優先使用CPU的權利。

3) 初始化UCOSII,并在UCOSII中創建任務
調用OSInit初始化UCOSII,通過調用OSTaskCreate函數創建任務。

4) 啟動UCOSII
調用OSStart啟動UCOSII。
通過以上4個步驟,UCOSII就開始在STM32上面運行。

總結

以上是生活随笔為你收集整理的STM32迷你板UCOSII系统移植的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。