一直没亲手移植过FreeRTOS,心血来潮移植了下最新版的FreeRTOSv202104.00
过程不赘述,可以参考 https://www.cnblogs.com/iot-dev/p/11681067.html,写的还是非常详细的。
task还是常见的LED1 LED2 闪烁加UART的打印,期间遇到了几个问题,如下
1.程序跑过了 vTaskStartScheduler(); //开启调度,继续往校跑
2.进入HardFault_Handler(这个应该是为#define configTOTAL_HEAP_SIZE 设置的太小)
3.程序卡到 while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
总结还是应从下面几点入手:
1、三个重要的中断函数SysTick、PendSV_Handler()与SVC_Handler()
这三个函数数在stm32f10x_it.c文件中和FreeRTOS 的port.c文件中都实现了。
一般stm32f10x_it.c文件里的都是空函数当然是不能用的,可以直接使用FreeRTOS 的port.c文件中的这三个函数。
首先是PendSV_Handler()与SVC_Handler()。在stm32f10x_it.c中注释掉PendSV_Handler()与SVC_Handler()这两个函数的函数体,声明不要注释,并在FreeRTOSConfig.h加上下面两句
/****************************************************************
FreeRTOS与中断服务函数有关的配置选项
****************************************************************/
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
接着是SysTick,在stm32f10x_it.c文件中增加extern void xPortSysTickHandler(void),原来的函数体内增加代码如下
extern void xPortSysTickHandler(void);
//systick中断服务函数
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
注:有些网上的文章写增加#define xPortSysTickHandler SysTick_Handler,直接加到FreeRTOSConfig.h肯定会报错,因为stm32f10x_it.c文件中和FreeRTOS 的port.c的SysTick_Handler冲突了,如果注释掉stm32f10x_it.c中的SysTick_Handler虽然不报错了,但也是FreeRTOS也是跑不起来的。原因如下图,在startup_stm32f10x_md.s中同样会用到这个函数,这是一个很重要的函数,我们需要在stm32f10x_it.c文件中实现STM32平台上的SysTick_Handler()函数
2.#define configTOTAL_HEAP_SIZE 不能设置的太小,任务栈的大小设置不合理
本人尝试下面这个,设置的大小倒影响不大,只要大于0就可以,但他关系到configTOTAL_HEAP_SIZE 设置的大小
#define configMINIMAL_STACK_SIZE
本人创建了三个任务如下
static void AppTaskCreate(void);/* 用于创建任务 */
static void LED1_Task(void* pvParameters);/* LED1_Task任务实现 */
static void LED2_Task(void* pvParameters);/* LED2_Task任务实现 */
开始时AppTaskCreate、LED1_Task、LED2_Task的堆栈和configMINIMAL_STACK_SIZE 分别设置为1024,实测发现configTOTAL_HEAP_SIZE 要设置到24*1024才能正常运行。
接着尝试最小配置(只取2^n),configMINIMAL_STACK_SIZE 可以配置为1,没发现什么问题,0就不可以了。AppTaskCreate、LED1_Task、LED2_Task的堆栈可以设置到64,设置到32会有灯不闪烁,这里应该和打印为字符数有关系。这时configTOTAL_HEAP_SIZE 基本可以设置到
2*1024,设置为1*1024会有一个灯不闪烁。
最小配置main.c和FreeRTOSConfig.h如下。
就这样移植任务圆满结束,希望对大家有所帮助吧。
main.c
//头文件
#include "stm32f10x.h"
#include "usart.h"
#include "led.h"
#include "RTC_Time.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "GPIOLIKE51.h"
/* 创建任务句柄 */
static TaskHandle_t AppTaskCreate_Handle = NULL;
/* LED1任务句柄 */
static TaskHandle_t LED1_Task_Handle = NULL;
/* LED2任务句柄 */
static TaskHandle_t LED2_Task_Handle = NULL;
/*
*************************************************************************
* 函数声明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于创建任务 */
static void LED1_Task(void* pvParameters);/* LED1_Task任务实现 */
static void LED2_Task(void* pvParameters);/* LED2_Task任务实现 */
//=============================================================================
//函数名称:main
//功能概要:主函数
//参数说明:无
//函数返回:int
//=============================================================================
int main(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
LED_GPIO_Config();//初始化LED
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
USART1_Config();
printf("FreeRTOS temp\r\n");
/* 创建AppTaskCreate任务 */
xReturn=0;
xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */
(const char* )"AppTaskCreate",/* 任务名字 */
(uint16_t )64, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )3, /* 任务的优先级 */
(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
/* 启动任务调度 */
if(pdPASS == xReturn)
{
printf("xRet P \r\n");
vTaskStartScheduler(); /* 启动任务,开启调度 */
printf("StarSche \r\n");
}
else
{
return -1;
printf("StarSche Fail\r\n");
}
// while (1);
printf("error\r\n");
}
/***********************************************************************
* @ 函数名 : AppTaskCreate
* @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
* @ 参数 : 无
* @ 返回值 : 无
**********************************************************************/
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
taskENTER_CRITICAL(); //进入临界区
/* 创建LED_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )LED1_Task, /* 任务入口函数 */
(const char* )"LED1",/* 任务名字 */
(uint16_t )64, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )4, /* 任务的优先级 */
(TaskHandle_t* )&LED1_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
printf("task LED1\r\n");
/* 创建LED_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )LED2_Task, /* 任务入口函数 */
(const char* )"LED2",/* 任务名字 */
(uint16_t )64, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )5, /* 任务的优先级 */
(TaskHandle_t* )&LED2_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
printf("task LED2\r\n");
vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
taskEXIT_CRITICAL(); //退出临界区
}
/**********************************************************************
* @ 函数名 : LED_Task
* @ 功能说明: LED_Task任务主体
* @ 参数 :
* @ 返回值 : 无
********************************************************************/
static void LED1_Task(void* parameter)
{
while (1)
{
PAout(8)=1; // LED1_ON;
vTaskDelay(500); /* 延时500个tick */
printf("LED1_ON\r\n");
PAout(8)=0; // LED1_OFF;
vTaskDelay(500); /* 延时500个tick */
printf("LED1_OFF\r\n");
}
}
/**********************************************************************
* @ 函数名 : LED_Task
* @ 功能说明: LED_Task任务主体
* @ 参数 :
* @ 返回值 : 无
********************************************************************/
static void LED2_Task(void* parameter)
{
while (1)
{
PDout(2)=1;// LED2_ON;
vTaskDelay(500); /* 延时500个tick */
printf("LED2_ON\r\n");
PDout(2)=0; // LED2_OFF;
vTaskDelay(500); /* 延时500个tick */
printf("LED2_OFF\r\n");
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
FreeRTOSConfig.h
/*
* FreeRTOS V202104.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#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.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 10 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 1 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
//支持动态内存申请
#define configSUPPORT_DYNAMIC_ALLOCATION 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#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
///* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
//(lowest) to 0 (1?) (highest). */
//#define configKERNEL_INTERRUPT_PRIORITY 255
///* !!!! 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 191 /* equivalent to 0xb0, or priority 11. */
/******************************************************************
FreeRTOS与中断有关的配置选项
******************************************************************/
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
//中断最低优先级
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
//系统可管理的最高中断优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15. This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 10
//added by zude 2021.0627
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#endif /* FREERTOS_CONFIG_H */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)