这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【Mini-F5265-OB】2、移植FreeRTOS

共3条 1/1 1 跳转至

【Mini-F5265-OB】2、移植FreeRTOS

助工
2024-12-29 15:03:19   被打赏 35 分(兑奖)     打赏

1. 前言

本篇将会从FreeRTOS官网下载内核源码,移植到MM32F320处理器的工程中,验证方法是创建一个任务,在任务中闪烁LED。

2. 移植2.1 获取源码

image.png

2.2 移植源文件

先在工程目录下面新建Middleware/FreeRTOS文件夹,把源根目录下的FreeRTOS-Kernel复制到这个目录下。

image.png

新建项目分组,将源文件根目录下的所有的.c添加到工程中:

image.png


添加port.c到工程中,由于我们使用的是VC6所以需要将FreeRTOS\portable\GCC\ARM_CM33_NTZ\non_secure目录下面的port.c、portasm.c添加进工程。当然如果你使用vc5那就添加keil下面的库

添加内存管理文件,这里选择portable/MemMang下面的heap_4.c

image.png

设置FreeRTOS的配置文件,他在example下面有一个,我将他复到的FreeRTOS目录下面并添加进工程。

添加完工程后,工程如下:

image.png

添加好后,将编译的头文件路径也添加如下:

image.png

【配置文件】

#ifndef FREERTOS_CONFIG_H
 
#define FREERTOS_CONFIG_H

 #include "platform.h"
 
extern uint32_t SystemCoreClock;
 
 
/* Star-MC1 port configuration. */
 
#define configENABLE_MPU                                0
 
#define configENABLE_FPU                                1
 
#define configENABLE_TRUSTZONE                          0
 
 
 
/* Constants related to the behaviour or the scheduler. */
 
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         0
 
#define configUSE_PREEMPTION                            1
 
#define configUSE_TIME_SLICING                          1
 
#define configMAX_PRIORITIES                            ( 5 )
 
#define configIDLE_SHOULD_YIELD                         1
 
#define configUSE_16_BIT_TICKS                          0 /* Only for 8 and 16-bit hardware. */
 
 
 
/* Constants that describe the hardware and memory usage. */
 
#define configCPU_CLOCK_HZ                              SystemCoreClock//系统时钟
 
#define configMINIMAL_STACK_SIZE                        ( ( uint16_t ) 128 )  // 定义空闲任务使用的堆栈大小。
 
#define configMAX_TASK_NAME_LEN                         ( 12 )
 
#define configTOTAL_HEAP_SIZE                           ( ( size_t ) ( 10 * 1024 ) )//配置FreeRTOS任务栈可用的RAM总量。
 
#define configTICK_RATE_HZ                          ( ( TickType_t ) 1000 )
 
/* Constants that build features in or out. */
 
#define configUSE_MUTEXES                               1
 
#define configUSE_TICKLESS_IDLE                         1
 
#define configUSE_APPLICATION_TASK_TAG                  0
 
#define configUSE_NEWLIB_REENTRANT                      0
 
#define configUSE_CO_ROUTINES                           0
 
#define configUSE_COUNTING_SEMAPHORES                   1
 
#define configUSE_RECURSIVE_MUTEXES                     1
 
#define configUSE_QUEUE_SETS                            0
 
#define configUSE_TASK_NOTIFICATIONS                    1
 
#define configUSE_TRACE_FACILITY                        1
 
 
 
/* Constants that define which hook (callback) functions should be used. */
 
#define configUSE_IDLE_HOOK                             0
 
#define configUSE_TICK_HOOK                             0
 
#define configUSE_MALLOC_FAILED_HOOK                    0
 
 
 
/* Constants provided for debugging and optimisation assistance. */
 
#define configCHECK_FOR_STACK_OVERFLOW                  0
 
#define configASSERT( x )                               if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
 
#define configQUEUE_REGISTRY_SIZE                       0
 
 
 
/* Software timer definitions. */
 
#define configUSE_TIMERS                                1
 
#define configTIMER_TASK_PRIORITY                       ( 3 )
 
#define configTIMER_QUEUE_LENGTH                        5
 
#define configTIMER_TASK_STACK_DEPTH                    ( configMINIMAL_STACK_SIZE  )
 
 
 
/* Set the following definitions to 1 to include the API function, or zero
 
 * to exclude the API function.  NOTE:  Setting an INCLUDE_ parameter to 0 is
 * only necessary if the linker does not automatically remove functions that are
 * not referenced anyway. */
#define INCLUDE_vTaskPrioritySet                        1
 
#define INCLUDE_uxTaskPriorityGet                       1
 
#define INCLUDE_vTaskDelete                             1
 
#define INCLUDE_vTaskCleanUpResources                   0
 
#define INCLUDE_vTaskSuspend                            1
 
#define INCLUDE_vTaskDelayUntil                         1
 
#define INCLUDE_vTaskDelay                              1
 
#define INCLUDE_uxTaskGetStackHighWaterMark             0
 
#define INCLUDE_xTaskGetIdleTaskHandle                  0
 
#define INCLUDE_eTaskGetState                           1
 
#define INCLUDE_xTaskResumeFromISR                      0
 
#define INCLUDE_xTaskGetCurrentTaskHandle               1
 
