写在前面:
推荐参考此链接:http://blog.csdn.net/ybhuangfugui/article/details/51760171
我也是参考上面的链接还有一些云课堂的视频进行学习,十分清晰,感谢给我带来知识的老师们。
本篇我移植成功的工程:http://download.csdn.net/download/lo_heng/10219630
------------------------------------------------------------------------手工分割线------------------------------------------------------------------------
原理本篇不再说明,可以自行查找资料,或者我日后经过深入研究过后更新。
1.移植信息
目标板:STM32F105VC
编译器:keil5
系统:ucos-II
2. 移植前准备
2.1下载和准备空的工程项目
①推荐直接下载这个STM32F107的官方移植工程https://www.micrium.com/download/micrium_stm32f107_ucos-ii
也可以到我分享的资源找,上链接http://download.csdn.net/download/lo_heng/10219705
②空的工程项目或者是简单的工程项目(写好可以成功烧录的)
2.2 我们需要从下载的官方工程中,挖出一些文件
从..\Micrium_uC-Eval-STM32F107_uCOS-II\Micrium\Software\目录中的ucos-II文件夹复制到你的项目底下
将..\\uCOS-II\Ports\ARM-Cortex-M3\Generic\RealView中的文件挖出来,其他不要了,最后ports里面是这样
将..\Micrium_uC-Eval-STM32F107_uCOS-II\Micrium\Software\EvalBoards\Micrium\uC-Eval-STM32F107\uCOS-II里面的文件os_config.h取出来放到自己项目下\uCOS-II\Config里面(config文件要自己新建)
最后请把这些导入项目,你的项目最终样子应该是这样(主要看Ports 和 Source)2.3 加入头文件(这个应该都懂,不多说了)
3.进行移植
3.1 修改os_cfg.h和ucos_ii.h
#define OS_DEBUG_EN 0
编译一下
然后他会告诉你.\uCOS-II\Source\ucos_ii.h(44): error: #5: cannot open source input file "app_cfg.h": No such file or directory
这样意思是找不到这个文件,你可以:①在ucos_ii.h里面把#include "app_cfg.h"注释了②可以新建一个app_cfg.h 这个是给用户定义的一个头文件
为了简单快捷我选用①方案在ucos_ii.h里面把#include "app_cfg.h"注释了
又编译一下
uCOS-II\Source\os_tmr.c(899): error: #20:identifier "OS_TASK_TMR_PRIO" is undefined
意思是,OS_TASK_TMR_PRIO未定义,因为暂时用不到,先关了,前往os_cfg.h找到以下语句,设为0
#define OS_TMR_EN 0
再编译一下
这次错的有点多,不过都是一个的问题,同上找到下面的语句,关掉
#define OS_APP_HOOKS_EN 0
以上终于把编译的错误改了,接下来才是重头戏。
3.2 修改关键文件(真正移植)
如图找到PendSV_Handler,改为下图,因为我们用的调度函数是ucos的调度函数。
同时注释原本的函数(在启动文件内)
最后更改stm32f10x_it.c如图,记得加上#include "os_cpu.h"
4.写Main函数与调试
- 请自行修改led的程序,最好是在上系统之前调试好led程序然后套用这个模板
#include "stm32f10x.h" #include "ucos_ii.h" #include "os_cpu.h" void LED_Init(void); void Task_LED(void *p); void OSTick_Init(void); //设置任务优先级 #define LED_TASK_PRIO 6 //设置任务堆栈大小 #define LED_STK_SIZE 64 //任务堆栈 OS_STK LED_TASK_STK[LED_STK_SIZE]; int main() { //LED灯的初始化 LED_Init(); //系统初始化 OSInit(); //初始化系统时钟 SysTick_Config(SystemCoreClock /1000); //新建任务LED OSTaskCreate(Task_LED,(void *) 0, (OS_STK *)&LED_TASK_STK[LED_STK_SIZE-1], (u8)LED_TASK_PRIO); //启动 OSStart(); return 0; } void OSTick_Init(void) { } void Task_LED(void *p) { p = p; while(1) { GPIO_SetBits(GPIOC,GPIO_Pin_5); OSTimeDly(100); GPIO_ResetBits(GPIOC,GPIO_Pin_5); OSTimeDly(100); } } void LED_Init() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); /* Configure PD0 and PD2 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); }
- 接下来测试任务调度是否成功
#include "stm32f10x.h" #include "ucos_ii.h" #include "os_cpu.h" void LED_Init(void); void Task_LED(void *p); void OSTick_Init(void); void Task_LED2(void *p); //设置任务优先级 #define LED_TASK_PRIO 6 #define LED2_TASK_PRIO 5 //设置任务堆栈大小 #define LED_STK_SIZE 64 //任务堆栈 OS_STK LED_TASK_STK[LED_STK_SIZE]; OS_STK LED2_TASK_STK[LED_STK_SIZE]; int main() { //LED灯的初始化 LED_Init(); //系统初始化 OSInit(); //初始化系统时钟 SysTick_Config(SystemCoreClock /1000); //新建任务LED1 OSTaskCreate(Task_LED,(void *) 0, (OS_STK *)&LED_TASK_STK[LED_STK_SIZE-1], (u8)LED_TASK_PRIO); //新建任务LED2 OSTaskCreate(Task_LED2,(void *) 0, (OS_STK *)&LED2_TASK_STK[LED_STK_SIZE-1], (u8)LED2_TASK_PRIO); //启动 OSStart(); return 0; } void OSTick_Init(void) { } void Task_LED(void *p) { p = p; while(1) { GPIO_SetBits(GPIOC,GPIO_Pin_5); OSTimeDly(100); GPIO_ResetBits(GPIOC,GPIO_Pin_5); OSTimeDly(100); } } void Task_LED2(void *p) { p = p; while(1) { GPIO_SetBits(GPIOC,GPIO_Pin_4); OSTimeDly(500); GPIO_ResetBits(GPIOC,GPIO_Pin_4); OSTimeDly(500); } } void LED_Init() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); /* Configure PD0 and PD2 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); }如果看到效果是,一盏灯闪烁快,一盏灯闪烁慢,那么恭喜你,移植成功!否则请检查PendSV_Handler函数是否正确