STM32F103移植FreeRTOS必须搞明白的系列知识---4(FreeRTOSConfig.h配置文件)

STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级)

STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

STM32F103移植FreeRTOS必须搞明白的系列知识---3(堆栈)

STM32F103移植FreeRTOS必须搞明白的系列知识---4(FreeRTOSConfig.h配置文件)
 

目录

一、FreeRTOSConfig.h配置文件概述

二、configCPU_CLOCK_HZ

三、configTICK_RATE_HZ

四、configMAX_PRIORITIES

五、configMINIMAL_STACK_SIZE

六、configTOTAL_HEAP_SIZE

七、configKERNEL_INTERRUPT_PRIORITY

八、configMAX_SYSCALL_INTERRUPT_PRIORITY 

九、实例

       1、配置configMAX_PRIORITIES

       2、配置configTOTAL_HEAP_SIZE

        3、配置configKERNEL_INTERRUPT_PRIORITY

        4、配置configMAX_SYSCALL_INTERRUPT_PRIORITY

        5、创建5个任务

        6、配置NVIC中断优先级组和抢占优先级和响应优先级


一、FreeRTOSConfig.h配置文件概述

        FreeRTOSConfig.h配置文件是由FreeRTOS官网提供给用户针对具体的某一款MCU并且独立于FreeRTOS内核的配置文件。

        要想实现STM32F103移植,必须熟悉FreeRTOSConfig.h配置文件中的以下几项(注:博主使用的FreeRTOS版本为FreeRTOS Kernel V10.2.1)。

         1、configCPU_CLOCK_HZ

         2、configTICK_RATE_HZ

         3、configMAX_PRIORITIES

         4、configMINIMAL_STACK_SIZE

         5、configTOTAL_HEAP_SIZE

         6、configKERNEL_INTERRUPT_PRIORITY

         7、configMAX_SYSCALL_INTERRUPT_PRIORITY 

二、configCPU_CLOCK_HZ

        写入实际的CPU内核时钟频率,也就是CPU指令执行频率。(stm32f103芯片的晶振为72MHZ。)

​        配置此值是为了正确的配置系统节拍中断周期。

        例如,在STM32F10X中,FreeRTOS Kernel V10.2.1

#define configCPU_CLOCK_HZ            ( ( unsigned long ) 72000000 )

三、configTICK_RATE_HZ

        FreeRTOS系统自己的节拍中断的频率。即一秒中断的次数,每次中断FreeRTOS都会进行任务调度。

        系统节拍中断用来测量时间,因此,越高的测量频率意味着可测到越高的分辨率时间。但是,高的系统节拍中断频率也意味着RTOS内核占用更多的CPU时间,因此会降低效率。RTOS演示例程都是使用系统节拍中断频率为1000HZ,这是为了测试RTOS内核,比实际使用的要高。(实际使用时不用这么高的系统节拍中断频率)
  多个任务可以共享一个优先级,RTOS调度器为相同优先级的任务分享CPU时间,在每一个RTOS 系统节拍中断到来时进行任务切换。高的系统节拍中断频率会降低分配给每一个任务的“时间片”持续时间。

  例如,在STM32F10X中,FreeRTOS Kernel V10.2.1

#define configTICK_RATE_HZ            ( ( TickType_t ) 1000 )

  表示滴答中断(SYSTICK)1毫秒中断1次。

  如果想让滴答中断(SYSTICK)100微秒中断1次,可以如下进行配置

#define configTICK_RATE_HZ            ( ( TickType_t ) 100 )


四、configMAX_PRIORITIES

        配置应用程序最大可用的优先级数目。

  在FreeRTOS内核中,每个有效优先级都会消耗一定量的RAM,因此这个值最好不要超过你的应用实际需要的优先级数目,FreeRTOS官网建议,宏configMAX_PRIORITIES最大数目不要超过32,那么工程项目可以使用的任务的优先级号范围为(0~31)

        每一个任务都会被分配一个优先级,任务的优先级值在0~ (configMAX_PRIORITIES - 1)之间。

        FreeRTOS任务优先级数值越,表示任务优先级越;FreeRTOS任务优先级数值越,表示任务优先级越

        空闲任务的优先级为0(tskIDLE_PRIORITY),因此它是最低优先级任务。

        例如,在STM32F103中,FreeRTOS Kernel V10.2.1

#define configMAX_PRIORITIES		( 5 )

        程序中给任务分配优先级时,可用的优先级号为:(0~configMAX_PRIORITIES-1)

        #define configMAX_PRIORITIES=5,因此工程项目中任务可用的优先级号范围为(0~4)。优先级号0被FreeRTOS内核固定分配给空闲任务;优先级号1,优先级号2,优先级号3,优先级号4都可以分配给用户任务。
        警告:优先级号5禁止分配给任务。如果优先级号5分配给任务,则会造成系统崩溃。

