FreeRTOS学习(一)STM32F103的FreeRTOS移植


(根据正点原子视频学习总结)

准备材料

1.FreeRTOS源码
2.正点原子跑马灯例程
FreeRTOS百度网盘连接
提取码:x7b6

1.添加FreeRTOS源码

在跑马灯例程中添加FreeRTOS文件夹
在这里插入图片描述
然后,将FreeRTOS源码source文件夹下的文件复制粘贴到刚刚跑马灯例程下新建的FreeRTOS文件夹下。
在这里插入图片描述在这里插入图片描述
将文件复制完成后,打开portable文件夹,删除不需要的文件,只保留Keil、MemMang、RVDS在这里插入图片描述
在这里插入图片描述

2.将文件添加到工程

在工程中添加分组,FreeRTOS_CORE和FreeRTOS_PORTABLE,CORE中存放FreeRTOS内核源文件(FreeRTOS下的7个.c文件),PORTABLE用于存放FreeRTOS内核的移植文件,需要添加heap_x.c和port.c进去,其中heap_x.c是不同类型的内存管理算法,port.c需要根据不同的芯片类型来选择对应的文件夹中的port.c(各文件夹位于FreeRTOS下的portable中,heap_x位于MemMang下,port位于RVDS下)。

类型port.c所在文件夹
STM32F1ARM_CM3
STM32F4ARM_CM4F
STM32F7ARM_CM7/r0p1
STM32H7ARM_CM7/r0p1

添加完成后如图所示:
在这里插入图片描述

3.添加头文件路径

添加完成后,对.c文件添加对应的头文件路径(魔术棒)。
注:这里要添加FreeRTOS文件下的include文件夹。
在这里插入图片描述

这里路径添加完成后,选择编译报错并会提示打不开FreeRTOSConfig.h文件
在这里插入图片描述

4.添加FreeRTOSConfig.h文件

FreeRTOSConfig.h 是 FreeRTOS 操作系统的配置文件,它不属于源码的文件,是根据需要来修改的,当然它在源码文件中Demo中也存在,这里选择使用正点原子例程中的FreeRTOSConfig.h文件,将它复制我们工程中FreeRTOS文件夹下的include文件夹下。
在这里插入图片描述
将FreeRTOSConfig.h 复制到上图位置后,对工程进行编译,这里我出现了两个报错。
报错1:…\FreeRTOS\queue.c(2762): error: #268: declaration may not appear after executable statement in block
QueueRegistryItem_t * pxEntryToWrite = NULL;
解决办法:魔术棒里勾选C99mode即可解决
报错2:…\SYSTEM\usart\usart.c(48): error: #260-D: explicit type is missing (“int” assumed)
_sys_exit(int x)
解决办法:将_sys_exit(int x) 改为void _sys_exit(int x)

修改完成后,即和正点原子视频中报错一致,将重复定义的函数屏蔽掉,再次编译显示无报错。
在这里插入图片描述

5.修改SYSTEM文件夹

建议直接复制例程中SYSTEM文件
①修改sys.h
sys.h的修改较为简单,只需将SYSTEM_SUPPORT_OS的0改为1即可。
在这里插入图片描述
②修改usart.c
usart.c文件有两部分要修改,一是添加FreeRTOS.h头文件,修改以后如下:
在这里插入图片描述
另外一个就是USART1的中断服务函数,删除掉OSIntEnter()和OSIntExit(),修改以后如下:
在这里插入图片描述
③delay.c
delay.c修改较大,这里建议直接使用例程中的,复制粘贴。
之后屏蔽掉SysTick_Handler函数

6.代码测试

完成上述工作后,将main.c替换为下面代码进行测试

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"



#define START_TASK_PRIO		1

#define START_STK_SIZE 		128  

TaskHandle_t StartTask_Handler;

void start_task(void *pvParameters);


#define LED0_TASK_PRIO		2

#define LED0_STK_SIZE 		50  

TaskHandle_t LED0Task_Handler;

void led0_task(void *pvParameters);


#define LED1_TASK_PRIO		3

#define LED1_STK_SIZE 		50  

TaskHandle_t LED1Task_Handler;

void led1_task(void *pvParameters);

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//
	delay_init();	    				  
	uart_init(115200);					
	LED_Init();		  					
	 

    xTaskCreate((TaskFunction_t )start_task,           
                (const char*    )"start_task",          
                (uint16_t       )START_STK_SIZE,       
                (void*          )NULL,                  
                (UBaseType_t    )START_TASK_PRIO,       
                (TaskHandle_t*  )&StartTask_Handler);                
    vTaskStartScheduler();         
}


