简介
STM32F1太常用了,因为官网已经把移植的工作做的很完善了,只要文件放到相应工程里就可以使用,这里只做一个简单的DEMO,记录下FreeRTOS正常启动的流程
CUBEMX配置
1.新建CUBEMX工程,使用SWD的情况先配置SWD设置,防止第一次烧录后,后续无法使用
2.由于FreeRTOS有重新使用到SYSTICK(滴搭定时器),port.c之中,有systick的新配置与响应,因此HAL库的基础时钟,要由SYSTICK改为其他时钟,如TIM2
3.配置时钟,根据实际情况配置即可,此处使HSE,8M,PLL输入作为系统时钟,72M主频
4.SYSTICK,PENDSV,SVC等系统中断,有被FreeRTOS,重新配置使用到。因此CUBEMX输出代码的时候都不能输出这个定义,不然编译时会报错,配置如下
5.基本的DEMO配置的基本参数已配置好,可以再配置下DEMO中,有用到的管脚,这里使PE5,PB5作为DEMO,IO输出管脚,用于后续的,就可以生成DEMO代码了
FreeRTOS源码放置
1.下载FreeRTOS源码,下载LTS版本
2.下载过来的FreeRTOS中的源码,并不是我们需要全部,只需将其中的FreeRTOS-Kernel文件夹下,拷贝出来即可,拷贝到工程下的FreeRTOS/Source文件夹中
3.最小FreeRTOS系统的情况下,内核只需要task.c,list.c,queue.c三个文件即可,同时工程还要需添加官方写好的port.c(portable/RVDS/ARM_CM3)的文件,根据自己的编译环境与芯片类型来选择相应的文件,
添加HEAP文件,默认推荐为heap_4.c(portable/MemMang)
4.添加FreeRTOSConfih.h,FREERTOS的配置文件内容如下,也可以根据编译错误提示修改相应的配置
由于是最小的系统因此关闭了很多类于HOOK调用的函数,关闭静态分配内存等
具体如下
点击查看代码
/*
* FreeRTOS Kernel V10.4.6
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* 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.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
//extern volatile uint32_t SystemCoreClock;
extern uint32_t SystemCoreClock;
#endif
/*-----------------------------------------------------------
* 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 configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 5 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configGENERATE_RUN_TIME_STATS 0
/* Software timer definitions. */
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH ( 128 )
/* 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 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#if (1) /* Specific priority configuration for non-Cortex-M0/M0+. */
/* Cortex-M specific definitions. */
#define configPRIO_BITS 4
/* The lowest interrupt priority that can be used in a call to a "set priority"
* function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* 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 ) )
#endif /* Specific priority configuration for non-Cortex-M0/M0+. */
/* Normal assert() semantics without relying on the provision of an assert.h
* header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
* standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#endif /* FREERTOS_CONFIG_H */
5.配置好INCLUDE文件路径
新建TASK
void vTask1(void *pvParameters)
{
for(;;)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);
vTaskDelay(1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
vTaskDelay(1000);
}
}
void vTask2(void *pvParameters)
{
for(;;)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
vTaskDelay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
vTaskDelay(500);
}
}
main函数中添加任务,同时开启调度
xTaskCreate(vTask1, "LED1", 128, NULL, 1, NULL);
xTaskCreate(vTask2, "LED2", 128, NULL, 1, NULL);
vTaskStartScheduler();
运行
编译后下载到线路板中,就可以实现FreeRTOS最小系统的使用了
总结
FreeRTOS是很成熟的操作系统,STM32F1也是很常用的MCU,因此在STM32上面使用FreeRTOS,基本上不用修改代码,工程配置好就可以使用了
同时CUBEMX里面也可以直接添加FreeRTOS来使用,只是CUBEMX生成FreeRTOS,上面又封装了一层API,如果已经习惯了FreeRTOS的用户去使用的话,就需要再学习下新的API,
手工添加代码,直接使用FreeRTOS本身的API,也是一个很好的选择。
FreeRTOS移植成功,只是开了个头,后面API的学习,以及在系统变得复杂时,对嵌入式操作系统的理解(信号量、互斥、优先级、中断处理、调度、队列等),合理分配系统的资源来完成具体的应用,才是后面的重点。
移植成功,离真正到项目中去做还需要一定的学习与练习。