uC/OS-II 移植笔记

时间:2021-06-05 13:30:50

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

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

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

uC/OS-II 移植笔记

注意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 ; 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[];
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(,,,,(u16*)gImage_image);
} int main()
{
HW_Init();
SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);
OSInit();
OSTaskCreate(RB_Task_LED,(void *),&startup_task_stk[STARTUP_TASK_STK_SIZE-], STARTUP_TASK_PRIO);
OSStart();
return ;
}

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 *),&task_led1_stk[TASK_LED1_STK_SIZE-], TASK_LED1_PRIO);
OSTaskCreate(RB_Task_led2,(void *),&task_led2_stk[TASK_LED2_STK_SIZE-], TASK_LED2_PRIO);
while()
{
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
}
}
void RB_Task_led1(void *p_arg)
{
(void)p_arg;
while()
{
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
}
} void RB_Task_led2(void *p_arg)
{
(void)p_arg;
while()
{
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
}
}

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以不同频率闪烁了

uC/OS-II 移植笔记

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

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

2015-5-13