void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           

    xTaskCreate((TaskFunction_t )led0_task,     	
                (const char*    )"led0_task",   	
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED0_TASK_PRIO,	
                (TaskHandle_t*  )&LED0Task_Handler);   

    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);         
    vTaskDelete(StartTask_Handler); 
    taskEXIT_CRITICAL();            
}


void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0=~LED0;
        vTaskDelay(500);
    }
}   


void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);
    }
}

LED灯工作说明移植成功。

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 以下是一个使用FreeRTOS控制LED灯的示例代码: ``` #include <stdlib.h> #include "FreeRTOS.h" #include "task.h" #include "stm32f10x.h" #define LED_GPIO_PORT GPIOC #define LED_GPIO_PIN GPIO_Pin_13 static void led_task(void* pvParameters) { while(1) { GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, Bit_SET); vTaskDelay(500 / portTICK_RATE_MS); GPIO_WriteBit(LED_GPIO_PORT, LED_GPIO_PIN, Bit_RESET); vTaskDelay(500 / portTICK_RATE_MS); } } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = LED_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure); xTaskCreate(led_task, "LED", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); vTaskStartScheduler(); while(1); } ``` 这段代码的作用是在STM32F103芯片上控制PC13引脚的LED灯,使用了FreeRTOS的任务调度功能来定时切换LED灯的状态。在任务函数`led_task`中,先将LED灯的状态设为高电平,然后延时500ms,再将LED灯的状态设为低电平,再延时500ms,循环执行。在主函数中,先初始化LED引脚为输出模式,然后创建一个名为“LED”的任务,将其加入任务队列,并启动FreeRTOS调度器。 ### 回答2: FreeRTOS是一个开源的实时操作系统内核,适用于嵌入式系统开发。根据题目需要,我假设你想要了解如何使用FreeRTOS来编写点灯的代码。 首先,你需要在嵌入式系统上安装FreeRTOS,并创建一个新的任务来控制点灯。 示例代码如下: 1. 首先,包含FreeRTOS所需的头文件: #include "FreeRTOS.h" #include "task.h" 2. 创建一个任务来控制点灯: void ledTask(void *pvParameters) { // 初始化GPIO控制灯的引脚 // 或者使用你的嵌入式硬件的特定API来控制灯的引脚 while(1) { // 点亮灯 // 或者使用你的嵌入式硬件的特定API来控制灯的状态 vTaskDelay(pdMS_TO_TICKS(100)); // 等待100毫秒 // 关闭灯 // 或者使用你的嵌入式硬件的特定API来控制灯的状态 vTaskDelay(pdMS_TO_TICKS(100)); // 等待100毫秒 } } 3. 在系统的初始化函数中创建任务: void systemInit(void) { // 初始化系统,包括初始化硬件等 xTaskCreate(ledTask, "LED Task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL); vTaskStartScheduler(); // 启动任务调度器 } 以上是一个简单的FreeRTOS点灯代码的示例,当任务启动后,它会周期性地点亮和关闭灯。你可以根据自己的具体需求来修改代码,比如更改点灯的频率或使用其他的GPIO函数来控制灯的状态。 需要注意的是,上述代码只提供了一个简单的示例,具体的实现可能需要根据你的嵌入式系统的硬件和外设接口进行调整。希望以上回答能够帮到你! ### 回答3: FreeRTOS是一种流行的实时操作系统,用于嵌入式系统的开发。它为多任务处理提供了一个可靠的解决方案,并提供了许多功能强大而又易于使用的API。 下面是一个用FreeRTOS编写的简单点灯代码示例: 首先,我们需要包含相应的头文件,包括FreeRTOS.h和task.h。然后,我们定义一个LED任务函数taskLED,用于控制LED的点亮和熄灭。 ```c #include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" // LED任务函数 void taskLED(void *pvParameters) { while (1) { // 控制LED点亮 // 等待1000毫秒 // 控制LED熄灭 // 等待1000毫秒 } } void app_main() { // 创建一个LED任务 xTaskCreate(&taskLED, "LED Task", 2048, NULL, 1, NULL); // 启动调度器 vTaskStartScheduler(); } ``` 在taskLED函数中,我们可以使用GPIO库函数来控制LED的点亮和熄灭。在这个示例中,我们使用了一个无限循环来连续地点亮和熄灭LED,并使用vTaskDelay函数来设置等待时间。 在app_main函数中,我们使用xTaskCreate函数创建了一个LED任务,指定了任务函数taskLED以及任务的栈大小。然后,我们调用vTaskStartScheduler函数来启动FreeRTOS的任务调度器。 当程序运行时,LED任务将会循环地控制LED的点亮和熄灭。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值