uC/OS-II 移植笔记

  用过51、AVR、Freescale、STM32,但是写程序一直没有用过实时操作系统,一是因为写的项目不大,二是不太想去看手册学东西。现在写的项目也算比较大,因为需要,所以就学一下,这样也不至于每次的程序都裸奔。

用的红牛STM32开发板(很久之前的板子,STM32F103ZET6芯片)

首先下载官方的库,还有uc/OS的源码。建立好工程后,添加UC/OS。如图

注意os_cfg.h 和 app_cfg.h 在源码里是没有的,一般是拷贝MicriumSoftwareEvalBoards里面的。

修改 startup_stm32f10x_hd.s

把PendSV_Handler 替换成 OS_CPU_PendSVHandler

把SysTick_Handler 替换成 OS_CPU_SysTickHandler

如果编译器报错说这两个函数没有声明,那在前面再添加 IMPORT 声明下。如下:

        DCD     SVC_Handler               ; SVCall Handler
        DCD     DebugMon_Handler          ; Debug Monitor Handler
        DCD     0                         ; Reserved
      ;  DCD     PendSV_Handler            ; PendSV Handler
        IMPORT  OS_CPU_PendSVHandler
        DCD     OS_CPU_PendSVHandler
      ;  DCD     SysTick_Handler           ; SysTick Handler
        IMPORT  OS_CPU_SysTickHandler 
        DCD     OS_CPU_SysTickHandler 
       
         ; External Interrupts
        DCD     WWDG_IRQHandler           ; Window Watchdog
        DCD     PVD_IRQHandler            ; PVD through EXTI Line detect
        DCD     TAMPER_IRQHandler         ; Tamper

修改OS_CFG.H,这里面主要是系统要启用的功能,我的配置如下:

#ifndef OS_CFG_H
#define OS_CFG_H

                                       /* ---------------------- MISCELLANEOUS ----------------------- */
#define OS_APP_HOOKS_EN           0    /* Application-defined hooks are called from the uC/OS-II hooks */
#define OS_ARG_CHK_EN             1    /* Enable (1) or Disable (0) argument checking                  */
#define OS_CPU_HOOKS_EN           1    /* uC/OS-II hooks are found in the processor port files         */

#define OS_DEBUG_EN               0    /* Enable(1) debug variables                                    */
#define OS_EVENT_MULTI_EN         0    /* Include code for OSEventPendMulti()                          */

#define OS_EVENT_NAME_SIZE       16    /* Determine the size of the name of a Sem, Mutex, Mbox or Q    */

#define OS_LOWEST_PRIO           31    /* Defines the lowest priority that can be assigned ...         */
                                       /* ... MUST NEVER be higher than 254!                           */

#define OS_MAX_EVENTS            10    /* Max. number of event control blocks in your application      */
#define OS_MAX_FLAGS              5    /* Max. number of Event Flag Groups    in your application      */
#define OS_MAX_MEM_PART           5    /* Max. number of memory partitions                             */
#define OS_MAX_QS                 4    /* Max. number of queue control blocks in your application      */
#define OS_MAX_TASKS             16    /* Max. number of tasks in your application, MUST be >= 2       */

#define OS_SCHED_LOCK_EN          0    /*     Include code for OSSchedLock() and OSSchedUnlock()       */

#define OS_TICK_STEP_EN           0    /* Enable tick stepping feature for uC/OS-View                  */
#define OS_TICKS_PER_SEC       1000    /* Set the number of ticks in one second                        */


                                       /* --------------------- TASK STACK SIZE ---------------------- */
#define OS_TASK_TMR_STK_SIZE    128    /* Timer      task stack size (# of OS_STK wide entries)        */
#define OS_TASK_STAT_STK_SIZE   128    /* Statistics task stack size (# of OS_STK wide entries)        */
#define OS_TASK_IDLE_STK_SIZE   128    /* Idle       task stack size (# of OS_STK wide entries)        */


                                       /* --------------------- TASK MANAGEMENT ---------------------- */
