1. 程式人生 > >UCOSII移植筆記(UCOSII+STM32F103+LED)

UCOSII移植筆記(UCOSII+STM32F103+LED)

編譯環境使用的是MDK,先實現ucosii的最基本功能,可以實現任務的排程,什麼訊號量,郵箱,佇列那些東西先不管。

1:檔案準備 之前下載的是官方沒有移植的原始碼,教程說只需要改一下os_cpu.h,os_cpu_a.asm 和os_cpu_c.c 就可以了,但是一看原始碼中 就是少了幾個檔案。未移植的原始碼檔案列表如下圖所示。
後來查了一些資料,原來別人用的是官方移植好的案例。在官網找了一下,有STM32的案例,但是隻有IAR環境下的。 先下下來再說,後來發現果然有在我們需要這裡面三個檔案都有。 說一個小的訣竅,用sourceinsight直接開啟工程裡面所有的檔案,看看有沒有我們所需要的檔案,就不需要一個一個資料夾去找了,工程裡面的所有檔案一目瞭然。 然後將所需要的檔案複製過來(uc/os-ii port的裡面原始檔全都複製過來),其檔案如下所示。同時將app_cfg.h複製過來(在移植的案例中,一些巨集定義定義在這裡)。ucosii.c刪了(沒有啥用)。

需要說明一下的情況是,工程模板裡面用的是ucos v2.86 但是我下載的原始碼是v2.90版本的。這裡面系統稍微有點不同,檔名也有不同。我的策略是檔名一樣的就用v2.90版本的檔案,有差別的就用工程模板裡面的。

然後將LED燈驅動原始檔和stm32的庫檔案新增進工程


注意在注意在魔術棒那裡新增標頭檔案的路徑,不要漏了,要不很惱火。

2:檔案配置和修改 (1)os_cfg.h 是用來配置系統功能的,我們需要通過修改它來達到剪裁系統功能的目的。      首先肯定是禁用訊號量、互斥訊號量、郵箱、佇列、訊號量集、定時器、記憶體管理,關閉除錯模式:      也用不著應用軟體的鉤子函式,也禁掉;多重事件控制也禁掉。 (2)修改 os_cpu_a.asm      PUBIC 改為 EXPORT 宣告函式名稱。      ·RSEG CODE:CODE:NOROOT(2)換成(記住,千萬不要頂格啊,要不錯誤在哪裡都不知道)       AREA |.text|, CODE, READONLY, ALIGN=2 ;AREA |.text| 表示:選擇段 |.text|
     ;CODE 表示程式碼段,READONLY 表示只讀(預設) ;ALIGN=2 表示 4 位元組對齊。若 ALIGN=n,這 2^n      THUMB ;Thumb 程式碼      REQUIRE8 ;指定當前檔案要求堆疊八位元組對齊      PRESERVE8 ;令指定當前檔案保持堆疊八位元組對齊 (3)修改 startup_stm32f10x_hd.s中PendSV_Handler 的地方替換成OS_CPU_PendSVHandler。即修改pendsv中斷函式的名稱          SysTick_Handler替換成OS_CPU_SysTickHandler,即修改系統時鐘中斷函式的名稱。 3:除錯 其他地方其實根本不需要修改。IAR與mdk都是通用的,基於cortex-M3核心進行開發的。什麼os_ctx,systickinit等都不需要進行修改。 在debug的時候,看哪些東西是是報錯未定義的,再到下載的工程案例中去找,或者是將檔案新增進來,或者是將函式或者巨集定義新增原始碼中(我的話是因為不想將為了一個函式或者巨集定義就將工程模板中的的一個檔案就拉倒工程中來,就貼上將報錯未定義的函式和巨集在工程模板檔案中找到,複製貼上)。有些巨集定義因為配置的不對會報錯,也要根據實際情況報錯資訊進行一下配置。 4:多工執行,主函式的寫法,以及多工的啟動。 #include "app.h"
#include  "ucos_ii.h"    
#include  "app_cfg.h"

#define TASK_STK_SIZE 512
#define     TaskStart_Prio 1 OS_STK TaskStk[5][TASK_STK_SIZE]; //UCOSII將使用者任務堆疊的定義交給了程式設計師自己實現。不一定需要使用二維陣列
void task1(void *p)
{
     while(1)
     {
          LED1_ON;
          delay();
          LED1_OFF;
          delay();
          OSTaskResume(2);
          OSTaskSuspend(1);
     }
    
}
void task2(void*p)
{
     while(1)
     {
          LED2_ON;
          delay();
          LED2_OFF;
          delay();
          OSTaskSuspend(2);
     }
}
void task3(void*p)
{
     while(1)
     {
          LED3_ON;
          delay();
          LED3_OFF;
          delay();
          OSTaskResume(1);
         
     }
}
int main(void)
{
     LED_GPIO_Config();
     OSInit();
     OSTaskCreate(task1,0,&TaskStk[1][TASK_STK_SIZE-1],1);
     OSTaskCreate(task2,0 ,&TaskStk[2][TASK_STK_SIZE-1],2);
     OSTaskCreate(task3,0 ,&TaskStk[3][TASK_STK_SIZE-1],3);
     OSStart();
     return 0; } 然後編譯執行。下載到板子上,我的是完全可以執行。