一、用CubeMX创建HAL库工程
二、准备UCOS-III源码
1、源码下载
2、源码修改
三、移植源码到HAL库工程上
1、复制文件夹到HAL库工程
2、在工程里添加文件与文件路径
3、修改文件
4、修改配置
5、修改代码
6、移植成功成果
四、注意事项
一、用CubeMX创建HAL库工程
- 创建项目
- 配置RCC
- 配置SYS
- 配置串口以方便调试
- 配置时钟树
- 配置工程名字与存放路径
- 工程文件配置
二、准备UCOS-III源码
1、源码下载
- 下载路径:https://pan.baidu.com/s/1ILWVoganFXihwkg7SltpeQ 提取码: 1111
2、源码修改
- 打开源码,在Micrium---Software文件夹里新增两个文件夹
- 在uCOS-III-BSP文件夹里增加bsp.c与bsp.h两个文件
- 在bsp.c添加如下代码
// bsp.c
#include "includes.h"
#include "main.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);
}
#endif
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR CPU_TS_TmrRd (void)
{
return ((CPU_TS_TMR)DWT_CYCCNT);
}
#endif
#if (CPU_CFG_TS_32_EN == DEF_ENABLED)
CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts)
{
CPU_INT64U ts_us;
CPU_INT64U fclk_freq;
fclk_freq = BSP_CPU_ClkFreq();
ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);
return (ts_us);
}
#endif
#if (CPU_CFG_TS_64_EN == DEF_ENABLED)
CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts)
{
CPU_INT64U ts_us;
CPU_INT64U fclk_freq;
fclk_freq = BSP_CPU_ClkFreq();
ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);
return (ts_us);
}
#endif
- 在bsp.h文件添加如下代码
// bsp.h
#ifndef __BSP_H__
#define __BSP_H__
#include "stm32f1xx_hal.h"
void BSP_Init(void);
#endif
- 在uCOS-III-CONFIG文件夹中添加如下代码
在源码以下路径复制
复制粘贴到uCOS-III-CONFIG文件夹
三、移植源码到HAL库工程上
1、复制文件夹到HAL库工程
2、在工程里添加文件与文件所在路径
- 在keil里新建以下分组
- 把工程里uCOS-III-CPU的三个文件与uCOS-III-CPU\ARM-Cortex-M3\RealView的三个文件添加到ucos-iii-Cpu分组里
- 把工程里uCOS-III-LIB的九个文件与uCOS-III-LIB\Ports\ARM-Cortex-M3\RealView 里面的 lib_mem_a.asm 文件的三个文件添加到ucos-iii-Lib分组里
- 把工程里uCOS-III-BSP的两个文件添加到ucos-iii-Bsp分组里
- 把工程里uCOS-III-CONFIG的八个文件添加到ucos-iii-Config分组里
- 把工程里的uCOS-III\Ports\ARM-Cortex-M3\Generic\RealView 里面的 三个文件添加到ucos-iii-Port分组里
- 把工程里的uCOS-III\Source里的全部文件添加到ucos-iii-Source分组里
- 添加文件所在路径
3、修改文件
- 把startup_stm32f103xb.s 文件下的两处PendSV_Handler和Systick_Handler改为OS_CPU_PendSVHandler和OS_CPU_SysTickHandler
- 注释掉stm32f1xx_it.c的PendSV_Handler与SysTick_Handler函数
- app_cfg.h里的#define APP_CFG_SERIAL_EN DEF_ENABLED 改为 #define APP_CFG_SERIAL_EN DEF_DISABLED、#define APP_TRACE BSP_Ser_Printf 改为 #define APP_TRACE (void)
- 在include是.h文件上#include <bsp.h> 后面加上#include <stm32f1xx_hal_gpio.h>
#include "app_cfg.h",将#include <stm32f10x_lib.h> 改为 #include <stm32f1xx_hal.h>
- 将lib_cfg.h的以下此处修改为5(由于RAM空间有限, 需要改小堆的大小)
4、修改配置
5、修改代码
- 串口重定义
uint8_t transmit_data_buffer;
int fputc(int c, FILE * f)
{
transmit_data_buffer = c;
HAL_UART_Transmit(&huart1,&transmit_data_buffer,1,1000);
return c;
}
- main函数
UCOS_III_Start();
while(1)
{
printf("task created is fail or error\r\n");
}
UCOS_III_Start函数
#define START_TASK_LEVEL 4
#define START_TASK_STK_SIZE 128
CPU_STK START_TASK_STK[START_TASK_STK_SIZE];
OS_TCB Start_Task_TCB;
void start_task_process(void* pdata);
#define UART_TASK_LEVEL 2
#define UART_TASK_STK_SIZE 128
CPU_STK UART_TASK_STK[UART_TASK_STK_SIZE];
OS_TCB UART_Task_TCB;
void uart_task_process(void* pdata);
OS_FLAG_GRP flag_group;
void UCOS_III_Start(void)
{
OS_ERR err;
OSInit(&err);
OSTaskCreate(&Start_Task_TCB, (CPU_CHAR*)"start_task", start_task_process, (void *)0,
START_TASK_LEVEL, &START_TASK_STK[0], START_TASK_STK_SIZE/10, START_TASK_STK_SIZE, 0, 0,
0, OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, &err);
OSStart(&err);
}
void start_task_process(void* pdata)
{
OS_ERR err;
OSFlagCreate(&flag_group, "flag_action", 0, &err);
CPU_SR_ALLOC();
OS_CRITICAL_ENTER();
OSTaskCreate(&UART_Task_TCB, (CPU_CHAR*)"uart_task", uart_task_process, (void *)0,
UART_TASK_LEVEL, &UART_TASK_STK[0], UART_TASK_STK_SIZE/10, UART_TASK_STK_SIZE, 0, 0, 0,
OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, &err);
OS_TaskSuspend((OS_TCB*)&Start_Task_TCB,&err);
OS_CRITICAL_EXIT();
}
void uart_task_process(void* pdata)
{
OS_ERR err;
while(1)
{
SL_Debug("USART1 is successfully configurated\r\n");
OSTimeDly(500, OS_OPT_TIME_PERIODIC, &err);
}
}
6、移植成果
由于移植成功的时候没有截图,这块请读者自行脑补~~~~~~~~
四、注意事项
- 当HAL库生生成的函数是静态函数(static)时,如果在其他地方有调用此函数请去掉static
- 切记不要在uCOS任务-III中使用HAL库的Delay函数(会卡死)需要延时时请使用使用uCOS-III的延时函数(OSTimeDly)
- 由于移植的过程中修改了startup_stm32f103xb.s 文件中的两处PendSV_Handler和Systick_Handler以及注释掉stm32f1xx_it.c的PendSV_Handler与SysTick_Handler函数,所以当移植后又不打算使用uCOS-III时,请将上述两处文件修改恢复为原来的样子,否则mcu将无法正常工作