#define OS_TASK_CHANGE_PRIO_EN    0    /*     Include code for OSTaskChangePrio()                      */
#define OS_TASK_CREATE_EN         1    /*     Include code for OSTaskCreate()                          */
#define OS_TASK_CREATE_EXT_EN     1    /*     Include code for OSTaskCreateExt()                       */
#define OS_TASK_DEL_EN            1    /*     Include code for OSTaskDel()                             */
#define OS_TASK_NAME_SIZE        16    /*     Determine the size of a task name                        */
#define OS_TASK_PROFILE_EN        1    /*     Include variables in OS_TCB for profiling                */
#define OS_TASK_QUERY_EN          0    /*     Include code for OSTaskQuery()                           */
#define OS_TASK_STAT_EN           0    /*     Enable (1) or Disable(0) the statistics task             */
#define OS_TASK_STAT_STK_CHK_EN   0    /*     Check task stacks from statistic task                    */
#define OS_TASK_SUSPEND_EN        0    /*     Include code for OSTaskSuspend() and OSTaskResume()      */
#define OS_TASK_SW_HOOK_EN        1    /*     Include code for OSTaskSwHook()                          */


                                       /* ----------------------- EVENT FLAGS ------------------------ */
#define OS_FLAG_EN                0    /* Enable (1) or Disable (0) code generation for EVENT FLAGS    */
#define OS_FLAG_ACCEPT_EN         1    /*     Include code for OSFlagAccept()                          */
#define OS_FLAG_DEL_EN            1    /*     Include code for OSFlagDel()                             */
#define OS_FLAG_NAME_SIZE        16    /*     Determine the size of the name of an event flag group    */
#define OS_FLAGS_NBITS           16    /*     Size in #bits of OS_FLAGS data type (8, 16 or 32)        */
#define OS_FLAG_QUERY_EN          1    /*     Include code for OSFlagQuery()                           */
#define OS_FLAG_WAIT_CLR_EN       1    /*     Include code for Wait on Clear EVENT FLAGS               */


                                       /* -------------------- MESSAGE MAILBOXES --------------------- */
#define OS_MBOX_EN                0    /* Enable (1) or Disable (0) code generation for MAILBOXES      */
#define OS_MBOX_ACCEPT_EN         1    /*     Include code for OSMboxAccept()                          */
#define OS_MBOX_DEL_EN            1    /*     Include code for OSMboxDel()                             */
#define OS_MBOX_PEND_ABORT_EN     1    /*     Include code for OSMboxPendAbort()                       */
#define OS_MBOX_POST_EN           1    /*     Include code for OSMboxPost()                            */
#define OS_MBOX_POST_OPT_EN       1    /*     Include code for OSMboxPostOpt()                         */
#define OS_MBOX_QUERY_EN          1    /*     Include code for OSMboxQuery()                           */


                                       /* --------------------- MEMORY MANAGEMENT -------------------- */
#define OS_MEM_EN                 0    /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_NAME_SIZE         16    /*     Determine the size of a memory partition name            */
#define OS_MEM_QUERY_EN           1    /*     Include code for OSMemQuery()                            */


                                       /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
#define OS_MUTEX_EN               0    /* Enable (1) or Disable (0) code generation for MUTEX          */
#define OS_MUTEX_ACCEPT_EN        1    /*     Include code for OSMutexAccept()                         */
#define OS_MUTEX_DEL_EN           1    /*     Include code for OSMutexDel()                            */
#define OS_MUTEX_QUERY_EN         1    /*     Include code for OSMutexQuery()                          */


                                       /* ---------------------- MESSAGE QUEUES ---------------------- */
#define OS_Q_EN                   0    /* Enable (1) or Disable (0) code generation for QUEUES         */
#define OS_Q_ACCEPT_EN            1    /*     Include code for OSQAccept()                             */
#define OS_Q_DEL_EN               1    /*     Include code for OSQDel()                                */
#define OS_Q_FLUSH_EN             1    /*     Include code for OSQFlush()                              */
#define OS_Q_PEND_ABORT_EN        1    /*     Include code for OSQPendAbort()                          */
#define OS_Q_POST_EN              1    /*     Include code for OSQPost()                               */
#define OS_Q_POST_FRONT_EN        1    /*     Include code for OSQPostFront()                          */
#define OS_Q_POST_OPT_EN          1    /*     Include code for OSQPostOpt()                            */
#define OS_Q_QUERY_EN             1    /*     Include code for OSQQuery()                              */


                                       /* ------------------------ SEMAPHORES ------------------------ */
#define OS_SEM_EN                 0    /* Enable (1) or Disable (0) code generation for SEMAPHORES     */
#define OS_SEM_ACCEPT_EN          1    /*    Include code for OSSemAccept()                            */
#define OS_SEM_DEL_EN             1    /*    Include code for OSSemDel()                               */
#define OS_SEM_PEND_ABORT_EN      1    /*    Include code for OSSemPendAbort()                         */
#define OS_SEM_QUERY_EN           1    /*    Include code for OSSemQuery()                             */
#define OS_SEM_SET_EN             1    /*    Include code for OSSemSet()                               */


                                       /* --------------------- TIME MANAGEMENT ---------------------- */
