0.uCOSII簡介
0.0 uCOSii背景
μC/OS-II由Micrium公司提供,是一個可移植、可固化的、可裁剪的、占先式多任務實時核心,它适用于多種微處理器,微控制器和數字處理晶片(已經移植到超過100種以上的微處理器應用中)。同時,該系統源代碼開放、整潔、一緻,注釋詳盡,适合系統開發。
μC/OS-II已經通過聯邦航空局(FAA)商用航行器認證,符合航空無線電技術委員會(RTCA)DO-178B标準。
0.1 特點及組成
μC/OS-II可以提供如下服務:
信号量
互斥信号量
事件辨別
消息郵箱
消息隊列
任務管理
固定大小記憶體塊管理
時間管理
另外,在μC/OS-II核心之上,有如下獨立子產品可供使用者選擇:
μC/FS檔案系統子產品
μC/GUI圖形軟體子產品
μC/TCP-IP協定棧子產品
μC/USB協定棧子產品
μC/OS-II可以大緻分成核心、任務處理、時間處理、任務同步與通信,CPU的移植等5個部分。
(1) 核心部分(OSCore.c)
是作業系統的處理核心,包括作業系統初始化、作業系統運作、中斷進出的前導、時鐘節拍、任務排程、事件處理等多部分。能夠維持系統基本工作的部分都在這裡。
(2) 任務處理部分(OSTask.c)
任務處理部分中的内容都是與任務的操作密切相關的。包括任務的建立、删除、挂起、恢複等等。因為μC/OS-II是以任務為基本機關排程的,是以這部分内容也相當重要。
(3) 時鐘部分(OSTime.c)
μC/OS-II中的最小時鐘機關是timetick(時鐘節拍)。任務延時等操作是在這裡完成的。
(4) 任務同步和通信部分
為事件處理部分,包括信号量、郵箱、郵箱隊列、事件标志等部分;主要用于任務間的互相聯系和對臨界資源的通路。
(5) 與CPU的接口部分
是指μC/OS-II針對所使用的CPU的移植部分。由于μC/OS-II是一個通用性的作業系統,是以對于關鍵問題上的實作,還是需要根據具體CPU的具體内容和要求作相應的移植。這部分内容由于牽涉到SP等系統指針,是以通常用彙編語言編寫。主要包括中斷級任務切換的底層實作、任務級任務切換的底層實作、時鐘節拍的産生和處理、中斷的相關處理部分等内容。
以上就是些基礎知識,不多說,進入正題!
1.0 移植準備
環境:KEIL-MDK v-5.25
硬體:STM32F103VET6核心闆
模闆程式:點燈程式即可
Uocsii源碼:http://micrium.com/downloadcenter/download-results/?searchterm=mp-uc-os-ii&supported=true下載下傳即可
得到檔案解壓後如下圖:

Doc-此檔案夾為一些關于uCOSII的文檔,可以看一下,我們所需要的移植檔案都在Souce檔案夾下。
1.1 移植檔案
在我們的模闆程式的工程目錄下建立一個 UCOS 空檔案夾,用來放置我們的移植檔案,同時在UCOS路徑下建立三個檔案夾 1.CORE, 2.CONFIG,
3.CONFIG檔案夾如下圖
在我們的Source下找到我們所需的檔案,将它們添加複制到我們的三個檔案夾中;如下所示:
CORE:
CONFIG:此檔案夾隻需要兩個檔案
includes.h:為一些配置檔案,我複制出來了
/*
************************************************************************************************
主要的包含檔案
文 件: INCLUDES.C ucos包含檔案
作 者: Jean J. Labrosse
************************************************************************************************
*/
#ifndef __INCLUDES_H__
#define __INCLUDES_H__
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include "ucos_ii.h"
#include "os_cpu.h"
#include "os_cfg.h"
#include <stm32f10x.h>
#endif
接下來就是我們的最後一個檔案夾
PORT:
這個檔案需要另外下載下傳,我就把整個檔案夾打包出來,https://pan.baidu.com/s/1-ZGLL-fc_cRwGfF87UaTsw
我們現在将所有檔案都添加進來了,但是我們隻是添加到檔案路徑中,還沒有真正添加到工程中,接下來我們将我們的檔案添加到工程中;
2.0 工程配置
将所需檔案添加至工程中
注意:
1.千萬不要吧ucos_ii.c檔案添加到UCOS-CORE分組中嗎,不然會出現很多的報錯。
2.記得同時将頭檔案路徑添加進去
添加完成後我們可以嘗試編譯工程,結果我們會出現出現很多報錯, 但是有很多報錯提示我們找不到頭檔案 app_cfg.h.
解決方法:
1.打開ucosii.h,注釋以下其app_cfg.h的聲明,因為我們沒有用到這個頭檔案。同時将我們的 includes.h 頭檔案聲明。
2.打開 stm32f103x_it.c,将中斷函數 void PendSV_Handler(void) 及其内容注釋掉 :
3.打開sys.h檔案,将此處定義修改以下,另其為1,因為本人用的是正點的模闆,是以此處必須修改才可以支援OS:
#define SYSTEM_SUPPORT_OS 1 //定義系統檔案夾是否支援UCOS
到此我們的UCOSii的配置基本就完成了,沒有報錯,那我們就把我們的點燈程式加入OS歡樂的跑起來吧。
#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);
}
}
代碼已粘貼出,我移植UCOSii的資料來自原子哥,在配置完成後,他會出現一個報錯:
…\OBJ\LED.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by delay.o and stm32f10x_it.o).
此時隻需要屏蔽 void SysTick_Handler(void)中斷即可
聲明:此文僅用來記錄學習和加深印象,畢竟類文太多了,我也是一路COPY過來的。