本篇目标:从搭建工程开始,一步步在 STM32F407ZGT6 上移植 ucos_ii 操作系统

材料准备:

  • stm32库文件:stm32f4官方库函数文件(stm32f4官网库函数资料)
  • ucos_ii源文件:ucos_ii操作系统官方源代码文件(ucos_ii官网资料)
  • 移植工程:stm32f4移植ucos_II最终工程(stm32f4移植ucos_ii工程)

搭建stm32f4工程

  • 建立如下文件夹,方便整理和拷贝:

  • 解压stm32库函数包,进行文件的拷贝:
    (1)将 STM32F4xx_DSP_StdPeriph_Lib_V1.7.1\Libraries\STM32F4xx_
    StdPeriph_Driver 文件夹下的两个文件夹拷贝到fwlib文件夹;
    (2)将 Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm 文件夹下的 startup_stm32f40_41xxx.s 拷贝到startup文件夹;
    (3)将 Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates 文件夹下的 system_stm32f4xx.c 拷贝到misis文件夹;
    (4)将 Libraries\CMSIS\Device\ST\STM32F4xx\Include 文件夹下的两个文件拷贝到misis文件夹;
    (5)将 Libraries\CMSIS\Include 文件夹下的 core_cm4.h 、core_cmFunc.h 、core_cmInstr.h 、core_cmSimd.h 拷贝到misis文件夹;
    (6)在 Project\STM32F4xx_StdPeriph_Examples 文件夹下随便找一个工程例子,将其中的 main.c 、stm32f4xx_conf.h 、stm32f4xx_it.c 、stm32f4xx_it.h 拷贝到user文件夹;

  • 建立keil工程如图:

  • keil工程修改:
    (1)删除main.c所有内容,只写一个main函数;
    (2)删除stm32f4xx.h中的包含头文件#inlcude”main.h”;
    (3)打开配置工程页面;在output中勾上creat hex file;在C/C++中Define处输入 STM32F40_41xxx,USE_STDPERIPH_DRIVER ;在C/C++中inlucde paths处添加所有头文件的路径,如图;

  • 编译,通过即可;


移植ucos_ii操作系统

  • 在ucos_II文件下建立Ports和Source文件夹

  • 解压ucos_ii源代码文件:
    (1)将 Micrium\Software\uCOS-II\Source 文件夹下的所有文件拷贝到Source文件夹;
    (2)将 Micrium\Software\uCOS-II\Ports\ARM-Cortex-M4\Generic\
    RealView 文件夹下的所有文件拷贝到Ports文件夹;
    (3)将 Micrium\Examples\ST\STM3240G-EVAL\OS2 文件夹下的app_cfg.h 、os_cfg.h拷贝到user文件夹;
    (4)在user文件夹下创建sys_cfg.c 、sys_cfg.h新文件;

  • 将文件添加进keil工程里面如图:

接下来开始修改ucos_ii源码

  • 注释 app_cfg.h中的 #include “cpu.h”和 void App_SerPrintf (CPU_CHAR *format, …);(136-137行)

  • 注释 os_cpu.h 中的 void OS_CPU_SysTickHandler (void); 和 void OS_CPU_
    SysTickInit (INT32U cnts);(185-186行)

  • 打开文件 os_cfg.h ,修改 OS_APP_HOOKS_EN 的定义值为0(30行);修改 OS_TICKS_PER_SEC 的定义值为 1000(51行);修改 OS_MEM_EN 的定义值为1(98行);修改 OS_TMR_EN 的定义值为 1(139行);

  • 打开文件os_cpu_c.c ,注释 #include “lib_def.h”(53行);注释 #if (OS_CPU_ARM_FP_EN == DEF_ENABLED) 与 #endif之间的所有内容(317-354行);注释 OS_CPU_SysTickHandler 整个函数内容(461-473行);注释 OS_CPU_SysTickInit 整个函数内容(488-507行);

  • 打开文件startup_stm32f40_41xxx.s 文件,将所有的 PendSV_Handler 替换成 OS_CPU_PendSVHandler (共3处,替换前需要将文件的只读属性去掉才能够修改文件);

  • 打开stm32f4xx_it.c文件,添加头文件 #include “ucos_ii.h”;找到 SysTick_Handler 函数(146行),添加以下程序:

void SysTick_Handler(void)
{OSIntEnter();OSTimeTick();OSIntExit();
}
  • 打开 sys_cfg.c 和 sys_cfg.h,编写一些函数:

