一、实验要求
1.学习嵌入式实时操作系统(RTOS),以uc/OS-III为例,将其移植到stm32F103上,构建至少3个任务(task):其中两个task分别以1s和3s周期对LED等进行点亮-熄灭的控制;另外一个task以2s周期通过串口发送“hello uc/OS! 欢迎来到RTOS多任务环境!”。记录详细的移植过程。
2.在上述实验中,在掌握Keil的仿真调试代码功能之外,也学习使用仪器对代码运行进行故障排查和功能调测。
(1)练习使用示波器去观察LED输出电平和串口通信的波形,分析故障;
(2)分别使用Keil虚拟仿真逻辑仪和真实逻辑仪(SaleaeLogic16)抓取LED输出电平和串口通信的波形,进行协议分析。
二、实验过程及结果
(一)移植uc/OS-III
1. 下载uC/OS-III源码
官网下载:http://micrium.com/downloadcenter/
云盘下载:https://pan.baidu.com/s/1Btj7foEXdXjjJWoZQsN-OQ 提取码:mleh
2. 建立STM32HAL库
选择STM32F103C8
芯片,修改RCC
中的HSE
为Crystal/Ceramic Resonator
点击System Core
中的SYS
,在Debug
处选择Serial Wire
选择串口USART1
,点击Mode
,选择Asynchronous
设置引脚PA1
、PB15
为GPIO_Output
点击Clock Configuration
,选择HSE
和PLLCLK
,设置HCLK
为72MHz
设置项目名称和路径,修改Toolchain/IDE
为MDK-ARM
,在Code Generator
中勾选
3. 复制uC/OS-III文件
在生成的keil工程文件夹中新建一个uCOS
文件夹
将下载源文件下的uC-CPU
、uC-LIB
、uCOS-III
复制到此
在Core
中的Src
文件夹下新建一个OS
文件夹
将Micrium\Software\EvalBoards\Micrium\uC-Eval-STM32F107\uCOS-III
下的app.c
、 app_cfg.h
、 cpu_cfg.h
、 includes.h
、 lib_cfg.h
、 os_app_hooks.c
、os_app_hook.h
、os_cfg.h
、os_cfg_app.h
文件复制到OS文件夹
在OS
文件夹中新建三个空白文件 bsp.c
、bsp.h
、app.h
4. 添加工程组件及路径
打开工程, 添加六个新组:bsp
、uCOSIII_CPU
、uCOSIII_LIB
、uCOSIII_Ports
、uCOSIII_Source
、OS_cfg
将app.c
添加进Application/User/Core
组,将Core/Src/OS
中的bsp.c
、bsp.h
添加进bsp
组
将uCOS/uC-CPU
中的cpu_core.c
、cpu_core.h
、cpu_def.h
和uCOS/uC-CPU/ARM-Cortex-M3/RealView
中的cpu.h
、cpu_c.c
、cpu_a.asm
添加进uCOSIII_CPU
组
将uCOS/uC-LIB
中的9个文件和uCOS/uC-LIB/Ports/ARM-Cortex-M3/Realview
中的lib_mem_a.asm
添加到uCOSIII-LIB
组
将uCOS/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView
中的3个文件添加到uCOSIII_Ports
组
将uCOS/ucos-III/Source
中的20个文件添加到uCOSIII_Source
组
将Core/Src/OS
中的8个文件添加到OS_cfg
组
点击魔法棒
,选择C/C++
添加文件路径
点击魔法棒
,选择Target
配置相关参数
5. 修改文件内容
(1)startup_stm32f103xb.s启动文件
PendSV_Handler -> OS_CPU_PendSVHandler
Systick_Handler -> OS_CPU_SysTickHandler
(2)app_cfg.h头文件
//修改前
#define APP_CFG_SERIAL_EN DEF_ENABLED
#define APP_TRACE BSP_Ser_Printf
//修改后
#define APP_CFG_SERIAL_EN DEF_DISABLED
#define APP_TRACE (void)
(3)includes.h头文件
//添加相关头文件
#include "gpio.h"
#include "app_cfg.h"
#include "app.h"
//添加HAL库
#include <stm32f10x_lib.h>//修改前
#include "stm32f1xx_hal.h"//修改后
(4)bsp.c、bsp.h文件
bsp.c
// bsp.c
#include "includes.h"
#define DWT_CR *(CPU_REG32 *)0xE0001000
#define DWT_CYCCNT *(CPU_REG32 *)0xE0001004
#define DEM_CR *(CPU_REG32 *)0xE000EDFC
#define DBGMCU_CR *(CPU_REG32 *)0xE0042004
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
CPU_INT32U BSP_CPU_ClkFreq (void)
{
return HAL_RCC_GetHCLKFreq();
}
void BSP_Tick_Init(void)
{
CPU_INT32U cpu_clk_freq;
CPU_INT32U cnts;
cpu_clk_freq = BSP_CPU_ClkFreq();
#if(OS_VERSION>=3000u)
cnts = cpu_clk_freq/(CPU_INT32U)OSCfg_TickRate_Hz;
#else
cnts = cpu_clk_freq/(CPU_INT32U)OS_TICKS_PER_SEC;
#endif
OS_CPU_SysTickInit(cnts);
}
void BSP_Init(void)
{
BSP_Tick_Init();
MX_GPIO_Init();
}
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void CPU_TS_TmrInit (void)
{
CPU_INT32U cpu_clk_freq_hz;
DEM_CR |= (CPU_INT32U)DEM_CR_TRCENA; /* Enable Cortex-M3's DWT CYCCNT reg. */
DWT_CYCCNT = (CPU_INT32U)0u;
DWT_CR |= (CPU_INT32U)DWT_CR_CYCCNTENA;
cpu_clk_freq_hz = BSP_CPU_ClkFreq();
CPU_TS_TmrFreqSet(cpu_clk_freq_hz);
}