将uc/OS移植到stm32F103上

一、嵌入式实时操作系统(RTOS)

1.定义

实时操作系统是保证在一定时间限制内完成特定功能的操作系统。实时操作系统有硬实时和软实时之分,硬实时要求在规定的时间内必须完成操作,这是在操作系统设计时保证的;软实时则只要按照任务的优先级,尽可能快地完成操作即可。我们通常使用的操作系统在经过一定改变之后就可以变成实时操作系统。

2.实时任务

在实时系统中必然存在着若干个实时任务,这些任务通常与某些个外部设备相关,能反应或控制相应的外部设备,因而带有某种程度的紧迫性。可从不同的角度对实时任务加以分类。
按任务执行时是否呈现周期性变化来划分:
①周期性实时任务
外部设备周期性地发出激励信号给计算机,要求它按照指定周期循环执行,以便周期性的控制某种外部设备。
②非周期性实时任务
外部设备所发出的激励信号并无明显的周期性,但都必须联系着一个截止时间。 它又可分为开始截止时间(任务在某时间以前必须开始执行)和完成截止时间(任务在某时间以前必须完成)两部分。
根据对截至时间的要求来划分
①硬实时任务
②软实时任务

3.特征

1)高精度计时系统
计时精度是影响实时性的一个重要因素。在实时应用系统中,经常需要精确确定实时地操作某个设备或执行某个任务,或精确的计算一个时间函数。这些不仅依赖于一些硬件提供的时钟精度,也依赖于实时操作系统实现的高精度计时功能。
2)多级中断机制
一个实时应用系统通常需要处理多种外部信息或事件,但处理的紧迫程度有轻重缓急之分。有的必须立即作出反应,有的则可以延后处理。因此,需要建立多级中断嵌套处理机制,以确保对紧迫程度较高的实时事件进行及时响应和处理。
3)实时调度机制
实时操作系统不仅要及时响应实时事件中断,同时也要及时调度运行实时任务。但是,处理机调度并不能随心所欲的进行,因为涉及到两个进程之间的切换,只能在确保“安全切换”的时间点上进行,实时调度机制包括两个方面,一是在调度策略和算法上保证优先调度实时任务;二是建立更多“安全切换”时间点,保证及时调度实时任务。

二、使用CubeMX建立STM32F103C8T6HAL库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置系统时钟为72M在这里插入图片描述
将与LED相连的端口PC13配置为GPIO_Output
在这里插入图片描述
设置串口USART1
在这里插入图片描述
填写项目信息
在这里插入图片描述
在这里插入图片描述
打开项目,在main函数的while循环中添加

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
  HAL_Delay(500);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
  HAL_Delay(500);

连接好电路后,编译烧录运行程序

三、移植uC/OS-III

1.从ucoslll官网中下载源码
http://micrium.com/downloadcenter/

在这里插入图片描述

2.新建uC-BSP和uC-CONFIG文件夹

3.为uC-BSP文件夹新建bsp.c和bsp.h文件
在这里插入图片描述
4.将uCOS相关文件复制到HAL工程的MDK-ARM文件夹下
5.将uCOS文件添加到项目
6.在keil中导入文件
在这里插入图片描述
在这里插入图片描述

7.CPU-Add选择uC-CPU下的
在这里插入图片描述
RealView下的
在这里插入图片描述

LIB-Add uC-LIB下的
在这里插入图片描述
RealView下的
在这里插入图片描述

PORT-Add RealView下的
在这里插入图片描述

SOURCE-Add Source下的
在这里插入图片描述

CONFIG-Add uc-CONFIG下的
在这里插入图片描述

BSP-Add uc-BSP下的
在这里插入图片描述

8.在path中添加
在这里插入图片描述

9.将启动文件的PendSV_HandlerSystick_Handler改为OS_CPU_PendSVHandlerOS_CPU_SysTickHandler
在这里插入图片描述
在这里插入图片描述

10.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)
在这里插入图片描述
在这里插入图片描述
11.includes.h
在#include <bsp.h> 后面加上

 #include “gpio.h”
 #include “app_cfg.h”

#include <stm32f10x_lib.h> 改为

 #include “stm32f1xx_hal.h”

在这里插入图片描述

12.lib_cfg.h
#define LIB_MEM_CFG_HEAP_SIZE 5u * 1024u改为

 #define LIB_MEM_CFG_HEAP_SIZE 5u * 1024u

在这里插入图片描述

13.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

14.bsp.h文件代码

// bsp.h
#ifndef  __BSP_H__
#define  __BSP_H__
#include "stm32f1xx_hal.h"
void BSP_Init(void);
#endif