sys_cfg.c:

#include "stm32f4xx.h"
#include "os_cfg.h"
#include "sys_cfg.h"/**** 函数名称 : OS_CPU_SysTickInit();** 函数描述 : 滴答定时器设定;** 传递值   : 无;** 返回值   : 无;***/
void OS_CPU_SysTickInit(void)
{RCC_ClocksTypeDef rcc_clocks;/* 获取系统时钟 */RCC_GetClocksFreq(&rcc_clocks);/* 设置滴答定时器溢出计数值 */SysTick_Config(rcc_clocks.HCLK_Frequency / OS_TICKS_PER_SEC);
}void Sys_Config(void)
{}

sys_cfg.h:

#ifndef  SYS_CFG_H
#define  SYS_CFG_Hvoid OS_CPU_SysTickInit(void);
void Sys_Config(void);#endif

至此为止,ucos_ii的源码修改结束,接下来就是ucos_ii初始化和任务的创建;


ucos_ii初始化

  • 修改main.c文件,添加相关头文件,添加任务相关宏定义,修改main函数如下:
#include "app_cfg.h"
#include "sys_cfg.h"
#include "ucos_ii.h"
#include "task_start.h"#define  APP_TASK_START_PRIO                     10u
#define  APP_TASK_START_STK_SIZE                128ustatic OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE];int main(void)
{/* stm32系统初始化配置 */Sys_Config();/* ucos_ii初始化 */OSInit();/* 创建ucos_ii初始化任务 TASK_START */OSTaskCreateExt(APP_TASK_START,(void    *)0,(OS_STK  *)&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],(INT8U    )APP_TASK_START_PRIO,(INT16U   )APP_TASK_START_PRIO,(OS_STK  *)&App_TaskStartStk[0],(INT32U   )APP_TASK_START_STK_SIZE,(void    *)0,(INT16U)(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));/* 开始 ucos_ii */                            OSStart();return 0;
}
  • 在task文件夹下创建文件 task_start.c 和 task_start.h,并添加进keil工程,打开文件添加头文件,宏定义,以及初始任务:

task_start.c:

#include "app_cfg.h"
#include "sys_cfg.h"
#include "ucos_ii.h"
#include "stm32f4xx.h"
#include "task_led.h"#define  APP_TASK_USER_GREEN_PRIO     6u
#define  APP_TASK_USER_RED_PRIO       8u
#define  APP_TASK_USER_STK_SIZE       128ustatic OS_STK   App_TaskGreenStk[APP_TASK_USER_STK_SIZE];
static OS_STK   App_TaskRedStk[APP_TASK_USER_STK_SIZE];static void APP_TASK_GREEN (void *p_arg);
static void APP_TASK_RED   (void *p_arg);/**** 函数名称 : APP_TASK_START();** 函数描述 : ucos_ii 初始化任务;** 传递值   : 无;** 返回值   : 无;***/
void APP_TASK_START(void *p_arg)
{ OS_CPU_SR cpu_sr;(void)p_arg;/* 配置滴答定时器,此函数调用位置为第一个创建任务开头 */OS_CPU_SysTickInit();/* 关中断 */                   OS_ENTER_CRITICAL();/* 创建绿灯任务 */                 OSTaskCreateExt(APP_TASK_GREEN,(void    *)0,(OS_STK *)&App_TaskGreenStk[APP_TASK_USER_STK_SIZE - 1],(INT8U   )APP_TASK_USER_GREEN_PRIO,(INT16U  )APP_TASK_USER_GREEN_PRIO,(OS_STK *)&App_TaskGreenStk[0],(INT32U  )APP_TASK_USER_STK_SIZE,(void   *)0,(INT16U  )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));/* 创建红灯任务 */               OSTaskCreateExt(APP_TASK_RED,(void   *)0,(OS_STK *)&App_TaskRedStk[APP_TASK_USER_STK_SIZE - 1],(INT8U   )APP_TASK_USER_RED_PRIO,(INT16U  )APP_TASK_USER_RED_PRIO,(OS_STK *)&App_TaskRedStk[0],(INT32U  )APP_TASK_USER_STK_SIZE,(void   *)0,(INT16U  )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));/* 删除任务自身 */               OSTaskDel(OS_PRIO_SELF);/* 关中断 */OS_EXIT_CRITICAL();
}

task_start.h:

