写在前面:
推荐参考此链接:http://blog.csdn.net/ybhuangfugui/article/details/51760171
我也是参考上面的链接还有一些云课堂的视频进行学习,十分清晰,感谢给我带来知识的老师们。
本篇我移植成功的工程:http://download.csdn.net/download/lo_heng/10219630
------------------------------------------------------------------------手工分割线------------------------------------------------------------------------
原理本篇不再说明,可以自行查找资料,或者我日后经过深入研究过后更新。
1.移植信息
目标板:STM32F105VC
编译器:keil5
系统:ucos-II
2.1下载和准备空的工程项目
①推荐直接下载这个STM32F107的官方移植工程https://www.micrium.com/download/micrium_stm32f107_ucos-ii
也可以到我分享的资源找,上链接http://download.csdn.net/download/lo_heng/10219705
②空的工程项目或者是简单的工程项目(写好可以成功烧录的)
2.2 我们需要从下载的官方工程中,挖出一些文件
将..\\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)
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
以上终于把编译的错误改了,接下来才是重头戏。
如图找到PendSV_Handler,改为下图,因为我们用的调度函数是ucos的调度函数。
同时注释原本的函数(在启动文件内)
最后更改stm32f10x_it.c如图,记得加上#include "os_cpu.h"
#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函数是否正确