企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
  μC/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器,微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中)。同时,该系统源代码开放、整洁、一致,注释详尽,适合系统开发。 μC/OS-II已经通过联邦航空局(FAA)商用航行器认证,符合航空无线电技术委员会(RTCA)DO-178B标准。 **——摘自百度百科** 经过三天对uC/OS-II的研究和琢磨,成功移植了自己的uC/OS-II;回首看下,简单的移植是非常简单的;可能这句话比较啰嗦,等我下面解析完之后就认同了; 首先,来附图,我相信只要刚刚认识ucosii的人,都见过这种类型的图了;而且版本不一; ![](https://box.kancloud.cn/2016-06-21_576915bd44008.jpg) 这个是摘自一个教程上面的,但是我觉得还是有点复杂,然后,我又仔细的精简了框架和代码;当然只适合初学者; ![](https://box.kancloud.cn/2016-06-21_576915bd692c1.jpg) 可能有人还不知道什么是BSP,Board Support Package,板级支持包;这样的话,一看我们的代码就可以分为四部分了; 为了有点逻辑,我从uC/OS-II Source开始说起;这部分代码大家都知道是不用修改的,但是我们至少要知道他依赖的外部头文件都有哪些; ### Step one: +------------------------------------------ |core:os_core.c |  os:os_flag.c    os_mbox.c |  os_mem.c     os_mutex.c |  os_q.c       os_sem.c |  os_task.c    os_time.c |      os_tmr.c |head:ucos_ii.h +------------------------------------------ 理论上这几个文件我们完全不用修改!但是,他依赖外部的一些头文件; app_cfg.h//应用程序的一些功能,目测这里是不需要的;但是他已经写了,那我们就保留吧;所以我们就要先建立一个空的app_cfg.h文件 os_cfg.h//做一些os功能的开关,我们可以由此来对系统进行一些裁剪;保留我们需要的功能; os_cpu.h//为了适应os,我们必须把os与cpu之间建立一个桥梁;就是通过os_port来进行建立的; ### step two: **os_ports**在uCOS-II\Ports\ARM-Cortex-M3\Generic\IAR os_cpu_c.c//有两个地方要说下:1:在stm32的启动代码里面已经有一些功能函数了,所以我们要把他进行删除,以及他所附带的函数;并在os_cpu.h中注释点他们的外部声明;2:部分宏定义也删除了; ~~~ #if 0 #define  OS_CPU_CM3_NVIC_ST_CTRL    (*((volatile INT32U *)0xE000E010uL)) /* SysTick Ctrl & Status Reg. */ #define  OS_CPU_CM3_NVIC_ST_RELOAD  (*((volatile INT32U *)0xE000E014uL)) /* SysTick Reload  Value Reg. */ #define  OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018uL)) /* SysTick Current Value Reg. */ #define  OS_CPU_CM3_NVIC_ST_CAL     (*((volatile INT32U *)0xE000E01CuL)) /* SysTick Cal     Value Reg. */ #define  OS_CPU_CM3_NVIC_PRIO_ST    (*((volatile INT8U  *)0xE000ED23uL)) /* SysTick Handler Prio  Reg. */ #define  OS_CPU_CM3_NVIC_ST_CTRL_COUNT                    0x00010000uL   /* Count flag.                */ #define  OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC                  0x00000004uL   /* Clock Source.              */ #define  OS_CPU_CM3_NVIC_ST_CTRL_INTEN                    0x00000002uL   /* Interrupt enable.          */ #define  OS_CPU_CM3_NVIC_ST_CTRL_ENABLE                   0x00000001uL   /* Counter mode.              */ #define  OS_CPU_CM3_NVIC_PRIO_MIN                               0xFFu    /* Min handler prio.          */ #endif #if 0 void  OS_CPU_SysTickHandler (void) void  OS_CPU_SysTickInit (INT32U  cnts) #endif ~~~ os_cpu.h 同样把下面几个外部声明的函数给去掉; ~~~ #if 0                                                 /* See OS_CPU_C.C                                    */ void       OS_CPU_SysTickHandler(void); void       OS_CPU_SysTickInit(void);                                                 /* See BSP.C                                         */ INT32U     OS_CPU_SysTickClkFreq(void); #endif ~~~ os_cpu_a.asm 这部分是汇编代码;由于他里面有部分指令集不适合stm32,所以我们要稍微改下: 1、将所有的PUBLIC 改为 EXPORT 2、把自己对齐部分也改下,也是因为指令集不匹配; ;       RSEG CODE:CODE:NOROOT(2) AREA |.text|, CODE, READONLY, ALIGN=2 THUMB REQUIRE8 PRESERVE8 注:AREA 一点不能顶头写,这是规定,不然回编译出错; os_dbg.c `#define OS_COMPILER_OPT __root ` 这个不兼容,需要把它改下; ~~~ #define OS_COMPILER_OPT //__root ~~~ ### step three: 将ST的官方库导进去即可; ### step four: startup_stm32f10x_hd.s 将 PendSV_Handler 替换成 OS_CPU_PendSVHandler stm32f10x_it.c 加头文件: ucos_ii.h,并添加如下代码: ~~~ /** * @brief  This function handles SysTick Handler. * @param  None * @retval None */ void SysTick_Handler(void) { OSIntEnter(); OSTimeTick(); OSIntExit(); } ~~~ os_cfg.h对部分功能进行剪裁; ~~~ #define OS_FLAG_EN0 #define OS_MBOX_EN 0 #define OS_MEM_EN 0 #define OS_MUTEX_EN 0 #define OS_Q_EN 0 #define OS_SEM_EN 0 #define OS_TMR_EN 0 #define OS_DEBUG_EN 0 #define OS_APP_HOOKS_EN 0 #define OS_EVENT_MULTI_EN 0 ~~~ 这样算是简单系统以及移植完成了,下面就是写自己的app了;我直接附上自己的main.c代码; main.c ~~~ #include "stm32f10x.h" #include "stm32f10x_conf.h" #include "ucos_ii.h" #define ON 1 #define OFF 0 #define LED1(opt) ((opt) ? (GPIOD->BRR |= 1<<3):(GPIOD->BSRR |= 1<<3)) #define LED2(opt) ((opt) ? (GPIOD->BRR |= 1<<6):(GPIOD->BSRR |= 1<<6)) #define LED3(opt) ((opt) ? (GPIOB->BRR |= 1<<5):(GPIOB->BSRR |= 1<<5)) #define SystemFrequency 72000000 #define STARTUP_TASK_PRIO 4 #define STARTUP_TASK_STK_SIZE 80 void SysTick_init(void) { SysTick_Config(SystemFrequency/OS_TICKS_PER_SEC); } void LED_Init() { RCC->APB2ENR |= (1<<3)|(1<<5); GPIOB->CRL &= ~(0xff<<20); GPIOB->CRL |= 0x33<<(4*5); GPIOD->CRL &= ~(0xff<<(4*3)); GPIOD->CRL &= ~(u32)((u32)0xff<<(4*6)); GPIOD->CRL |= 0x33<<(4*3); GPIOD->CRL |= 0x33<<(4*6); LED1(OFF); LED2(OFF); LED3(OFF); } void TestLed1(void *p_arg) { SysTick_init(); while(1) { LED1(ON); OSTimeDlyHMSM(0,0,1,0); LED1(OFF); OSTimeDlyHMSM(0,0,1,0); } } void TestLed2(void *p_arg) { SysTick_init(); while(1) { LED2(ON); OSTimeDlyHMSM(0,0,0,500); LED2(OFF); OSTimeDlyHMSM(0,0,0,500); } } void TestLed3(void *p_arg) { SysTick_init(); while(1) { LED3(ON); OSTimeDlyHMSM(0,0,0,100); LED3(OFF); OSTimeDlyHMSM(0,0,0,100); } } static OS_STK task_testled1[STARTUP_TASK_STK_SIZE]; static OS_STK task_testled2[STARTUP_TASK_STK_SIZE]; static OS_STK task_testled3[STARTUP_TASK_STK_SIZE]; int main() { LED_Init(); OSInit(); OSTaskCreate(TestLed1,(void *)0,&task_testled1[STARTUP_TASK_STK_SIZE-1],STARTUP_TASK_PRIO); OSTaskCreate(TestLed2,(void *)0,&task_testled2[STARTUP_TASK_STK_SIZE-1],STARTUP_TASK_PRIO-1); OSTaskCreate(TestLed3,(void *)0,&task_testled3[STARTUP_TASK_STK_SIZE-1],STARTUP_TASK_PRIO-2); OSStart(); return 0; } ~~~ OK,到此为止,已经移植完成;我们就可以测试下;希望大家多多指教;后期继续深入学习ucosii的其他功能;