• 基于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)将文件夹MicriumSoftwareuCOS-IIPortsARM-Cortex-M3GenericIAR中的文件全部复制到port文件夹中。
       将文件夹MicriumSoftwareuCOS-IISource中的文件全部复制到source文件夹中。
       将文件夹MicriumSoftwareEvalBoardsSTSTM3210E-EVALIAROS-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)打开MicriumSoftwareEvalBoardsSTSTM3210E-EVALIARBSPsp.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);
    }
    }


  • 相关阅读:
    MyBatis 知识点梳理
    SSH无密码登录的原理及配置
    Maven学习笔记
    阿里Java开发电话面试经历惨败
    Java生成验证码(二)
    Java生成验证码(一)
    Hibernate 知识点梳理
    数据结构线性表顺序表示 (二)
    replace tabs with the proper number of blanks
    数据结构线性表顺序表示 (三)
  • 原文地址:https://www.cnblogs.com/lialong1st/p/7756651.html
Copyright © 2020-2023  润新知