#ifndef  TASK_START_H
#define  TASK_START_Hvoid APP_TASK_START(void *p_arg);#endif

ucos_ii建立用户任务

  • 首先需要初始化stm32的GPIO口,在sys_cfg.c中修改和添加下列函数:
/**** 函数名称 : GPIO_Configuration();** 函数描述 : GPIO初始化配置;** 传递值   : 无;** 返回值   : 无;***/
static void GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_Init(GPIOG, &GPIO_InitStructure);/* 关闭所有灯 */GPIO_ResetBits(GPIOD,GPIO_Pin_7);GPIO_ResetBits(GPIOG,GPIO_Pin_9);
}/**** 函数名称 : Sys_Config();** 函数描述 : 系统初始化配置;** 传递值    : 无;** 返回值   : 无;***/
void Sys_Config(void)
{/* 配置GPIO口 */GPIO_Configuration();
}
  • 在task文件夹下创建文件 task_led.c 和 task_led.h,并添加进keil工程,打开文件添加led任务函数:

task_led.c:

#include "stm32f4xx.h"
#include "ucos_ii.h"#define LED_RED_OFF     GPIO_ResetBits(GPIOD,GPIO_Pin_7);
#define LED_RED_ON      GPIO_SetBits(GPIOD,GPIO_Pin_7);#define LED_GREEN_OFF   GPIO_ResetBits(GPIOG,GPIO_Pin_9);
#define LED_GREEN_ON    GPIO_SetBits(GPIOG,GPIO_Pin_9);/**** 函数名称 : APP_TASK_GREEN();** 函数描述 : 绿灯任务;** 传递值   : 无;** 返回值   : 无;***/
void APP_TASK_GREEN(void *p_arg)
{for (;;){/* 红灯亮 */LED_GREEN_ON;/* 延时0.5s,并任务切换 */OSTimeDly(500);/* 红灯灭 */LED_GREEN_OFF;/* 延时0.5s,并任务切换 */OSTimeDly(500);}
}/**** 函数名称 : APP_TASK_RED();** 函数描述 : 红灯任务;** 传递值   : 无;** 返回值   : 无;***/
void APP_TASK_RED(void *p_arg)
{for (;;){/* 红灯亮 */LED_RED_ON;/* 延时0.25s,并任务切换 */OSTimeDly(250);/* 红灯灭 */LED_RED_OFF;/* 延时0.25s,并任务切换 */OSTimeDly(250);}
}

task_led.h:

#ifndef  TASK_LED_H
#define  TASK_LED_Hvoid APP_TASK_GREEN (void *p_arg);
void APP_TASK_RED   (void *p_arg);#endif

至此,移植工作全部完成,编译,下载;成功后会发现两个led闪烁,就相当于两个led灯的任务相互交替进行,互不影响;

小结:每个裸板移植 ucos_ii 方法都是想通的,整理觉得移植ucos_ii比较重要的几个点:

  1. 滴答定时器的配置,包括滴答定时器的初始化配置其计数值,以及滴答定时器溢出中断中函数的调用;
  2. 任务调度,在每个创建的任务中必须使用延时函数、挂起函数或者删除函数,才能使多个任务进行相互切换,调用的以上函数最终都会调用用汇编写的任务切换函数 OSCtxSw() ,所以任务切换相关代码也是重要的一部分;

总结:从移植 ucos_ii 到移植 lwip 经过了很漫长的过程,终于也算移植成功了,所以先写了对 ucos_ii 的移植,之后再在此基础上再写 lwip 的移植,共勉

