第一节:FreeRTOS (MDK)系统移植 (详细)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ZenNaiHeQiao/article/details/82620971

移植总结:

第一步准备素材:如何在官网上下载源文件

第二步移植代码:包括两步:①从源码中提需需要的文件②将代码添加到工程中

第三步修改代码:最关键的一步使代码能够运行起来。

移植例程代码DEMO https://download.csdn.net/download/zennaiheqiao/10661276

 

第一步:准备素材(源码的下载)

(1)首先在FreeRTOS的网站官方可以下载到最新版的FreeRTOS的包。 

(2)解压下载的文件(了解文件大概内容)

1,下载包根目录下包含两个子目录:FreeRTOS的和FreeRTOS的-PLUS其中,FreeRTOS的加文件夹中包含一些FreeRTOS的+组件和演示例程(组件大都收费),我们不对这个文件夹下的内容多做了解,重点说一下FreeRTOS文件夹.freeRTOS和freeRTOS都是放置源码的,加上只是配置更强大了。包含了CLI FAT Trace一些扩展例程

2,FreeRTOS文件夹介绍下包含三个子目录:Demo,License,Source。

其中,演示包含演示例程的工程文件,源代码包含实时操作系统源代码文件。

其中Demo文件夹包含了各类处理器的Demo程序。其中包括407和103的程序,FreeRTOSConfig.h文件就是里面复制出来的。

Source源码:包括include和porttable。(包括是一些头文件,porttable是操作硬件的一些封装。)

(3)提取源中的源文件(移植用)

FreeRTOS的实时操作系统内核仅包含三个必要文件,此外还有三个可选文件.RTOS核心代码位于三个源文件中,分别是tasks.c,queue.c和list.c.这三个文件位于FreeRTOS操作系统/源目录下,在同一目录下还有3个可选的文件,叫做timers.c,event_groups.c和croutine.c,分别用于软件定时器,事件组和协程。

Keil文件夹是必须的,但是打开后发现需要去拷贝RVDS的文件,“参见-RVDS目录”,即文件复用

MemMang是文件夹跟内存相关的。

对于支持的处理器架构,RTOS需要一些与处理器架构相关的代码。可以称之为RTOS硬件接口层,它们位于FreeRTOS/Source/Portable/[相应编译器]/[相应处理器架构]文件夹下。我们这次要移植到Cortex-M3微控制,使用Keil MDK编译器,所以需要的RTOS硬件接口代码位于:FreeRTOS\Source\portable\RVDS\ARM_CM3文件夹下。

MemMang里面有5中内存的管理方式,都可以用各有优缺点后面会研究,选第四种使用。

堆栈分配也是属于硬件接口层(移植层),在FreeRTOS/Source/portable/MemMang文件夹下具有各种类型的堆栈分配方案。这里我们使用heap_1.c提供的堆栈分配方案。关于FreeRTOS的内存管理,后续《FreeRTOS内存管理》一文中会详细介绍FreeRTOS内存管理的特性和用法,《FreeRTOS内存管理分析》一文会从源码级别分析FreeRTOS内存管理的具体实现,这里不用多纠结,

问价准备齐了。准备干活FreeRTOS

第二步:移植代码

准备移植的文件

新建一个FreeRTOS文件夹,将Source 文件夹内容全copy过来

portable删除无关的文件,资料准备完全。

工程添加移植文件

 在工程中添加如下文件。并设置路径。

编译后

去官方的STM32F103中COPY一个FreeRTOSConfig.h  

再次编译,无错误。

修改代码

①新建一个FreeRTOS文件夹,将Source 文件夹内容全copy过来

②挂接中断

注意工程内不能有 SysTick,PendSV 和 SVC 三个系统中断的使用,因为 FreeRTOS 系统要使用这三个中断

有的话屏蔽就好了

在Cortex-M3硬件下,FreeRTOS使用SysTick作为系统节拍时钟,使用SVC和PendSVC进行上下文切换。异常中断服务代码位于…\FreeRTOS\Source\portable\IAR\ARM_CM3\port.c文件中,FreeRTOS已经为各种构架的CPU写好了这些代码,可以直接拿来用,需要做的是将这些异常中断的入口地址挂接到启动代码中。在 FreeRTOSConfig.h 添加如下定义:

#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler
#define xPortSysTickHandler SysTick_Handler

 

编译后无错误。

添加任务:

需要包含头文件 "FreeRTOS.h""task.h" "timers.h" "croutine.h"

/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp/usart/bsp_debug_usart.h"
#include "includes.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)
{  
  char str[20];
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 	
  DEBUG_USART_Init();   /* 调试串口初始化配置,115200-N-8-1.使能串口发送和接受 */
  printf("FreeRTOS DEMO !");
  
  	//创建开始任务
    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();           //进入临界区
    //创建LED0任务
    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);   
    //创建LED1任务
    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();            //退出临界区
}

//LED0任务函数 
void led0_task(void *pvParameters)
{
    while(1)
    {
       printf(" Task 1 \r\n");
        vTaskDelay(500);
    }
}   

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
         printf(" Task 2_1 \r\n");
        vTaskDelay(200);
         printf(" Task 2_2 \r\n");
        vTaskDelay(800);
    }
}

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

总结:FreeRTOS 移植难度不大

①下载源码是在官网上下载的最新版本,移植时候没有版本限制。

②移植源码后,工程少一个FreeRTOSConfig.h文件这个直接在 DEMO例程里面复制.

③挂接中断,程序中有挂接中断这个环节,这个需要注意。然后添加程序就可以运行了。

后续要搞懂的问题是如何修改嘀嗒定时器,和一些内部运行 的机制。

https://blog.csdn.net/zhzht19861011/article/details/50072033

关于配置节拍

这里我们使用SysTick定时器作为系统的节拍时钟,设定每隔10ms产生一次节拍中断。由于FreeRTOS对移植做了非常多的工作,以至于我们只需要在FreeRTOSConfig.h中配置好以下两个宏定义即可:

  1. configCPU_CLOCK_HZ     (/*你的硬件平台CPU系统时钟,Fcclk*/)
  2. configTICK_RATE_HZ       ((portTickType)100)         

      第一个宏定义CPU系统时钟,也就是CPU执行时的频率。第二个宏定义FreeRTOS的时间片频率,这里定义为100,表明RTOS一秒钟可以切换100次任务,也就是每个时间片为10ms。

      在prot.c中,函数vPortSetupTimerInterrupt()设置节拍时钟该函数根据上面的两个宏定义的参数,计算系统定时器定时器的重装载数值寄存器,然后设置系统定时器定时器的控制及状态寄存器,设置如下:使用内核时钟源,使能中断,使能系统定时器定时器。另外,函数vPortSetupTimerInterrupt()由函数vTaskStartScheduler()调用,这个函数用于启动调度器。

猜你喜欢

转载自blog.csdn.net/ZenNaiHeQiao/article/details/82620971
今日推荐