Mécanisme de détection de débordement de pile FreeRTOS_analyse du code source attaché

1. Activez la fonction de détection de débordement de pile

freertos fournit une fonction de détection de débordement de pile, qui peut être activée en définissant la macro configCHECK_FOR_STACK_OVERFLOW dans le fichier FreeRTOSConfig.h , et l'opération de détection de débordement de pile sera automatiquement effectuée lorsque la tâche est commutée

/*
 * 大于0时启用堆栈溢出检测功能,如果使用此功能 
 * 用户必须提供一个栈溢出钩子函数,如果使用的话
 * 此值可以为1或者2,因为有两种栈溢出检测方法 */
#define configCHECK_FOR_STACK_OVERFLOW			1   

2. Le premier mécanisme de détection de débordement de pile

Lorsque la macro configCHECK_FOR_STACK_OVERFLOW vaut 1, le premier mécanisme de détection de débordement de pile est adopté. En comparant le pointeur supérieur de pile et le pointeur de début de pile ou
le pointeur supérieur de pile et le pointeur inférieur de pile,
le code source de FreeRTOS est le suivant

insérez la description de l'image ici


3. Le deuxième mécanisme de détection de débordement de pile

Lorsque la macro configCHECK_FOR_STACK_OVERFLOW vaut 2, le deuxième mécanisme de détection de débordement de pile est utilisé
pour juger si les 16 derniers octets de données dans l'espace de pile sont tous égaux à 0xa5 . Si l'un d'eux n'est pas égal à 0xa5, cela signifie que la pile peut Ce qui suit
est le code source de FreeRTOS

3.1 Lorsque la pile grandit vers le bas : déterminer si les 4 premiers octets de données de la pile ont été modifiés

insérez la description de l'image ici

3.2 Lorsque la pile grandit vers le haut : déterminer si les 20 octets de données en fin de pile ont été modifiés

insérez la description de l'image ici

D'où vient 0xa5, voir le code source

Lors de l'utilisation de la fonction vTaskCreate pour créer une nouvelle tâche, si la valeur de la macro configCHECK_FOR_STACK_OVERFLOW est 2,
l'espace de la pile sera rempli avec 0x5a (macro taskSTAC_FILL_BYTE)

insérez la description de l'image ici


4. Déterminer le moment du débordement de la pile

Bien sûr, lorsque la tâche est commutée, c'est-à-dire dans la fonction vTaskSwitchContext(void) , la fonction
taskCHECK_FOR_STACK_OVERFLOW() est appelée dans cette fonction Cette fonction est visible dans les deux premières images ci-dessus, mais elle n'est pas marquée.

void vTaskSwitchContext( void )
{
    
    
	if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
	{
    
    
		/* The scheduler is currently suspended - do not allow a context
		switch. */
		xYieldPending = pdTRUE;
	}
	...
	...
	/* Check for stack overflow, if configured. */
	taskCHECK_FOR_STACK_OVERFLOW();  //检查栈溢出
	...
	...
}	

À ce stade, le mécanisme de détection de débordement de pile de FreeRTOS a été clarifié, oui !


5. Avantages et inconvénients des deux méthodes

première méthode :

  1. Avantages : rapide
  2. Inconvénients : impossible de détecter tous les débordements de pile. Par exemple, le pointeur du haut de la pile franchit les limites pendant l'exécution de la tâche, mais le pointeur du haut de la pile pointe vers la position légale avant le changement de tâche. À ce stade, le dépassement de pile ne peut pas être détecté.

Deuxième méthode :

  1. Avantages : légèrement plus lent que la première méthode (mais toujours rapide pour les utilisateurs)
  2. Inconvénients : bien que presque toutes les situations de débordement de pile puissent être détectées, si la valeur de débordement de pile est identique à la valeur de la marque de pile lorsque la pile déborde , c'est-à-dire que les quatre derniers octets de l'espace de pile sont exactement 0xa5, le débordement de pile ne peut pas être détecté dans ce cas

6. Comment éviter le débordement de pile

Blog de référence : https://blog.csdn.net/fanxueya1322/article/details/86567390

  • Estimez la taille de la pile de tâches à l'avance et définissez la taille de la pile de tâches sur deux fois la taille de mémoire requise par la tâche
  • Pour réduire la demande d'espace de pile, ne définissez pas de variables automatiques qui occupent beaucoup de mémoire . Vous devez modifier ces variables en pointeurs et allouer de la mémoire à partir de l'espace du tas .
  • Ne transmettez pas de grandes structures/unions/objets dans les paramètres de fonction , utilisez des références ou des pointeurs comme paramètres de fonction.
  • Réduisez le niveau des appels de fonction et utilisez les fonctions récursives avec prudence , telles que A->B->C->A ring call.

Je suppose que tu aimes

Origine blog.csdn.net/HuangChen666/article/details/131911863
conseillé
Classement