【基于STM32HAL库移植FreeRTOS】

该文详细介绍了如何使用CubeMX创建基础工程并移植FreeRTOS操作系统,包括下载FreeRTOS源码、选择必要的文件、配置FreeRTOSConfig.h以及添加中断处理函数。同时,文中展示了如何在STM32F1xx的usart.c文件中添加串口调试功能,并在main.c中创建任务和调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目标:基于STM32HAL库移植FreeRTOS操作系统

目标:掌握FreeRTO的移植,后期将直接使用配置工具进行开发

内容:

  1. 使用CubeMX创建基础工程
  2. 移植FreeRTOS
  3. 了解三个参数的作用

步骤:

1、使用CubeMX创建基础工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、移植FreeRTOS
FreeRTOS下载地址:https://www.freertos.org/zh-cn-cmn-s/a00104.html
下载解压后根据下图进入如下位置
1、将Source文件夹中的文件复制到你工程里的新建的FreeRTOS文件夹
在这里插入图片描述
1、portable文件夹中只保留下图中的三个文件夹。
MemMang是内存管理文件
RVDS是FreeRTOS适配STM32的文件
在这里插入图片描述
然后在工程里面添加这些文件,还有一个FreeRTOS配置文件(FreeRTOSConfig.h),别忘了添加文件的路径
在这里插入图片描述
FreeRTOSConfig.h的配置如下所示:

#ifndef FREERTOS_CONFIG_H__
#define FREERTOS_CONFIG_H__
// 设置为1使用抢占式
#define configUSE_PREEMPTION										1
//使用时间片轮转调度
#define configUSE_TIME_SLICING     							1
//使用空闲任务调度
#define configIDLE_SHOULD_YIELD									1
// 设置为1使能低功耗tickless模式,为0保持系统节拍(tick)中断一直运行。
#define configUSE_TICKLESS_IDLE                 0
// 系统时钟主频
#define configCPU_CLOCK_HZ                      ( ( unsigned long ) 72000000 )
// 系统节拍中断的频率,即1s进中断的次数,配置为1000就是一秒进1000次中断,系统节拍就是1s。
#define configTICK_RATE_HZ                      ( ( TickType_t ) 1000 )
// 任务最大优先级,对于STM32来说最大不要超过32
#define configMAX_PRIORITIES                    32
// 任务最小栈大小
#define configMINIMAL_STACK_SIZE                ( ( unsigned short ) 128 )

// FreeRTOR堆空间大小
#define configTOTAL_HEAP_SIZE                   ( ( size_t ) ( 17 * 1024 ) )

// 任务名称最大长度
#define configMAX_TASK_NAME_LEN                 16

// 系统节拍计数器的变量类型,即定义portTickType是表示16位变量还是32位变量。
#define configUSE_16_BIT_TICKS                  0


// 设置是否使用互斥量
#define configUSE_MUTEXES                       1

// 设置是否使用递归互斥量
#define configUSE_RECURSIVE_MUTEXES             0

// 设置是否使用计数信号量
#define configUSE_COUNTING_SEMAPHORES           0

// 设置可以记录的队列和信号量的最大数目
#define configQUEUE_REGISTRY_SIZE               10

// 是否使用空闲钩子函数
#define configUSE_IDLE_HOOK                     1

// 是否使用TICK嘀嗒钩子函数
#define configUSE_TICK_HOOK                     0

// 是否使用栈溢出检查
#define configCHECK_FOR_STACK_OVERFLOW          0

// 是否使用内存申请失败钩子函数
#define configUSE_MALLOC_FAILED_HOOK            0

// 是否使用软件定时器
#define configUSE_TIMERS                        1

// 设置软件定时器服务/守护进程的优先级
#define configTIMER_TASK_PRIORITY               3

// 设置软件定时器命令队列的长度
#define configTIMER_QUEUE_LENGTH                10

// 设置软件定时器服务/守护进程任务的堆栈深度
#define configTIMER_TASK_STACK_DEPTH            configMINIMAL_STACK_SIZE

// STM32的最低优先级
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15

// 能够在中断服务函数中安全调用FreeRTOS API的中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1

#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << 4 )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << 4 )


// 将以下定义设置为1以包含API函数,或设置为0排除API函数
#define INCLUDE_vTaskPrioritySet                1
#define INCLUDE_uxTaskPriorityGet               1
#define INCLUDE_vTaskDelete                     1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_xResumeFromISR                  1
#define INCLUDE_vTaskDelayUntil                 1
#define INCLUDE_vTaskDelay                      1
#define INCLUDE_xTaskGetSchedulerState          1
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_uxTaskGetStackHighWaterMark     0
#define INCLUDE_xTaskGetIdleTaskHandle          0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle  0
#define INCLUDE_pcTaskGetTaskName               0
#define INCLUDE_eTaskGetState                   0
#define INCLUDE_xEventGroupSetBitFromISR        1
#define INCLUDE_xTimerPendFunctionCall          0

#endif  /* FREERTOS_CONFIG_H__ */



在stm32f1xx_it.c文件中,添加下面三个函数

extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
extern void vPortSVCHandler(void);

在这里插入图片描述

在usart.c文件中添加一下代码,方便串口调试输出打印信息

/* USER CODE BEGIN 0 */
#include "stdio.h" //添加头文件
/* USER CODE END 0 */
int fputc(int ch, FILE *f)                             //串口重定向
 {	 
	 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
   return ch;
 }

在main.c文件添加一下头文件
在这里开始就要创建任务开始调度了。

#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stdio.h"

/* USER CODE BEGIN 0 */
static volatile int led1=0;
static volatile int led2=0;
static volatile int led3=0;
static volatile int IdleTask=0;
void led1_task(void* arg)
{
    while(1)
    {
		led1=1;
		led2=0;
		led3=0;
		IdleTask=0;
		printf("T1\r\n");
    }
}

void led2_task(void* arg)
{
    while(1)
    {
	    led1=0;
		led2=1;
		led3=0;
		IdleTask=0;
		printf("T2\r\n");
    }
}

void led3_task(void* arg)
{
	const TickType_t xDelay5ms = pdMS_TO_TICKS( 5UL );
    while(1)
    {   
		led1=0;
		led2=0;
		led3=1;
		IdleTask=0;
		printf("T3\r\n");	
	    vTaskDelay( xDelay5ms );
    }
}
void vApplicationIdleHook(void)
{
	led1=0;
	led2=0;
	led3=0;
	IdleTask=1;
	//vTaskDelay(10);
	
	/* 故意加入打印让flagIdleTaskrun变为1的时间维持长一点 */
	printf("Id\r\n");				
}

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	//在操作系统中数字越大优先级越高
	xTaskCreate(led1_task, "led1_task", 128, NULL, 0, NULL);
	
	// 创建任务led2灯任务
	xTaskCreate(led2_task, "led2_task", 128, NULL, 0, NULL);
	
	// 创建串口打印任务
   xTaskCreate(led3_task, "led3_task", 128, NULL, 2, NULL);

	// 启动任务调度
    vTaskStartScheduler();
		
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

编译成功后点击在线调试步骤如下图
在这里插入图片描述
在这里插入图片描述

经过虚拟仿真在逻辑分析仪中的效果如图所示:
在这里插入图片描述


三个参数的设置:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值