赞
踩
配置RCC
配置SYS
配置PA6和PB10为
GPIO_Output`
配置USART1
生成代码
官网下载地址:https://www.silabs.com/developers/micrium
或者
链接:https://pan.baidu.com/s/1PnPjS9vrpwOgGgeXGtoZhw
提取码:9962
–来自百度网盘超级会员V1的分享
在项目中创建一个UCOSIII
文件夹:
将下载的源文件下的uC-CPU
、uC-LIB
、uCOS-III
复制到该文件夹:
在Src文件夹下新建一个OS文件夹
将下载的源码中\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文件夹中:
新建三个空白文件: bsp.c、bsp.h、app.h
:
将Src/OS
中的bsp.c
和 bsp.h
文件添加至 bsp
组中,将 app.c
添加进 Application/User/Core
组中:
将UCOSIII/uC-CPU
中的cpu_core.c
、cpu_core.h
、cpu_def.h
添加进uCOSIII_CPU
组中,同时将UCOSIII/uC-CPU/ARM-Cortex-M3/RealView
中的三个文件添加到该组:
将UCOSIII/uC-LIB
中的9个文件添加到uCOSIII-LIB
组中,同时将UCOSIII/uC-LIB/Ports/ARM-Cortex-M3/Realview
中的lib_mem_a.asm
添加到该组中:
将UCOSIII/UcosIII/Ports/ARM-Cortex-M3/Generic/RealView
中的3个文件添加的uCOSIII_Ports
组中:
将UCOSIII/UcosIII/Source
中的20个文件添加到uCOSIII_Source
组中:
将Core/Src/OS
中的以下图中的8个文件添加到OS_cfg
组中
如图所示,添加头文件路径:
将启动文件下图中的PendSV_Handler
和Systick_Handler
改为OS_CPU_PendSVHandler
和OS_CPU_SysTickHandler
:
修改前:
修改后:
修改前:
修改后:
添加3个头文件:
#include "gpio.h"
#include "app_cfg.h"
#include "app.h"
修改前:
修改后:
#include "stm32f1xx_hal.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); } #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
由于我们使用了printf函数,需要在usart.c
文件中添加以下代码完成printf重定向
//添加头文件#include "stdio.h"
/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f){
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
return ch;
}
/* USER CODE END 1 */
加入宏定义:
#define LIB_MEM_CFG_HEAP_SIZE 10u * 1024u
#include "includes.h"
构建三个任务:
#include "main.h" #include "usart.h" #include "gpio.h" #include <includes.h> /* 任务优先级 */ #define START_TASK_PRIO 2 #define LED0_TASK_PRIO 3 #define LED1_TASK_PRIO 3 #define MSG_TASK_PRIO 4 /* 任务堆栈大小 */ #define START_STK_SIZE 96 #define LED0_STK_SIZE 64 #define LED1_STK_SIZE 64 #define MSG_STK_SIZE 64 /*定义任务控制块*/ static OS_TCB StartTaskTCB; static OS_TCB Led0TaskTCB; static OS_TCB Led1TaskTCB; static OS_TCB MsgTaskTCB; /*定义任务堆栈*/ static CPU_STK START_TASK_STK[START_STK_SIZE]; static CPU_STK LED0_TASK_STK[LED0_STK_SIZE]; static CPU_STK LED1_TASK_STK[LED1_STK_SIZE]; static CPU_STK MSG_TASK_STK[MSG_STK_SIZE]; void SystemClock_Config(void); /*声明用户任务*/ void start_task(void *p_arg); static void led_PA6(void *p_arg); static void send_msg(void *p_arg); static void led_PB10(void *p_arg); /*主函数*/ int main(void) { OS_ERR err; OSInit(&err); HAL_Init(); SystemClock_Config(); //MX_GPIO_Init(); 这个在BSP的初始化里也会初始化 MX_USART1_UART_Init(); /* 创建任务 */ OSTaskCreate((OS_TCB *)&StartTaskTCB, /* Create the start task */ (CPU_CHAR *)"start task", (OS_TASK_PTR ) start_task, (void *) 0, (OS_PRIO ) START_TASK_PRIO, (CPU_STK *)&START_TASK_STK[0], (CPU_STK_SIZE) START_STK_SIZE/10, (CPU_STK_SIZE) START_STK_SIZE, (OS_MSG_QTY ) 0, (OS_TICK ) 0, (void *) 0, (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), (OS_ERR *)&err); /* 启动多任务系统,控制权交给uC/OS-III */ OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */ } void start_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; /* YangJie add 2021.05.20*/ BSP_Init(); /* Initialize BSP functions */ //CPU_Init(); //Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); //统计任务 #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间 CPU_IntDisMeasMaxCurReset(); #endif #if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms OSSchedRoundRobinCfg(DEF_ENABLED,1,&err); #endif OS_CRITICAL_ENTER(); //进入临界区 /* 创建LED0任务 */ OSTaskCreate((OS_TCB * )&Led0TaskTCB, (CPU_CHAR * )"led_PA6", (OS_TASK_PTR )led_PA6, (void * )0, (OS_PRIO )LED0_TASK_PRIO, (CPU_STK * )&LED0_TASK_STK[0], (CPU_STK_SIZE)LED0_STK_SIZE/10, (CPU_STK_SIZE)LED0_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); /* 创建LED1任务 */ OSTaskCreate((OS_TCB * )&Led1TaskTCB, (CPU_CHAR * )"led_PB10", (OS_TASK_PTR )led_PB10, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )&LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); /* 创建MSG任务 */ OSTaskCreate((OS_TCB * )&MsgTaskTCB, (CPU_CHAR * )"send_msg", (OS_TASK_PTR )send_msg, (void * )0, (OS_PRIO )MSG_TASK_PRIO, (CPU_STK * )&MSG_TASK_STK[0], (CPU_STK_SIZE)MSG_STK_SIZE/10, (CPU_STK_SIZE)MSG_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )&err); OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区 } static void led_PA6 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); /* Create Application Objects */ while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } static void led_PB10 (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); while (DEF_TRUE) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET); OSTimeDlyHMSM(0, 0, 3, 0,OS_OPT_TIME_HMSM_STRICT,&err); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET); OSTimeDlyHMSM(0, 0, 3, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } static void send_msg (void *p_arg) { OS_ERR err; (void)p_arg; BSP_Init(); /* Initialize BSP functions */ CPU_Init(); Mem_Init(); /* Initialize Memory Management Module */ #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif CPU_IntDisMeasMaxCurReset(); /* Create Application Objects */ while (DEF_TRUE) { printf("hello uc/OS! 欢迎来到RTOS多任务环境! \r\n"); OSTimeDlyHMSM(0, 0, 2, 0,OS_OPT_TIME_HMSM_STRICT,&err); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } void Error_Handler(void) { __disable_irq(); while (1) { } } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { } #endif
效果如下:
本次实验主要学习了stm32f103c8t6移植uC/OS-III操作系统的具体流程,并完成了多任务创建实现的实验要求。
参考资料:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。