STM32F4移植ucos_II相关推荐

  1. 基于STM32F4移植W5500官方驱动库ioLibrary_Driver(转)

    源: 基于STM32F4移植W5500官方驱动库ioLibrary_Driver 参考: 基于STM32+W5500 的Ethernet和Internet移植 Upgrade W5500 Throug ...

  2. STM32F4移植官方DSP

    目录 库文件下载 1.Cube软件包提取 2.MDK安装目录内提取(以5.7.0版本为例) 3.官网下载 4.Github 文件内容说明 ​编辑 工程移植(以正点原子工程模板为例) 库文件下载 1.C ...

  3. STM32F4移植MLX90614(I2C)

    一.MLX90614简介 迈来芯 MLX90614 是一款用于非接触式温度测量的红外温度计.IR 敏感型热电堆检测器芯片和信号调节 ASIC 都集成在同一 TO-39 罐封装中.MLX90614 集成 ...

  4. STM32F4移植EMWIN(RA8875驱动显示屏)

    在网上找了众多资料后,终于根据正点原子和F4 EMWIN移植文档和网上的一个例程资料,在F4上成功移植了EMWIN. 一开始步骤和正点原子都一样,只是因为显示屏的驱动芯片不同,在GUIDRV_Temp ...

  5. STM32F4移植STemWin

    目录 一.STemWin的文件结构 二.STemWin的移植步骤 三.STemWin的LCD驱动移植 四.STemWin的触摸屏驱动移植 五.补充 STM32芯片为:STM32F407VGT6 STe ...

  6. STM32F4移植FreeRTOS V10.3.1

                                                                            STM32F429移植FreeRTOS 一.环境 Win ...

  7. STM32F4基础工程移植FreeRTOS

    本篇目标:基于上一篇的基础工程(stm32f4_first_demo)上,移植freertos,建立移植工程(stm32f4_freertos). 资料准备: Freertos源文件 最后工程:项目工 ...

  8. MPU6050(读取原数据、移植DMP、stm32f4、HAL库、KEIL5)

    记录一下自己遇到的问题及解决方法,希望能帮助到一些人. 第一步,读取芯片的原始数据.需要注意两点:1.对HAL库提供的IIC读取写入函数进行再包装.(千万不要觉的这步多此一举,后面移植DMP时用得到) ...

  9. STM32驱动代码:STM32F4驱动7针0.96寸OLED显示字符、汉字

    STM32F4驱动7针0.96寸OLED显示字符.汉字 适用于stm32f1.stm32f4移植 工程资料链接:STM32F4驱动7针0.96寸OLED.rar 一. 代码效果 二.硬件准备 1.准备 ...

  10. STM32的音频编码与在PC端的解码

    STM32的音频编码与在PC端的解码 简介 STM32F4移植 编码 PC移植 解码 结尾 简介 能看到这篇文章的基本上都是有迫切需求的人,话不多说,切入正题 编解码库:Speex 编码硬件平台:ST ...

最新文章

  1. 访问地址指向本机地址_详解MySql通过ip地址进行访问的方法
  2. Appium查找元素
  3. springcloud gateway 源码解析、请求响应流程、第三方响应结果在 gateway 的经过
  4. 怎样高效实现增长?这里有50个经典的增长黑客策略
  5. 吴恩达深度学习4.4练习_Convolutional Neural Networks_Art Generation with Neural Style Transfer
  6. LeetCode 96——不同的二叉搜索树
  7. plc 上位机编译算法_基于西门子PLC的Socket通信深度剖析
  8. pygame安装教程(小白入手)
  9. 破局:技术视野与规划
  10. 阿里P8大牛匠心独运,用图解的方式让繁杂的计算机网络一目了然
  11. macbook配置java环境变量_Mac配置JDK环境变量的详细操作
  12. 永恒之蓝实验 MS17-010
  13. Python爬虫三:抓取链家已成交二手房信息(58W数据)
  14. 【像素与浏览器视口的细节】及移动web设置“width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no“原因
  15. 解决 WebStorm 很卡的问题
  16. 芒德布罗集matlab程序,分形、噪声和状态变量
  17. MATLAB求多项式系数及次数
  18. python文件处理练习14
  19. 一部适合有一点点lingo编程基础的人阅读的lingo入门教程——重学lingo,发现很多遗忘的小知识,并将其整理成册——运算符、数学函数、金融函数、概率密度函数、变量定界与集操作函数
  20. 02 windows网络安全

热门文章

  1. java怎么导包_java包与导包
  2. RTOS系列文章(5):C语言程序运行原理分析:汇编、栈、栈帧、进栈、出栈、保存现场、恢复现场、返回
  3. ddns文件服务器,DDNS基础配置
  4. Sublime text 3 安装使用 Theme Boxy
  5. SQL基础系列(八)——排序、分组排序(RANK)
  6. 和平精英为什么服务器显示错误,和平精英为什么会出现错误代码5567?_和平精英错误代码5567解决步骤一览...
  7. 谷歌浏览器86版_Google 谷歌浏览器 Chrome v87.0.4280.66 Win Mac Linux 安卓等稳定版
  8. csp是什么比赛_CSP-J/S认证 NOIP、NOI信息学竞赛解读!
  9. [python-opencv]滑动验证码打码
  10. 给博客添加能动的看板娘