本帖最后由 xiaoqi976633690 于 2024-6-24 11:47 编辑
#技术资源# #申请原创#
一、实验目的
在MM32F5330MCU上移植FreeRTOS,并运行2个task,打印信息。
二、实验代码
1.FreeRTOS移植
a.下载源码 freertos
https://www.freertos.org/zh-cn-cmn-s/
b.整理文件
核心文件在目录 源码\FreeRTOS\Source 下的.c和.h文件
.h文件在目录 源码\FreeRTOS\Source\include 下
接口文件在 源码\\FreeRTOS\Source\portable\GCC\ARM_CM33_NTZ\non_secure 下 源码\FreeRTOS\Source\portable\MemMang\heap_4.c 下
将以上文件copy出来,放入自己的工程内
keil目录拓扑
增加include路径
c.FREERTOSCONFIG.H文件修改
将freertos文件加入工程后就剩最后的freertos配置文件了。
主要注意以下几个配置
FREERTOSCONFIG.H文件定义
#include "platform.h"
extern uint32_t SystemCoreClock;
//configENABLE_TRUSTZONE 配置为0
#define configENABLE_MPU 0//MPU支持
#define configENABLE_FPU 1 //要启用 FPU 支持,请构建 FreeRTOS,并将 configENABLE_FPU 设置为一
#define configENABLE_TRUSTZONE 0 //TrustZone 支持
#define configMINIMAL_STACK_SIZE ( ( uint16_t ) 256 )/ /小了任务里面printf打印会有问题
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) ) //大了编译器报错
#define configCPU_CLOCK_HZ SystemCoreClock//系统时钟180000000
//注意mm32f5330_it.c要注释掉一下几个中断
#define SVC_Handler SVCall_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
完整配置文件
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
* http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
#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 ) 512 )
#define configMAX_TASK_NAME_LEN ( 12 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) )//大了会报错
#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 2048
/* 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 */
d.中断函数屏蔽
中断里面要屏蔽模板自带的几个中断入口函数,因为freertos已经帮我们实现了,为了防止编译报重定义所以需要屏蔽。
e. 移植打印tinyprintf
任务里面不能使用microlib自带的 pintf函数 不然卡死,这个坑了我好几天,移植都没啥问题就是进入调度后会卡死。
找了个小资源的tinyprintf 移植上来可以打印了,xprintf测试也可以
int uart1_sent(int ch)
{
UART_SendData(UART1, (uint8_t)ch);
while (RESET == UART_GetFlagStatus(UART1, UART_FLAG_TXC))
{
}
return (ch);
}
void tiny_sent ( void* p, char ch)
{
UART_SendData(UART1, (uint8_t)ch);
while (RESET == UART_GetFlagStatus(UART1, UART_FLAG_TXC))
{
}
}
xdev_out(uart1_sent);//xprintf 接口
init_printf(NULL,tiny_sent );//tinyprintf 接口
d.编译
2.任务创建
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO 2
//任务堆栈大小
#define LED1_STK_SIZE 50
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
//任务优先级
#define LED2_TASK_PRIO 3
//任务堆栈大小
#define LED2_STK_SIZE 50
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);
int uart1_sent(int ch)
{
UART_SendData(UART1, (uint8_t)ch);
while (RESET == UART_GetFlagStatus(UART1, UART_FLAG_TXC))
{
}
return (ch);
}
void tiny_sent ( void* p, char ch)
{
UART_SendData(UART1, (uint8_t)ch);
while (RESET == UART_GetFlagStatus(UART1, UART_FLAG_TXC))
{
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
PLATFORM_InitConsole(115200);
PLATFORM_InitLED();
xdev_out(uart1_sent);//xprintf 接口
init_printf(NULL,tiny_sent );//tinyprintf 接口
//创建开始任务
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)
{
//xprintf("task1 led1111111111111111111111111\r");
tfp_printf("task1 led1111111111111111111111111\r");
GPIO_WriteBit(GPIOB, GPIO_Pin_11, 0);
vTaskDelay(500);
GPIO_WriteBit(GPIOB, GPIO_Pin_11, 1);
vTaskDelay(500);
}
}
//LED1任务函数
void led2_task(void *pvParameters)
{
while(1)
{
xprintf("task2 led222222\r");
GPIO_WriteBit(GPIOB, GPIO_Pin_10, 0);
vTaskDelay(200);
GPIO_WriteBit(GPIOB, GPIO_Pin_10, 1);
vTaskDelay(200);
}
}
三、实验结果
四、实验心得
移植过程还是有很多需要注意的地方,由于没有M33内核太多参考很多报错和异常都需要自己去搜索引擎上查找相关信息。
但是通过对异常的解决可以加深自己对freertos的了解。
希望本帖能帮助大家减少开发过程中的异常。
|