#define INCLUDE_xTaskGetSchedulerState                  0
 
#define INCLUDE_xSemaphoreGetMutexHolder                0
 
#define INCLUDE_xTimerPendFunctionCall                  1
 
 
 
/* This demo makes use of one or more example stats formatting functions.  These
 
 * format the raw data provided by the uxTaskGetSystemState() function in to
 * human readable ASCII form.  See the notes in the implementation of vTaskList()
 * within FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS            1
 
 
 
/* Dimensions a buffer that can be used by the FreeRTOS+CLI command interpreter.
 
 * See the FreeRTOS+CLI documentation for more information:
 * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_CLI/ */
#define configCOMMAND_INT_MAX_OUTPUT_SIZE               4096
 
 
 
/* Interrupt priority configuration follows...................... */
 
 
 
/* Use the system definition, if there is one. */
 
#ifdef __NVIC_PRIO_BITS
 
    #define configPRIO_BITS                             __NVIC_PRIO_BITS
 
#else
 
    #define configPRIO_BITS                             3   /* 8 priority levels. */
 
#endif
 
 
 
/* The lowest interrupt priority that can be used in a call to a "set priority"
 
 * function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0x07
 
 
 
/* The highest interrupt priority that can be used by any interrupt service
 
 * routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT
 * CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A
 * HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values). */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
 
 
 
/* Interrupt priorities used by the kernel port layer itself.  These are generic
 
 * to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
 
 
 
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
 
 * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY            ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
 
 
 
/* The #ifdef guards against the file being included from IAR assembly files. */
 
#ifndef __IASMARM__
 
 
 
    /* Constants related to the generation of run time stats. */
 
    #define configGENERATE_RUN_TIME_STATS               0
 
    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
 
    #define portGET_RUN_TIME_COUNTER_VALUE()            0
 
  //  #define configTICK_RATE_HZ                          ( ( TickType_t ) 1000 )
 
 
 
#endif /* __IASMARM__ */
 
 
 
/* Enable static allocation. */
 
#define configSUPPORT_STATIC_ALLOCATION                 0
 
 
 
/* System Handler */
 
#define SVC_Handler                                     SVCall_Handler
 
#define xPortPendSVHandler                              PendSV_Handler
 
#define xPortSysTickHandler                             SysTick_Handler
 
 
 
#endif /* FREERTOS_CONFIG_H */

具体的配置文件还需要看具体自己需要的什么功能来配置

【注意】

由于freertos实现了SVCall_Handler、PendSV_Handler、SysTick_Handler,所以我们需要在mm32f5260_it.c中注释掉这三个函数,要不会编译报错。

image.png

【测试程序】

修改main.c如下:

#define _MAIN_C_

/* Files include */
#include "platform.h"
#include "gpio_led_toggle.h"
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"



/***********************************************************************************************************************
  * @brief  This function is main entrance
  * @note   main
  * @param  none
  * @retval none
  *********************************************************************************************************************/
//任务优先级
#define START_TASK_PRIO                1
//任务堆栈大小        
#define START_STK_SIZE                 256
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO                2
//任务堆栈大小        
#define LED1_STK_SIZE                 256
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级
#define LED2_TASK_PRIO                3
//任务堆栈大小        
#define LED2_STK_SIZE                 256
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);



int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    PLATFORM_InitConsole(115200);
    PLATFORM_InitLED();

                //创建开始任务
    xTaskCreate(  start_task  ,      //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄    
                
    vTaskStartScheduler();          //开启任务调度
        
                while (1)
                {

                }        
}



//开始任务任务函数
void start_task(void *pvParameters)
{

    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    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);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led2_task,     
                (const char*    )"led2_task",   
                (uint16_t       )LED2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED2_TASK_PRIO,
                (TaskHandle_t*  )&LED2Task_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//LED0任务函数 
void led1_task(void *pvParameters)
{
    while(1)
    {
				

        GPIO_WriteBit(GPIOB, GPIO_Pin_15, 0);
        vTaskDelay(500);
			GPIO_WriteBit(GPIOB, GPIO_Pin_15, 1);
			vTaskDelay(500);

    }
}   

//LED1任务函数
void led2_task(void *pvParameters)
{
    while(1)
    {
			//	printf("task2\r\n");
        GPIO_WriteBit(GPIOB, GPIO_Pin_14, 0);
        vTaskDelay(200);
        GPIO_WriteBit(GPIOB, GPIO_Pin_14, 1);
        vTaskDelay(200);
    }
}



/********************************************** (C) Copyright MindMotion **********************************************/

下载到开发板上,可以可看到板载的两个LED灯会按不同的频率闪烁。

【printf卡死的问题】

经过查找资料,因为printf需要申请大的内存空间,因此必须把总栈分配大一些:

#define configTOTAL_HEAP_SIZE                           ( ( size_t ) ( 20 * 1024 ) )//配置FreeRTOS任务栈可用的RAM总量。

然后就可以正常的打印了。

image.png









关键词: Mini-F5265-OB     FreeRTOS     移植    

院士
2024-12-30 17:18:20     打赏
2楼

这个是传说中的Cortex-M33内核的吗?


院士
2024-12-31 22:56:10     打赏
3楼

玩得开心啊~~


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]