基於IAR和STM32的uCOS-II移植

網上基於MDK的移植數不勝數,但是基於IAR的移植幾乎沒有,因爲官方的例程就是基於IAR的,所以移植起來很簡單,沒人介紹,但還是得小心謹慎,一不小心就出錯,對於新手來說,查找錯誤可不是那麼容易的。IAR建立工程,這裏就不介紹。

 

以下紅色部分需要與MCU型號對應

 

(1)在官網下載適合自己STM32的uCOS-II庫,連接如下,我用的MCU是STM32F103VCT6,屬於大容量的,所以選擇的庫是STMicroelectronics STM32F103ZE。

 

 

(2)下載下來的是(.exe)文件,雙擊解壓得到名稱爲Micrium的文件夾。

 

(3)在自己的工程中建立文件夾ucosii,裏面包含3個子文件夾,分別是config,port,source,文件夾名稱隨意。

 

(4)將文件夾Micrium\Software\uCOS-II\Ports\ARM-Cortex-M3\Generic\IAR中的文件全部複製到port文件夾中。

   將文件夾Micrium\Software\uCOS-II\Source中的文件全部複製到source文件夾中。

   將文件夾Micrium\Software\EvalBoards\ST\STM3210E-EVAL\IAR\OS-Probe中的app_cfg.h和os_cfg.h複製到config文件夾中。

   (STM3210E-EVAL此目錄根據STM型號而定,型號不相符是否有影響,未測試)

 

(5)爲了防止修改錯誤,這裏暫時可以將port和source這兩個文件夾中的文件設置爲只讀,以後用的時候再取消。

 

(6)修改os_cfg.h中的第一個宏定義爲#define OS_APP_HOOKS_EN    0  (取消鉤子函數)。

 

(7)將啓動程序startup_stm32f10x_hd.s中所有PendSV_Handler替換成OS_CPU_PendSVHandler,SysTick_Handler替換成OS_CPU_SysTickHandler。

注意:下面這種註釋是錯誤的,會導致進入硬件錯位中斷,害的我浪費了好幾天時間。

   PUBWEAK OS_CPU_PendSVHandler;PendSV_Handler

        SECTION .text:CODE:REORDER(1)
OS_CPU_PendSVHandler;PendSV_Handler
        B OS_CPU_PendSVHandler;PendSV_Handler

        PUBWEAK OS_CPU_SysTickHandler;SysTick_Handler
        SECTION .text:CODE:REORDER(1)
OS_CPU_SysTickHandler;SysTick_Handler
        B OS_CPU_SysTickHandler;SysTick_Handler

 

(8)打開Micrium\Software\EvalBoards\ST\STM3210E-EVAL\IAR\BSP\bsp.c文件,複製函數CPU_INT32U  BSP_CPU_ClkFreq (void)和INT32U  OS_CPU_SysTickClkFreq (void)到main.c中。

   (注意將所有CPU_INT32U修改爲INT32U,不然會報錯)

 

(9)在main.c中創建任務。

 

#include "ucos_ii.h"
#include "os_cpu.h"
#include "stm32f10x.h"

#define STARTUP_TASK_PRIO               10
#define STARTUP_TASK_STK_SIZE           64
OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE];

//LED1任務
//設置任務優先級
#define LED1_TASK_PRIO       5 
//設置任務堆棧大小
#define LED1_STK_SIZE       64
//創建任務堆棧空間
OS_STK LED1_TASK_STK[LED1_STK_SIZE];

//LED2任務
//設置任務優先級
#define LED2_TASK_PRIO       6 
//設置任務堆棧大小
#define LED2_STK_SIZE   64
//創建任務堆棧空間
OS_STK LED2_TASK_STK[LED2_STK_SIZE];

void led1_task(void *p_arg);
void led2_task(void *p_arg);

INT32U  OS_CPU_SysTickClkFreq (void)
{
    INT32U  freq;
    
    RCC_ClocksTypeDef  rcc_clocks;

    RCC_GetClocksFreq(&rcc_clocks);

    freq = (INT32U)rcc_clocks.HCLK_Frequency;
    
    return (freq);
}

void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能PB,PE端口時鐘
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED0-->PA.2 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度爲50MHz
 GPIO_Init(GPIOA, &GPIO_InitStructure); //根據設定參數初始化GPIOA.2
 GPIO_ResetBits(GPIOA,GPIO_Pin_2); //PA.2 輸出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;     //LED1-->PB.12 端口配置, 推輓輸出
 GPIO_Init(GPIOB, &GPIO_InitStructure);   //推輓輸出 ,IO口速度爲50MHz
 GPIO_ResetBits(GPIOB,GPIO_Pin_12); //PB.12 輸出高 
}

static void startup_task(void *p_arg)
{
    INT8U err;
    OS_CPU_SR cpu_sr=0;
    
    OS_CPU_SysTickInit();
    
    #if (OS_TASK_STAT_EN > 0)
    OSStatInit();
    #endif
    
    OS_ENTER_CRITICAL(); //進入臨界區(無法被中斷打斷) 
    
   
  err = OSTaskCreate(led1_task, (void *)0,
                       (OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1], LED1_TASK_PRIO);   
  err = OSTaskCreate(led2_task, (void *)0,
                       (OS_STK*)&LED2_TASK_STK[LED2_STK_SIZE-1], LED2_TASK_PRIO);
    
OSTaskSuspend(STARTUP_TASK_PRIO); //掛起起始任務.
OS_EXIT_CRITICAL(); //退出臨界區(可以被中斷打斷)
    
    if (OS_ERR_NONE != err)
while(1);
    
    OSTaskDel(OS_PRIO_SELF);
}

int main(void)
{
    LED_Init();
    OSInit();
    OSTaskCreate(startup_task, (void *)0,
                 (OS_STK*)&startup_task_stk[STARTUP_TASK_STK_SIZE-1],
                 STARTUP_TASK_PRIO);
    OSStart();
    return 0;
}

//LED1任務
void led1_task(void *p_arg)
{
while(1)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
        OSTimeDly(500);
GPIO_SetBits(GPIOA,GPIO_Pin_2);
        OSTimeDly(500);
}
}

//LED2任務
void led2_task(void *p_arg)
{  
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
        OSTimeDly(500);
GPIO_SetBits(GPIOB,GPIO_Pin_12);
        OSTimeDly(500);
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章