#define OS_TIME_DLY_HMSM_EN       1    /*     Include code for OSTimeDlyHMSM()                         */
#define OS_TIME_DLY_RESUME_EN     1    /*     Include code for OSTimeDlyResume()                       */
#define OS_TIME_GET_SET_EN        1    /*     Include code for OSTimeGet() and OSTimeSet()             */
#define OS_TIME_TICK_HOOK_EN      1    /*     Include code for OSTimeTickHook()                        */


                                       /* --------------------- TIMER MANAGEMENT --------------------- */
#define OS_TMR_EN                 0    /* Enable (1) or Disable (0) code generation for TIMERS         */
#define OS_TMR_CFG_MAX           16    /*     Maximum number of timers                                 */
#define OS_TMR_CFG_NAME_SIZE     16    /*     Determine the size of a timer name                       */
#define OS_TMR_CFG_WHEEL_SIZE     8    /*     Size of timer wheel (#Spokes)                            */
#define OS_TMR_CFG_TICKS_PER_SEC 10    /*     Rate at which timer management task runs (Hz)            */



#endif

然后在 os_cpu_c.c 中添加一个获取时钟频率的函数:

INT32U OS_CPU_SysTickClkFreq(void) 
{ 
  RCC_ClocksTypeDef  rcc_clocks; 
  RCC_GetClocksFreq(&rcc_clocks); 
  return ((INT32U)rcc_clocks.HCLK_Frequency); 
  
}

到此为止移植的差不多了。

主函数:

#include "common.h"

extern const unsigned char gImage_image[153600];
static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE];


void HW_Init(void)
{
  SystemInit();
  TFT_Init();
  RB_LED_GPIO_Init();
  ili9320_Clear(Green);
  RB_Comm_GPIOOUT_Init();
  RB_Time2_Mode_Config();
  RB_Time2_NVIC_Configuration();
 
}
void HW_Set_Init(void)
{
  ili9320_DrawPicture(0,0,240,320,(u16*)gImage_image);
}

int main()
{
  HW_Init();
  SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC); 
  OSInit();
  OSTaskCreate(RB_Task_LED,(void *)0,&startup_task_stk[STARTUP_TASK_STK_SIZE-1], STARTUP_TASK_PRIO);
  OSStart();
  return 0;
}

OS的APP函数:

#include "ucos_app.h"

static OS_STK task_led1_stk[TASK_LED1_STK_SIZE];
static OS_STK task_led2_stk[TASK_LED2_STK_SIZE];

void RB_Task_LED(void *p_arg)
{
  (void)p_arg;
  OSTaskCreate(RB_Task_led1,(void *)0,&task_led1_stk[TASK_LED1_STK_SIZE-1], TASK_LED1_PRIO);
  OSTaskCreate(RB_Task_led2,(void *)0,&task_led2_stk[TASK_LED2_STK_SIZE-1], TASK_LED2_PRIO);
  while(1)
  {
    RB_LED_ReadWrite(2,0);
    OSTimeDlyHMSM(0, 0,0,100);
    RB_LED_ReadWrite(2,1);
    OSTimeDlyHMSM(0, 0,0,100);
  }
}
void RB_Task_led1(void *p_arg)
{
  (void)p_arg;
  while(1)
  {
    RB_LED_ReadWrite(3,0);
    OSTimeDlyHMSM(0, 0,0,200);
    RB_LED_ReadWrite(3,1);
    OSTimeDlyHMSM(0, 0,0,200);
  }
}

void RB_Task_led2(void *p_arg)
{
  (void)p_arg;
  while(1)
  {
    RB_LED_ReadWrite(4,0);
    OSTimeDlyHMSM(0, 0,0,300);
    RB_LED_ReadWrite(4,1);
    OSTimeDlyHMSM(0, 0,0,300);
  }
}

APP_CFG.H

#ifndef __APP_CFG_H__
#define __APP_CFG_H__

#define STARTUP_TASK_PRIO 4         //任务优先级
#define TASK_LED1_PRIO 5
#define TASK_LED2_PRIO 6

#define STARTUP_TASK_STK_SIZE 80    //设置栈大小
#define TASK_LED1_STK_SIZE 80
#define TASK_LED2_STK_SIZE 80




#endif

编译通过后,下载到板子既可以发现三个LED以不同频率闪烁了

移植主要参考的是 野火的教程 :《从0开始移植UCOS II到野火M3开发板教程(V2.0》

接下来就是学习UC/OS的具体用法和功能了。

                                                                                                                                      2015-5-13

原文地址:https://www.cnblogs.com/einstein-2014731/p/4499690.html