STM32STM32STM32STM32移植 uCOS-IIuCOS-IIuCOS-IIuCOS-II
bybybyby lgm:lgm:lgm:lgm: lgm_boy@126.comlgm_boy@126.comlgm_boy@126.comlgm_boy@126.com
1. 准备
MDK-ARM
http://www.keil.com/do
wnload/product/
STM32外设库
http://www.st.com/intern
et/com/SOFTWARE_R
ESOURCES/SW_COM
PONENT/FIRMWARE/
stm32f10x_stdperiph_li
b.zip
uCOS-II源码
http://micrium.com/page
/downloads/ports/st/stm
32
2. 安装MDK,解压外设库和 uCOS-II源码
3. 创建工程目录结构,如下
4. 复制外设库
� STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport 下
的文件 core_cm3.c和 core_cm3.h到工程目录的 CMSIS中
� STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\
ST\STM32F10x下的文件 stm32f10x.h、system_stm32f10x.c和 system_stm32f10x.h
到工程目录的 CMSIS中
� STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\
ST\STM32F10x\startup\arm下的相应文件到工程目录的 CMSIS中,文件名的最
后两位对应相应的芯片,如芯片为 stm32f107vct6,为 Connectivity line型,选择
startup_stm32f10x_cl.s
� STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driv
er下的 inc和 src目录到工程目录的 STM32F10x_StdPeriph_Driver中
� STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Templa
te下的 main.c、stm32f10x_conf.h、stm32f10x_it.c和 stm32f10x_it.h到工程目录的
User中
5. 复制 uCOS-II源码
� 在工程目录的 uCOS-II下建立 Ports和 Source这两个文件夹
� Micrium\Software\uCOS-II\Ports\ARM-Cortex-M3\Generic\RealView 下的
所有文件到新建的 Ports目录下
� Micrium\Software\uCOS-II\Source下的所有文件到新建的 Source下
� Micrium\Software\EvalBoards\ST\STM3210B-EVAL\RVMDK\OS-Probe 下
的 app_cfg.h和 os_cfg.h到工程目录的 User中
6. 打开 Keil,创建新工程,选择器件,注意弹出来的是否添加启动文件的询问
选择否
7. 更改 Target名称,并删除默认的组 Source Group 1,建立如下组结构
8. 为每个组添加文件,如下所示
基本上是添加相应文件夹下的文件,其中有些.h头文件其实没有必要添加,
只是为了在移植过程中方便直接在 Keil里修改,就给一起加上了。
设置 Object到 Obj目录并将 Create HEX File复选框选上
设置 List到 List目录
将以下目录添加到 C/C++的 Include Paths
9. 配置 STM32库,注意其中有些文件被设定为只读,在修改时如遇到不可改
动的文件,先将该文件的只读属性去掉。
� 打开 stm32f10x.h,把#define STM32F10X_CL的注释去掉(根据芯片去
掉对应注释)
� 把#define USE_STDPERIPH_DRIVER的注释去掉
� 打开 system_stm32f10x.c,去掉相应的 SYSCLK_FREQ宏定义的注释
10. 配置 uCOS-II。
� 打开 os_cpu.h,把最后三个函数
void OS_CPU_SysTickHandler(void);
void OS_CPU_SysTickInit(void);
INT32U OS_CPU_SysTickClkFreq(void);
注释掉
� 打开 os_cpu_c.c,把开头的 8个 OS_CPU_CM3_NVIC_ST开头的宏定义
注释掉,把文件里的最后两个函数注释掉
� 打开 startup_stm32f10x_cl.s,用替换功能把所有出现 PendSV_Handler的
地方用 OS_CPU_PendSVHandler替换掉(应该有 3处)
� 打 开 stm32f10x_it.c , 在 开 头 部 分 加 上 #include "ucos_ii.h" , 把
SysTick_Handler函数体改为如下
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
void SysTick_Handler(void)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR */
OSIntNesting++;
OS_EXIT_CRITICAL();
OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */
OSIntExit();
}
� 打开 app_cfg.h,全选删除,并将以下内容复制进去
#ifndef __APP_CFG_H__
#define __APP_CFG_H__
/* task priority */
#define STARTUP_TASK_PRIO 4
#define TASK1_PRIO 5
#define TASK2_PRIO 6
/* task stack size */
#define STARTUP_TASK_STK_SIZE 80
#define TASK1_STK_SIZE 128
#define TASK2_STK_SIZE 128
#endif
� 打开 os_cfg.h,将 OS_APP_HOOKS_EN设置为 0
� 打开 main.c,全选删除,并将以下内容复制进去,具体板级代码需要适
当修改
#include "ucos_ii.h"
#include "stm32f10x.h"
#define LED_0 0
#define LED_1 1
#define LED_2 2
#define LED_3 3
static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE];
static OS_STK task1_stk[TASK1_STK_SIZE];
static OS_STK task2_stk[TASK2_STK_SIZE];
void led_init(void);
void led_on(uint32_t n);
void led_off(uint32_t n);
//static void delay(uint32_t ms);
static void systick_init(void);
static void startup_task(void *p_arg);
static void task1(void *p_arg);
static void task2(void *p_arg);
int main(void)
{
OSInit();
OSTaskCreate(startup_task,
(void *)0,
&startup_task_stk[STARTUP_TASK_STK_SIZE - 1],
STARTUP_TASK_PRIO);
OSStart();
return 0;
}
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 |
GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void led_on(uint32_t n)
{
switch (n)
{
case LED_0:
GPIO_SetBits(GPIOD, GPIO_Pin_2);
break;
case LED_1:
GPIO_SetBits(GPIOD, GPIO_Pin_3);
break;
case LED_2:
GPIO_SetBits(GPIOD, GPIO_Pin_4);
break;
case LED_3:
GPIO_SetBits(GPIOD, GPIO_Pin_7);
break;
default:
break;
}
}
void led_off(uint32_t n)
{
switch (n)
{
case LED_0:
GPIO_ResetBits(GPIOD, GPIO_Pin_2);
break;
case LED_1:
GPIO_ResetBits(GPIOD, GPIO_Pin_3);
break;
case LED_2:
GPIO_ResetBits(GPIOD, GPIO_Pin_4);
break;
case LED_3:
GPIO_ResetBits(GPIOD, GPIO_Pin_7);
break;
default:
break;
}
}
//static void delay(uint32_t ms)
//{
// uint32_t count = 8000;
// while (ms--)
// {
// while (count--);
// count = 8000;
// }
//}
static void systick_init(void)
{
RCC_ClocksTypeDef rcc_clocks;
RCC_GetClocksFreq(&rcc_clocks);
SysTick_Config(rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC);
}
static void startup_task(void *p_arg)
{
systick_init(); /* Initialize the SysTick. */
led_init();
#if (OS_TASK_STAT_EN > 0)
OSStatInit(); /* Determine CPU capacity. */
#endif
/* TODO: create application tasks here */
OSTaskCreate(task1, (void *)0,
&task1_stk[TASK1_STK_SIZE - 1], TASK1_PRIO);
OSTaskCreate(task2, (void *)0,
&task2_stk[TASK2_STK_SIZE - 1], TASK2_PRIO);
OSTaskDel(OS_PRIO_SELF);
}
static void task1(void *p_arg)
{
while (1)
{
led_on(LED_0);
OSTimeDly(200);
led_off(LED_0);
OSTimeDly(200);
}
}
static void task2(void *p_arg)
{
while (1)
{
led_on(LED_1);
OSTimeDly(500);
led_off(LED_1);
OSTimeDly(500);
}
}
11. 编译,调试,下载,运行