日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

STM32迷你板UCOSII系统移植

發(fā)布時(shí)間:2025/4/5 windows 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32迷你板UCOSII系统移植 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

本文結(jié)構(gòu)

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

1.UCOSII簡介

UCOSII 是一個(gè)可以基于ROM 運(yùn)行的、可裁減的、搶占式、實(shí)時(shí)多任務(wù)內(nèi)核,具有高度可
移植性,特別適合于微處理器和控制器,是和很多商業(yè)操作系統(tǒng)性能相當(dāng)?shù)膶?shí)時(shí)操作系統(tǒng)
(RTOS)。

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

UCOSII體系結(jié)構(gòu)如圖所示

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

2.UCOSII移植具體步驟

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

UCOSII文件夾下新建三個(gè)文件夾

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

6,軟件資料\2,UCOS學(xué)習(xí)資料\UCOSII資料\UCOS II源碼\Micrium\Software\uCOS-II\Source


將上面所有文件復(fù)制到CORE文件夾下,復(fù)制完的CORE文件夾下內(nèi)容:

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

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

添加好文件的CONFIG文件夾

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

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

添加完的PORT文件夾

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


向分組中添加文件
UCOSII-CORE分組添加如下,但是需要?jiǎng)h除掉ucos_ii.c文件,否則會(huì)報(bào)錯(cuò)。

刪除掉ucos_ii.c文件之后

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

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

添加完成后會(huì)發(fā)現(xiàn)工程目錄下多了三個(gè)文件夾

但是我們發(fā)現(xiàn)UCOSII-CORE文件下都是加鎖的

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

回過頭來查看發(fā)現(xiàn)文件枷鎖已經(jīng)去掉

下面需要將路徑包含進(jìn)來
點(diǎn)擊魔法棒,選擇C/C++,找到include paths

點(diǎn)擊后面的添加按鈕

添加進(jìn)來CORE,PORT,CONFIG文件

下面進(jìn)行編譯,發(fā)現(xiàn)報(bào)錯(cuò)

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


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


然后再次編譯
又發(fā)現(xiàn)另一個(gè)錯(cuò)誤:PendSV_Handler 函數(shù)被重定義

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


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

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

在stm32f10x_it.c文件下

解決:注釋掉

再次編譯,發(fā)現(xiàn)沒有錯(cuò)誤

6.修改sys.h文件

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

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

將SYSTEM_SUPPORT_OS 改為1,表示支持UCOS系統(tǒng)
修改前:

修改后:


再次編譯,有報(bào)錯(cuò):還是重定義的問題,同樣的,這里我們還是注釋掉stm32f10x_it.c文件下SysTick_Handler 函數(shù)

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


再次編譯發(fā)現(xiàn)沒有錯(cuò)誤
這里需要注意的是os_cpu_c.h文件夾下的OSTaskStkInit函數(shù),當(dāng)移植時(shí)發(fā)現(xiàn)和下面的不一致時(shí),需要替換成下面的OSTaskStkInit函數(shù)。

/* ********************************************************************************************************* * 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.移植后的測試

下面進(jìn)行UCOSII操作系統(tǒng)的測試
將下面代碼復(fù)制到main.c中,替換掉原來的代碼

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

編譯之后沒有錯(cuò)誤,下載到開發(fā)板上

開發(fā)板出現(xiàn)led燈的交替閃爍,
再進(jìn)行串口測試,也就是浮點(diǎn)測試:每個(gè)500ms進(jìn)行+0.01的操作

至此,UCOSII操作系統(tǒng)移植成功。

4.總結(jié)

1) 移植UCOSII

要想U(xiǎn)COSII在STM32正常運(yùn)行,首先是需要移植UCOSII,正點(diǎn)原子提供的SYSTEM文件夾里面的系統(tǒng)函數(shù)直接支持UCOSII,只需要在sys.h文件里面將:SYSTEM_SUPPORT_UCOS宏定義改為1,即可通過delay_init函數(shù)初始化UCOSII的系統(tǒng)時(shí)鐘節(jié)拍,為UCOSII提供時(shí)鐘節(jié)拍。

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

3) 初始化UCOSII,并在UCOSII中創(chuàng)建任務(wù)
調(diào)用OSInit初始化UCOSII,通過調(diào)用OSTaskCreate函數(shù)創(chuàng)建任務(wù)。

4) 啟動(dòng)UCOSII
調(diào)用OSStart啟動(dòng)UCOSII。
通過以上4個(gè)步驟,UCOSII就開始在STM32上面運(yùn)行。

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。