一、下載ucosii系統源文件
https://www.micrium.com/downloadcenter/download-results/?searchterm=mi-stm32f103ze&supported=true
二、創建工程
在stm32裸機工程的基礎上實現ucos系統的移植。在工程目錄下新建uCOSII目錄,並在該目錄下建立CONFIG,CORE,PORT三個文件夾,分類存放需要的系統源文件。
\Micrium\Software\EvalBoards\ST\STM32F103ZE-SK\IAR\OS-Probe-LCD中的app_cfg.h,include.h,os_cfg.h複製到CONFIG文件夾中
\Micrium\Software\uCOS-II\Source中的所有文件複製到CORE目錄下
\Micrium\Software\uCOS-II\Ports\arm-cortex-m3\Generic\IAR中的所有文件複製到PORT目錄下
在工程中添加對應的組,並將文件添加到工程中,將頭文件目錄添加到工程的包含路徑中
三、需要修改的文件
os_cpu_a.asm
將PUBLIC FUNCTIONS中的PUBLIC修改爲EXPORT,因爲MDK編程環境不是別PUBLIC,
PUBLIC OS_CPU_SR_Save EXPORT OS_CPU_SR_Save
PUBLIC OS_CPU_SR_RestoreEXPORT OS_CPU_SR_Restore
PUBLIC OSStartHighRdyEXPORT OSStartHighRdy
PUBLIC OSCtxSw EXPORT OSCtxSw
PUBLIC OSIntCtxSw EXPORT OSIntCtxSw
PUBLIC OS_CPU_PendSVHandler EXPORT OS_CPU_PendSVHandler
將CODE GENERATION DIRECTIVES中的內容替換成環境可以識別的指令
RSEGCODE:CODE:NOROOT(2)
轉換成
AREA|.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
os_dbg.c
去掉#define OS_COMPILER_OPT 的宏定義
#define OS_COMPILER_OPT // __root
includes.h
取消暫時沒有使用的頭文件
//#include <cpu.h>
//#include <lib_def.h>
//#include <lib_mem.h>
//#include <lib_str.h>
//#include <lib_ascii.h>
//#include <stm32f10x_lib.h>
//#include <bsp.h>
//#include <probe_com.h>
//#include <ksd.h>
//#include <ksd.h>
//#include <probe_rs232.h>
#//include <os_probe.h>
os_cfg.h
取消APP_HOOK的使能
#defineOS_APP_HOOKS_EN 0
startup_stm32f10x_hd.s
將處理器啓動文件中所有的PendSV_Handler中斷向量名修改爲OS_CPU_PendSVHandler
stm32f10x_it.c
添加頭文件,並完善SysTick_Handler()函數
#include<ucos_ii.h>
/**
*@brief This function handles SysTickHandler.
*@param None
*@retval None
*/
voidSysTick_Handler(void)
{
OSIntEnter(); //進入中斷
OSTimeTick(); //調用ucos的時鐘服務程序
OSIntExit(); //觸發任務切換軟中斷
}
四、程序設計
主程序通過兩個任務實現兩個LED燈同時閃爍
//UCOSII-任務調度
#include "includes.h"
#define LED3(opt) ((opt) ? (GPIOB->BRR |= 1<<5):(GPIOB->BSRR |= 1<<5))
#define LED2(opt) ((opt) ? (GPIOE->BRR |= 1<<5):(GPIOE->BSRR |= 1<<5))
#define SystemFrequency 72000000
/////////////////////////UCOSII任務堆棧設置///////////////////////////////////
//START任務
//設置任務優先級
#define START_TASK_PRIO 10 //開始任務的優先級設置爲最低
//設置任務堆棧大小
#define START_STK_SIZE 64
//創建任務堆棧空間
OS_STK START_TASK_STK[START_STK_SIZE];
//任務函數接口
void start_task(void *pdata);
//LED1任務
#define LED1_TASK_PRIO 7
#define LED1_STK_SIZE 64
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
void led1_task(void *pdata);
//LED2任務
#define LED2_TASK_PRIO 6
#define LED2_STK_SIZE 64
OS_STK LED2_TASK_STK[LED2_STK_SIZE];
void led2_task(void *pdata);
//初始化PB5和PE5爲輸出口並使能這兩個時鐘
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE兩個端口時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度爲50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據設定參數初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5輸出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
}
void SysTick_init(void)
{
SysTick_Config(SystemFrequency/OS_TICKS_PER_SEC);
}
int main(void)
{
SysTick_init();
LED_Init();
OSInit();
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(); //³õʼ»¯Í³¼ÆÈÎÎñ.ÕâÀï»áÑÓʱ1ÃëÖÓ×óÓÒ
OS_ENTER_CRITICAL(); //½øÈëÁÙ½çÇø(ÎÞ•¨±»Öжϴò¶Ï)
OSTaskCreate(led1_task,(void *)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
OSTaskCreate(led2_task,(void *)0,(OS_STK*)&LED2_TASK_STK[LED2_STK_SIZE-1],LED2_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //掛起起始任務
OS_EXIT_CRITICAL(); //退出臨界區
}
//LED1任務
void led2_task(void *pdata)
{
while(1)
{
LED3(1);
OSTimeDlyHMSM(0,0,2,0);
LED3(0);
OSTimeDlyHMSM(0,0,0,500);
};
}
//LED2任務
void led1_task(void *pdata)
{
while(1)
{
LED2(1);
OSTimeDlyHMSM(0,0,1,0);
LED2(0);
OSTimeDlyHMSM(0,0,1,0);
};
}