• 简单RTOS学习(一) uc/os-II 工程模板建立


      随着工业需求以及单片机性能越来越高,单个芯片能够且需要处理的任务也越来越多,使用传统前后台任务模式已经很难满足设计的需求,嵌入式实时操作系统正是在这种背景下发展起来,目前流行的有rt-threadfreeRTOSuc/os等轻量级嵌入式操作系统,以及嵌入式Linux这样用于复杂应用开发的操作系统,它们的各有优劣。对于开发者来说,熟悉和使用嵌入式操作系统也是必备技能。深入和理解RTOS的原理,邵贝贝的<嵌入式实时操作系统uCOS-II>是比较好的资料。不过本博文是从应用的角度阐述ucos的移植,以及各模块在实际开发中的运用,不过多的涉及内部的实现原理和核心技术。

      uC/OS-II移植stm32在网上的说明很多这里在大量的重复意义不大,因此本节重点不是如何完成移植,而是讲述如何根据现有文件快速新建一个ucos工程模板。对于Cortex-M3平台,如os_cpu_a.asm这个汇编文件就是通用的,直接拿来用就可以。

    1.startup_stm32f10x_cl.s (启动代码)

     这里面涉及到两个中断,SysTick_Handler 和 PendSV_Handler

     根据文档说明建议SysTick_Handler保留作为系统滴答时钟,PendSV_Handle则使用uC/OS-II内部自带中断替换

     即需要将startup_stm32f10x_cl.s中的3处PendSV_Handler全部都替换为OS_CPU_PendSVHandler,建议用MDK自带的replace替换,如此启动文件修改完毕。

    2.os_cpu_c.c(堆栈建立及钩子函数)

     因为SysTick_Handler保留为操作系统滴答时钟,那么CPU文件中的操作系统时钟函数就不需要,可以注释掉。

    //void OS_CPU_SysTickHandler(void)
    //{
    //    OS_CPU_SR  cpu_sr;
    
    //    OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR          */
    //    OSIntNesting++;
    //    OS_EXIT_CRITICAL();
    //   
    //        OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */
    //    OSIntExit();                                 /* Tell uC/OS-II that we are leaving the ISR          */
    //}

    3.stm32f10x_it.c(stm3210x系列的中断函数定义文件)

     将SysTick_Handler保留作为ucos系统的滴答时钟,那么就把OS_CPU_SysTickHandler内数据复制到系统滴答时钟中

    void SysTick_Handler(void)
    {
        OS_CPU_SR  cpu_sr;
    
       OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR */
       OSIntEnter();
       OS_EXIT_CRITICAL();
        OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()               */
      OSIntExit();                                 /* Tell uC/OS-II that we are leaving the ISR  */
    }

    4.main.c(启动系统,新建任务)

      maic.c主要处理系统启动和任务创建相关功能

    static  void      App_TaskStart(void        *p_arg);
    static  OS_STK   App_TaskStartStk[APP_TASK_START_STK_SIZE];
    
    static  void      Task1(void        *p_arg);
    static  OS_STK  Task1Stk[APP_TASK_START_STK_SIZE];
    
    int main(void)
    {
        /*屏蔽所有中断*/
         IntDisAll(); 
    
        /*初始化uC/OS-II系统*/
        OSInit();                        
      
        /*创建任务App_TaskStart,堆栈512,优先级9*/
        OSTaskCreate(App_TaskStart,
                                 (void *)0,
                                 &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],    
                                 APP_TASK_START_PRIO);
        
        /*节拍计数器清零*/
        OSTimeSet(0);
    
        /*u/OS-II启动*/
        OSStart();     
                                     
        return 0;
    }
    
    static  void      App_TaskStart(void        *p_arg)
    {
    #if OS_CRITICAL_METHOD == 3  
        OS_CPU_SR          cpu_sr = 0;  
    #endif
        
       /*外设相关初始化*/
        BSP_Init();
        
        /*systick时钟初始化*/
        SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);
        
        /*进入临界区*/
        OS_ENTER_CRITICAL();  
        
        /*创建任务App_TaskStart,堆栈512,优先级9*/
        OSTaskCreate(Task1,
                                 (void *)0,
                                 &Task1Stk[APP_TASK_START_STK_SIZE - 1],    
                                 1);
        
        /*离开临界区*/
        OS_EXIT_CRITICAL();
        
        while(1)
        {
            /*系统运行状态确认*/
            GPIO_ResetBits(GPIO_LED, GPIO_LED_1);
            OSTimeDlyHMSM(0, 0, 0, 400);
            GPIO_SetBits(GPIO_LED, GPIO_LED_1);
            OSTimeDlyHMSM(0, 0, 0, 400);
        }
    }
    
    static  void  Task1(void        *p_arg)
    {
        while(1)
        {
            /*系统运行状态确认*/
            GPIO_ResetBits(GPIO_LED, GPIO_LED_2);
            OSTimeDlyHMSM(0, 0, 0, 200);
            GPIO_SetBits(GPIO_LED, GPIO_LED_2);
            OSTimeDlyHMSM(0, 0, 0, 200);
        }
    }

      将编译完成的文件下载到开发板中,就可以看到两个LED以不同的频率闪烁,从而证明工程模板建立成功。

      os_cpu_a.asm文件链接:os_cpu_a.asm文件

      ucos-ii移植范例链接:ucos-ii工程模板

    MDK技巧:

      一般情况下,将网络/文本上代码复制到MDK中,或者将MDK代码复制到网页/文本中,如果注释为中文,则往往会变成乱码,这里说明解决办法:

      选择左上角Edit->最后项Configuration->Editor下的Encoding项选择为Chinese GB2312(Slimplified),之后再进行复制即可,如果不习惯这种字体,复制完毕后在改为ANSI,此时不会出现乱码。如图:

      

  • 相关阅读:
    LOJ.2721.[NOI2018]屠龙勇士(扩展CRT 扩展欧几里得)
    Codeforces.959E.Mahmoud and Ehab and the xor-MST(思路)
    BZOJ.3058.四叶草魔杖(Kruskal 状压DP)
    Codeforces.838E.Convex Countour(区间DP)
    Codeforces.838D.Airplane Arrangements(思路)
    Codeforces.997C.Sky Full of Stars(容斥 计数)
    Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)
    BZOJ.3759.Hungergame(博弈论 线性基)
    LOJ.2718.[NOI2018]归程(Kruskal重构树 倍增)
    序列化二叉树
  • 原文地址:https://www.cnblogs.com/zc110747/p/4683640.html
Copyright © 2020-2023  润新知