15.main.c函数代码

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#include "usart.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <includes.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* 任务优先级 */
#define START_TASK_PRIO		3
#define LED0_TASK_PRIO		4
#define LED1_TASK_PRIO		5
#define FLOAT_TASK_PRIO		6

/* 任务堆栈大小	*/
#define START_STK_SIZE 		256
#define LED0_STK_SIZE 		128
#define LED1_STK_SIZE 		128
#define FLOAT_STK_SIZE		128
/* 任务栈 */	
CPU_STK START_TASK_STK[START_STK_SIZE];
CPU_STK LED0_TASK_STK[LED0_STK_SIZE];
CPU_STK LED1_TASK_STK[LED1_STK_SIZE];
/* 任务控制块 */
OS_TCB StartTaskTCB;
OS_TCB Led0TaskTCB;
OS_TCB Led1TaskTCB;
OS_TCB FloatTaskTCB;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* 任务函数定义 */
void start_task(void *p_arg);
static  void  AppTaskCreate(void);
static  void  AppObjCreate(void);
static  void  led_pc13(void *p_arg);
static  void  send_msg(void *p_arg);
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
  * @brief System Clock Configuration
  * @retval None
  */
  void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
/* USER CODE END 0 */
/**
  * @brief  The application entry point.
  * @retval int
  */
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_pc13", 		
                 (OS_TASK_PTR )led_pc13, 			
                 (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	* )"led1 task", 		
                 (OS_TASK_PTR )send_msg, 			
                 (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);
				 
	OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err);		//挂起开始任务			 
	OS_CRITICAL_EXIT();	//进入临界区
	}

17.需要在usart.c文件中添加以下代码完成printf重定向

int fputc(int ch,FILE *f){
 HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
 return ch;
}

18.添加头文件
19.编译运行烧录调试
在这里插入图片描述

四、总结

参考链接
https://blog.csdn.net/weixin_43116606/article/details/105532222
https://www.cnblogs.com/dreamrj/p/14046598.html
https://blog.csdn.net/sunke9/article/details/104315486?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.highlightwordscore&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.highlightwordscore

版权声明:本文为CSDN博主「山妖的阶梯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_51086303/article/details/121790261

一、嵌入式实时操作系统(RTOS)

1.定义

实时操作系统是保证在一定时间限制内完成特定功能的操作系统。实时操作系统有硬实时和软实时之分,硬实时要求在规定的时间内必须完成操作,这是在操作系统设计时保证的;软实时则只要按照任务的优先级,尽可能快地完成操作即可。我们通常使用的操作系统在经过一定改变之后就可以变成实时操作系统。

2.实时任务

在实时系统中必然存在着若干个实时任务,这些任务通常与某些个外部设备相关,能反应或控制相应的外部设备,因而带有某种程度的紧迫性。可从不同的角度对实时任务加以分类。
按任务执行时是否呈现周期性变化来划分:
①周期性实时任务
外部设备周期性地发出激励信号给计算机,要求它按照指定周期循环执行,以便周期性的控制某种外部设备。
②非周期性实时任务
外部设备所发出的激励信号并无明显的周期性,但都必须联系着一个截止时间。 它又可分为开始截止时间(任务在某时间以前必须开始执行)和完成截止时间(任务在某时间以前必须完成)两部分。
根据对截至时间的要求来划分
①硬实时任务
②软实时任务

3.特征

1)高精度计时系统
计时精度是影响实时性的一个重要因素。在实时应用系统中,经常需要精确确定实时地操作某个设备或执行某个任务,或精确的计算一个时间函数。这些不仅依赖于一些硬件提供的时钟精度,也依赖于实时操作系统实现的高精度计时功能。
2)多级中断机制
一个实时应用系统通常需要处理多种外部信息或事件,但处理的紧迫程度有轻重缓急之分。有的必须立即作出反应,有的则可以延后处理。因此,需要建立多级中断嵌套处理机制,以确保对紧迫程度较高的实时事件进行及时响应和处理。
3)实时调度机制
实时操作系统不仅要及时响应实时事件中断,同时也要及时调度运行实时任务。但是,处理机调度并不能随心所欲的进行,因为涉及到两个进程之间的切换,只能在确保“安全切换”的时间点上进行,实时调度机制包括两个方面,一是在调度策略和算法上保证优先调度实时任务;二是建立更多“安全切换”时间点,保证及时调度实时任务。

二、使用CubeMX建立STM32F103C8T6HAL库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置系统时钟为72M在这里插入图片描述
将与LED相连的端口PC13配置为GPIO_Output
在这里插入图片描述
设置串口USART1
在这里插入图片描述
填写项目信息
在这里插入图片描述
在这里插入图片描述
打开项目,在main函数的while循环中添加

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
  HAL_Delay(500);
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
  HAL_Delay(500);

连接好电路后,编译烧录运行程序