五、configMINIMAL_STACK_SIZE

        定义空闲任务使用的堆栈大小。

        通常此值不应小于对应处理器演示例程文件FreeRTOSConfig.h中定义的数值。

       例如,在STM32F103中,FreeRTOS Kernel V10.2.1

#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )

       在STM32F103中,堆栈大小不是以字节为单位,而是以字为单位的。在32位架构下,栈大小为128表示栈内存占用128*4=512字节的空间。

六、configTOTAL_HEAP_SIZE

        配置FreeRTOS任务栈可用的RAM总量。

        工程项目分配的所有任务都在该区域申请用户栈,每个任务的形参、非静态局部变量以及函数调用信息也在该区域申请空间。也就是说,工程项目中动态创建的每一个任务,都需要从configTOTAL_HEAP_SIZE空间申请栈区(称之为任务栈)

        工程项目中动态创建的每个任务从configTOTAL_HEAP_SIZE空间申请到栈区(称之为任务栈)后,该任务的形参、非静态局部变量以及函数调用信息都会使用这个栈区(称之为任务栈)进行入栈和出栈。

        例如,在STM32F10X中,FreeRTOS Kernel V10.2.1

#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 17 * 1024 ) )

        如果实际工程项目创建的任务比较大,可以增加configTOTAL_HEAP_SIZE空间,例如:

#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 25 * 1024 ) )

七、configKERNEL_INTERRUPT_PRIORITY

        设置FreeRTOS内核的中断优先级(内核PendSV中断和SysTick中断使用的中断优先级),因为FreeRTOS内核中断(PendSV中断和SysTick中断)不允许抢占用户使用的中断(例如:用户的USART1中断,用户的SPI1中断),因此这个宏configKERNEL_INTERRUPT_PRIORITY一般定义为硬件最低优先级(例如:15)

        对于STM32F103 Cortex-M3 内核而言,硬件最低优先级为15。因此宏configKERNEL_INTERRUPT_PRIORITY=255,参见下图。

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
/*这是Cortex-M3 NVIC的原始值。值可以是255(最低)到0(1?)(最高)*/ 
#define configKERNEL_INTERRUPT_PRIORITY 		255

        configKERNEL_INTERRUPT_PRIORITY=255和中断优先级15有什么联系呢?

        (1)、对于STM32F103Cortex-M3内核,只使用了8位中的高四位[7:4]作为中断优先级,低四位无任何意义,一般填充1。

        (2)、configKERNEL_INTERRUPT_PRIORITY=255,而255=1111 1111B,高4位的1111B=0x0F=15。所以,255就表示FreeRTOS内核的中断优先级号=15。

提示:

        (1)、宏configKERNEL_INTERRUPT_PRIORITY用于设置FreeRTOS内核PendSV中断和SysTick(滴答定时器)中断的中断优先级。

        (2)、port.c 中有如下定义:

#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )

八、configMAX_SYSCALL_INTERRUPT_PRIORITY 

        配置可受FreeRTOS内核控制的最高中断优先级号,这个宏配置的中断优先级号范围为(1~15),禁止将configMAX_SYSCALL_INTERRUPT_PRIORITY设置为0

       警告:宏configMAX_SYSCALL_INTERRUPT_PRIORITY的设置范围为1~15,千万不能将宏configMAX_SYSCALL_INTERRUPT_PRIORITY设置为0。因为中断优先级号0是专门用于SVC中断启动任务使用的。(内核启动中断vTaskStartScheduler())

        优先级号于这个宏(configMAX_SYSCALL_INTERRUPT_PRIORITY)的硬件中断,不受FreeRTOS管控,FreeRTOS无权用taskENTER_CRITICAL()函数禁止这些硬件中断,同时也不能在这些硬件中断中调用任何FreeRTOS API函数,否则系统会有崩溃的风险。优先级号于这个宏(configMAX_SYSCALL_INTERRUPT_PRIORITY)的硬件中断,才接受FreeRTOS的管控,FreeRTOS可以用taskENTER_CRITICAL()函数禁止这些硬件中断,FreeRTOS可以在这些硬件中断中调用FreeRTOS API函数,

        在文件portmacro.h 中,将宏(configMAX_SYSCALL_INTERRUPT_PRIORITY) 写入到BASEPRI 寄存器,最终对应于taskENTER_CRITICAL()函数,参见下图。

