FreeRTOS运行不稳定的原因记录

1.configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )报错

最近用FreeRTOS开发一个商用项目,用到了FreeRTOS,测试时发现一个奇怪的问题,代码运行一段时间后要么fault,要么某个任务像死了一样不在运行。找了很久没找到是什么问题,最后无奈,打开了FreeRTOS调试功能发现以下代码报错。

#if( configASSERT_DEFINED == 1 )

	void vPortValidateInterruptPriority( void )
	{
	extern uint32_t ulPortGetIPSR( void );
	uint32_t ulCurrentInterrupt;
	uint8_t ucCurrentPriority;

		ulCurrentInterrupt = ulPortGetIPSR();

		/* Is the interrupt number a user defined interrupt? */
		if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
		{
			/* Look up the interrupt's priority. */
			ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];

			/* The following assertion will fail if a service routine (ISR) for
			an interrupt that has been assigned a priority above
			configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
			function.  ISR safe FreeRTOS API functions must *only* be called
			from interrupts that have been assigned a priority at or below
			configMAX_SYSCALL_INTERRUPT_PRIORITY.

			Numerically low interrupt priority numbers represent logically high
			interrupt priorities, therefore the priority of the interrupt must
			be set to a value equal to or numerically *higher* than
			configMAX_SYSCALL_INTERRUPT_PRIORITY.

			Interrupts that	use the FreeRTOS API must not be left at their
			default priority of	zero as that is the highest possible priority,
			which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
			and	therefore also guaranteed to be invalid.

			FreeRTOS maintains separate thread and ISR API functions to ensure
			interrupt entry is as fast and simple as possible.

			The following links provide detailed information:
			http://www.freertos.org/RTOS-Cortex-M3-M4.html
			http://www.freertos.org/FAQHelp.html */
			configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
		}

		/* Priority grouping:  The interrupt controller (NVIC) allows the bits
		that define each interrupt's priority to be split between bits that
		define the interrupt's pre-emption priority bits and bits that define
		the interrupt's sub-priority.  For simplicity all bits must be defined
		to be pre-emption priority bits.  The following assertion will fail if
		this is not the case (if some bits represent a sub-priority).

		If the application only uses CMSIS libraries for interrupt
		configuration then the correct setting can be achieved on all Cortex-M
		devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
		scheduler.  Note however that some vendor specific peripheral libraries
		assume a non-zero priority group setting, in which cases using a value
		of zero will result in unpredicable behaviour. */
		configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
	}

#endif /* configASSERT_DEFINED */

该代码在port.c文件内,具体报错位置是:

configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

该报错意思是当前中断的优先级大于系统能够管理的优先级。

在FreeRTOS内有一个configMAX_SYSCALL_INTERRUPT_PRIORITY的宏,它是配置FreeRTOS能够管理中断的最大优先级,在FreeRTOS内中断优先级分组只能全部配置成抢占优先级,没有子优先级,FreeRTOS也没有处理子优先级的代码。在FreeRTOS内只有大于configMAX_SYSCALL_INTERRUPT_PRIORITY才能调用FreeRTOS API(中断优先级很低),小于configMAX_SYSCALL_INTERRUPT_PRIORITY不能调用FreeRTOS的API(中断优先级很高),如果调用了就会出现上述问题,经查我的代码内中断的优先级很高,比系统能够管理的中断优先级还要高,还在中断内调用了FreeRTOS的API,该语句就会报错configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )。将中断优先级调低,FreeRTOS运行不稳定的问题成功解决,跑了一个月都没有死。

2.configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 )报错。

此处报错,第一种是因为高于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断调用了RTOS的API导致的,解决办法,将中断优先级调低,比configMAX_SYSCALL_INTERRUPT_PRIORITY要低,就可以调用RTOS的API了。

第二种是因为中断发送消息队列,发送信号量等操作使用了不带ISR结尾的API,而是调用了普通不带ISR的API导致的,解决办法,将API替换为带ISR结尾的API便可以解决问题。

你可能感兴趣的:(嵌入式,嵌入式,stm32,freertos)