uC/OS-II 移植笔记

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

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

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

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

修改 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

时间: 2024-10-12 15:52:14

uC/OS-II 移植笔记的相关文章

uC/OS II 任务切换原理

今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引发一次中断,自动将CS.IP寄存器压入堆栈,再利用中断返回,将新任务的任务断点指针弹出到CPU的CS.IP寄存器中,实现任务切换.虽然明白个大概,但是其中的细节却有点模糊,为什么调用IRET中断返回指令后,弹入CPU的CS.IP寄存器的断点指针是新任务的断点指针,而不是当前任务的,UCOS II是如

uc/os iii移植到STM32F4---IAR开发环境

也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢出警告(为何keil没有报堆栈溢出??),网上有人说不用理会,但是实际使用时发生了错误(定义的常量数组值被改变,怀疑是堆栈溢出导致),发现使用的IAR版本不能完美支持使用的STM32芯片,换用高版本测试..(高版本正确,与低版本对芯片的支持有关) 2.开始时虽然会堆栈溢出,但是能够进入异常中断,进入

uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()

1. OSTaskCreate()    OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构.        源码例如以下: #if OS_TASK_CREATE_EN > 0                    /* 条件编译,是否同意任务的创建               */INT8U  OSTaskCreate (void (*task)(void *pd), /* 函数指针,void *

lwIP移植笔记 - OS篇

lwIP作为RTOS准标配的TCP/IP,在我们编写网络模块时,经常用到. 本移植笔记使用lwIP的版本为V1.4.1. MDK:            V4.0+ RTOS:          μC/OS-II V2.91 Eval-Board: LPC1752 Ethernet:     ENC28J60 移植lwIP到OS其实就是实现sys.h的过程. 移植文档(doc\sys_arch.txt) Since lwIP 1.4.0, semaphore and mailbox functi

关于uC/OS的简单学习(转)

1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数,且处理函数非常简单,一般仅是向相应的Task发消息,唤醒该Task来处理中断任务. 一个高效的调度器,这是OS的灵魂,实现多任务间的调度(包括调度点.调度算法.任务切换等). 好像就这么点,呵呵.它不支持内存保护,即不像Linux那样分用户空间.内核空间.如一个Task运行时,可调用内核函数Task

lwIP移植笔记 - ethernet篇

我们已经完成了lwIP的系统移植,那么我们就需要进行ethernet的移植工作. ethernet的移植工作,主要是"填空"ethernetif.c的过程!(PS. 再一次感谢Adam Dunkels大侠的无私工作!以及对他的敬意!) ethernetif.c位置(../src/netif) 一.移植硬件 1. 初始化 实现函数:static    void    low_level_init(struct    netif    *netif); (1) 初始化MAC地址 (2) 初

Mac OS X学习笔记

命令行 软连接:$ sudo ln -s /home/user/bin/node-echo.js /usr/local/bin/node-echo 使环境变量的修改立即生效:source ~/.bash_profile hosts修改:sudo vi /etc/hosts 让node有root权限: $ sudo chown root /usr/local/bin/node $ sudo chmod +s /usr/local/bin/node 印象笔记 cmd+shift+d = date,

【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

1 LES BX, DWORD PTR DS:_OSTCBCur ;取得任务堆栈指针ES:[BX] 2 MOV ES:[BX+2], SS ;将当前SS(栈的基地址)寄存器值存放至当前任务堆栈的2,3内存单元 3 MOV ES:[BX+0], SP ;将当前SP(栈顶的偏移量)存放至当前任务堆栈的0,1内存单元 首先讲讲LES指针的功能:LES的功能有点像C语言的*. LES REG,MEM 参与操作的寄存器不仅有REG,还有ES寄存器.在16位系统中,寄存器为16位,很显然,MEM所指向的内存

FreeRTOS STM32移植笔记

FreeRTOS STM32移植笔记