static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
{

uint32_t ulReturn, ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;
__asm
{

/* Set BASEPRI to the max syscall priority to effect a critical section. */
mrs ulReturn, basepri //先读出 BASEPRI 的值,保存在 ulReturn 中
msr basepri, ulNewBASEPRI //将 configMAX_SYSCALL_INTERRUPT_PRIORITY 写入到寄存器 BASEPRI 中。
dsb
isb
}
return ulReturn; //返回 ulReturn,退出临界区代码保护的时候要使用到此值
}

        例如,在STM32F10X中,FreeRTOS Kernel V10.2.1

/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY不能设置为零!!!! */
/*相当于0x5F或优先级5*/
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 95 /*equivalent to 0x50, or priority 5. */
 

        上面的代码中,配置configMAX_SYSCALL_INTERRUPT_PRIORITY中断优先级号为5。

        configMAX_SYSCALL_INTERRUPT_PRIORITY=95和中断优先级号5有什么联系呢?

        (1)、对于STM32F103Cortex-M3内核,只使用了8位中的高四位[7:4]作为中断优先级,低四位无任何意义,一般填充1。

        (2)、configMAX_SYSCALL_INTERRUPT_PRIORITY=95,而95=0101 1111B,高4位的0101B=0x05=5。所以,95就表示可受FreeRTOS管控的起始中断优先级号=5。

        1、如果配置configMAX_SYSCALL_INTERRUPT_PRIORITY = 95(0x5F也即中断优先级号为5),那么,中断优先级号为0~4  的中断不受FreeRTOS控制,用户不能在中断优先级号为0~4  的中断服务程序中调用以​FromISR结尾的API函数,否则会造成系统崩溃。

        2、如果配置configMAX_SYSCALL_INTERRUPT_PRIORITY = 95(0x5F也即中断优先级号为5),那么,中断优先级号为5~15  的中断可以接受FreeRTOS控制,用户可以在中断优先级号为5~15  的中断服务程序中调用以​FromISR结尾的API函数。

        3、如果用户在用户任务中调用关闭中断的API函数taskENTER_CRITICAL(); 如果中断优先级号为0~4的中断触发,那么用户关中闭断的操作不起任何作用,程序仍然会跳转到中断优先级号为0~4 的中断服务程序中执行。中断优先级号为0~4的中断称之为不受FreeRTOS控制的中断(原因:configMAX_SYSCALL_INTERRUPT_PRIORITY宏配置的优先级号为5,优先级号5及5以上的硬件中断才受FreeRTOS控制的控制;优先级号低于5以下的中断不受FreeRTOS控制的控制)。

        4、如果用户在用户任务中调用关闭中断的API函数taskENTER_CRITICAL(); 如果中断优先级号为5~15的中断触发,那么用户关闭中断的操作起作用,程序不会跳转到中断优先级号为5~15的中断服务程序中,仍然会执行用户任务中的程序,只有当用户任务中执行开中断API函数taskEXIT_CRITICAL();,系统才会去响应中断优先级号为5~15的中断,跳转到中断优先级号为5~15的中断服务程序中执行。

九、实例

       实际的工程项目需要:3个串口中断(USART1,USART2,USART3),1个定时器TIM2中断,创建5个任务,请问:该如何配置FreeRTOSConfig.h

       1、配置configMAX_PRIORITIES

             由于需要创建5个任务,因此宏configMAX_PRIORITIES=6。

#define configMAX_PRIORITIES		( 6 )

             任务优先级号1,分配给用户任务vTaskVoltage_Task(void *pvParameters)

             任务优先级号2,分配给用户任务vTaskDT_Poll_Task(void *pvParameters)

             任务优先级号3,分配给用户任务vTaskDT_Parse_Task(void *pvParameters)

             任务优先级号4,分配给用户任务vFreeModbus_Task(void *pvParameters)

             任务优先级号5,分配给用户任务vGPS_Task(void *pvParameters)

       2、配置configTOTAL_HEAP_SIZE

#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 20 * 1024 ) )

        3、配置configKERNEL_INTERRUPT_PRIORITY

        设置FreeRTOS内核的中断优先级=15。(内核PendSV中断和SysTick中断使用的中断优先级)    