三、移植uC/OS-III

1.从ucoslll官网中下载源码
http://micrium.com/downloadcenter/

在这里插入图片描述

2.新建uC-BSP和uC-CONFIG文件夹

3.为uC-BSP文件夹新建bsp.c和bsp.h文件
在这里插入图片描述
4.将uCOS相关文件复制到HAL工程的MDK-ARM文件夹下
5.将uCOS文件添加到项目
6.在keil中导入文件
在这里插入图片描述
在这里插入图片描述

7.CPU-Add选择uC-CPU下的
在这里插入图片描述
RealView下的
在这里插入图片描述

LIB-Add uC-LIB下的
在这里插入图片描述
RealView下的
在这里插入图片描述

PORT-Add RealView下的
在这里插入图片描述

SOURCE-Add Source下的
在这里插入图片描述

CONFIG-Add uc-CONFIG下的
在这里插入图片描述

BSP-Add uc-BSP下的
在这里插入图片描述

8.在path中添加
在这里插入图片描述

9.将启动文件的PendSV_HandlerSystick_Handler改为OS_CPU_PendSVHandlerOS_CPU_SysTickHandler
在这里插入图片描述
在这里插入图片描述

10.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)
在这里插入图片描述
在这里插入图片描述
11.includes.h
在#include <bsp.h> 后面加上

 #include “gpio.h”
 #include “app_cfg.h”

#include <stm32f10x_lib.h> 改为

 #include “stm32f1xx_hal.h”

在这里插入图片描述

12.lib_cfg.h
#define LIB_MEM_CFG_HEAP_SIZE 5u * 1024u改为

 #define LIB_MEM_CFG_HEAP_SIZE 5u * 1024u

在这里插入图片描述

13.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

14.bsp.h文件代码

// bsp.h
#ifndef  __BSP_H__
#define  __BSP_H__
#include "stm32f1xx_hal.h"
void BSP_Init(void);
#endif

15.main.c函数代码

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#include "usart.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <includes.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* 任务优先级 */
#define START_TASK_PRIO		3
#define LED0_TASK_PRIO		4
#define LED1_TASK_PRIO		5
#define FLOAT_TASK_PRIO		6

/* 任务堆栈大小	*/
#define START_STK_SIZE 		256
#define LED0_STK_SIZE 		128
#define LED1_STK_SIZE 		128
#define FLOAT_STK_SIZE		128
/* 任务栈 */	
CPU_STK START_TASK_STK[START_STK_SIZE];
CPU_STK LED0_TASK_STK[LED0_STK_SIZE];
CPU_STK LED1_TASK_STK[LED1_STK_SIZE];
/* 任务控制块 */
OS_TCB StartTaskTCB;
OS_TCB Led0TaskTCB;
OS_TCB Led1TaskTCB;
OS_TCB FloatTaskTCB;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* 任务函数定义 */
void start_task(void *p_arg);
static  void  AppTaskCreate(void);
static  void  AppObjCreate(void);
static  void  led_pc13(void *p_arg);
static  void  send_msg(void *p_arg);
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
  * @brief System Clock Configuration
  * @retval None
  */
  void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
/* USER CODE END 0 */
/**
  * @brief  The application entry point.
  * @retval int
  */
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_pc13", 		
                 (OS_TASK_PTR )led_pc13, 			
                 (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	* )"led1 task", 		
                 (OS_TASK_PTR )send_msg, 			
                 (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);
				 
	OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err);		//挂起开始任务			 
	OS_CRITICAL_EXIT();	//进入临界区
	}

17.需要在usart.c文件中添加以下代码完成printf重定向

int fputc(int ch,FILE *f){
 HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
 return ch;
}

18.添加头文件
19.编译运行烧录调试
在这里插入图片描述

四、总结

参考链接
https://blog.csdn.net/weixin_43116606/article/details/105532222
https://www.cnblogs.com/dreamrj/p/14046598.html
https://blog.csdn.net/sunke9/article/details/104315486?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.highlightwordscore&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.highlightwordscore

版权声明:本文为CSDN博主「山妖的阶梯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_51086303/article/details/121790261

生成海报
点赞 0

山妖的阶梯

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

串口不定长接收

一、保留接收区和开启接收的语句    uint8_t buffer[5];HAL_UART_Transmit_IT(&huart1,buffer,3); 二、写入开启空闲中断的语句    __HAL_UART_ENABLE_IT(&huart

基于STM32单片机的电子密码锁设计

一.硬件方案 本设计采用STM32F103C8T6单片机作为主控芯片,结合外围的矩阵按键输入、LCD1602液晶显示、报警、开锁等电路模块实现开锁、上锁、报警、密码更改等功能,设计了一款可以多次修改密码并且具有报警