/* 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

        4、配置configMAX_SYSCALL_INTERRUPT_PRIORITY

        设置可受FreeRTOS内核控制的最高中断优先级号=5。

        (1)、中断优先级号为0的中断禁止用户配置。

        (2)、中断优先级号为1~4的中断不受FreeRTOS内核控制

        (3)、中断优先级号为5~15的中断受FreeRTOS内核控制

/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY不能设置为零!!!! */
/*相当于0x5F或优先级5*/
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 95 /*equivalent to 0x50, or priority 5. */
 

        5、创建5个任务

	xTaskCreate( vTaskVoltage_Task,     	// 任务函数  
                 "vTaskStart",   			// 任务名    
                 512,            			// 任务栈大小,单位word,也就是4字节 
                 NULL,           			// 任务参数  
                 tskIDLE_PRIORITY + 1, 		// 任务优先级
                 &xHandleTaskVoltage);   	// 任务句柄  
	
	xTaskCreate( vTaskDT_Poll_Task,    		// 任务函数  
                 "vTaskDT_Poll",   				// 任务名    
                 //configMINIMAL_STACK_SIZE,// 任务栈大小,单位word,也就是4字节
				 512,            			// 任务栈大小,单位word,也就是4字节 
                 NULL,           			// 任务参数  
                 tskIDLE_PRIORITY + 2,		// 任务优先级
                 &xHandleTaskDT);  			// 任务句柄  		

	xTaskCreate( vTaskDT_Parse_Task,    	// 任务函数  
                 "vTaskDT_Parse",   		// 任务名    
                 //configMINIMAL_STACK_SIZE,// 任务栈大小,单位word,也就是4字节
				 512,            			// 任务栈大小,单位word,也就是4字节 
                 NULL,           			// 任务参数  
                 tskIDLE_PRIORITY + 3,		// 任务优先级
                 &xHandleTaskDT);  			// 任务句柄  				
			 
	xTaskCreate( vFreeModbus_Task,     		// 任务函数  
                 "vFreeModbus",   			// 任务名    
                 512,            			// 任务栈大小,单位word,也就是4字节 
                 NULL,           			// 任务参数  
                 tskIDLE_PRIORITY + 4,		// 任务优先级
                 &xHandleTaskFreeModbus);  	// 任务句柄  
			 

	xTaskCreate( vGPS_Task,     			// 任务函数  
                 "vGPS",   					// 任务名    
                 512,            			// 任务栈大小,单位word,也就是4字节 
                 NULL,           			// 任务参数  
                 tskIDLE_PRIORITY + 5,		// 任务优先级
                 &xHandleTaskGps);   		// 任务句柄  

        6、配置NVIC中断优先级组和抢占优先级和响应优先级

        (1)、优先级分组设置为NVIC_PriorityGroup_4

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); 

        中断优先级号为1~4的中断不受FreeRTOS内核控制,中断优先级号为5~15的中断受FreeRTOS内核控制。

        (2)、设置USART1的抢占优先级号=5

        (3)、设置USART2的抢占优先级号=6

        (4)、设置USART4的抢占优先级号=7

        (5)、设置TIM2定时中断的抢占优先级号=8

	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;	 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;	 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);	
	
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;	 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

致谢:

(20条消息) FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1_ba_wang_mao的博客-CSDN博客

  • 12
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
移植 FreeRTOSSTM32F103C8T6 上时,需要进行 FreeRTOSConfig.h 文件的配置。以下是一些常见的配置选项: 1. 配置时钟频率:根据你的实际情况,设置 configCPU_CLOCK_HZ 宏定义为 STM32F103C8T6 的时钟频率。 2. 配置优先级:根据你的应用需求,设置 configMAX_PRIORITIES 宏定义为需要支持的最大任务优先级。 3. 配置堆栈大小:根据你的应用需求,设置 configMINIMAL_STACK_SIZE 宏定义为你期望的最小任务堆栈大小。 4. 配置空闲任务堆栈大小:设置 configIDLE_STACK_SIZE 宏定义为空闲任务的堆栈大小。 5. 配置时钟节拍:设置 configTICK_RATE_HZ 宏定义为你希望的 FreeRTOS 时钟节拍频率。 6. 配置内存管理器:根据你的应用需求,选择使用 heap_1.c、heap_2.c、heap_3.c 或 heap_4.c 中的一个作为内存管理器。 7. 配置中断嵌套:如果你的应用需要使用中断嵌套,设置 configKERNEL_INTERRUPT_PRIORITY 宏定义为内核中断优先级的值,同时设置 configMAX_SYSCALL_INTERRUPT_PRIORITY 宏定义为用于系统调用的最高优先级。 8. 配置其他选项:根据你的应用需求,可以配置其他的 FreeRTOS 选项,如任务调度器的算法、任务队列长度等。 以上是一些常见的 FreeRTOSConfig.h 配置选项,你可以根据你的应用需求进行相应的修改和调整。同时,还需要根据你的硬件平台进行其他的移植工作,如配置中断和时钟等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值