Comprendre les fonctions liées à la gestion de la mémoire uCOS

Bloc de contrôle du pool de mémoire :

structure os_mem {   

    Type OS_OBJ_TYPE ; /* Doit être défini sur OS_OBJ_TYPE_MEM */

    void *AddrPtr; //La position de départ du pool de mémoire 

    CPU_CHAR *NamePtr; //Nom du pool de mémoire

    void *FreeListPtr; //Pointe vers la liste des blocs de mémoire libres (le premier bloc de mémoire de la liste)

    OS_MEM_SIZE BlkSize; //La taille de chaque bloc mémoire

    OS_MEM_QTY NbrMax; //Le nombre total de blocs de mémoire

    OS_MEM_QTY NbrFree; //Nombre de blocs de mémoire libres

    OS_MEM *DbgPrevPtr; //Pointez vers le pool de mémoire précédent dans la liste de débogage

    OS_MEM *DbgNextPtr; //Pointez vers le pool de mémoire suivant dans la liste de débogage

    CPU_INT32U MemID; // L'ID unique des débogueurs et traceurs tiers 

} ;

Fonction de gestion de la mémoire : Étant donné que la gestion de la mémoire est effectuée via le bloc de contrôle du pool de mémoire, tout comme le bloc de contrôle des tâches d'opération de tâche, les fonctions liées à la gestion de la mémoire implémentent également les fonctions correspondantes en exploitant les valeurs des éléments du bloc de contrôle du pool de mémoire.

{

OSMemCreate : fonction de création de pool de mémoire

{

Idée de fonction : deux choses : l'une consiste à initialiser le bloc de contrôle du pool de mémoire et à attribuer des valeurs initiales à ses éléments. La seconde consiste à diviser le pool de mémoire en blocs et à enchaîner les blocs de mémoire dans une liste unidirectionnelle.

6 paramètres d'entrée : pointeur p_mem pointant vers le bloc de contrôle du pool de mémoire ; nom du pool de mémoire p_name ; adresse de début du pool de mémoire p_addr ; nombre de blocs de mémoire n_blks ; taille de bloc de mémoire unique blk_size (en octets) ; type d'erreur renvoyé p_err.

Processus fonctionnel : ① Effectuez d'abord un contrôle de sécurité, un contrôle d'appel illégal pendant une interruption et un contrôle des paramètres. Lors du contrôle des paramètres, le nombre de blocs mémoire n_blks est d'au moins deux ; la taille du bloc mémoire blk_size est d'au moins quatre octets ; ce qui équivaut à un bloc mémoire d'au moins deux octets. Il est nécessaire que la première adresse du pool de mémoire soit alignée sur quatre octets, c'est-à-dire que la première adresse doit être un multiple de 4. C'est facile à juger. Il suffit de ET la première adresse avec 0x03. Si c'est 0, cela signifie un alignement. Car à l'exception des deux bits les plus bas d'un nombre binaire : l'un représente 1 et l'autre représente 2, les autres bits de poids fort sont tous des multiples de 4, donc tant que les deux derniers bits de l'adresse de haut en bas sont 0, la somme le nombre décimal doit être un multiple de 4. Ensuite, l'alignement peut être déterminé en calculant le ET au niveau du bit (~) sous forme binaire . Il est également nécessaire de déterminer si la taille du bloc mémoire blk_size est un multiple de 4. Vous pouvez utiliser la même méthode pour la déterminer, car le paramètre uCOS est que la taille du bloc mémoire doit pouvoir accueillir un nombre entier de pointeurs, et la taille du pointeur système 32 bits est de 4 octets. ② Tout d'abord, connectez les blocs de mémoire dans une liste chaînée. Créer une liste chaînée est très simple : l'adresse de départ p_addr du pool de mémoire est également l'adresse du premier bloc mémoire, et les adresses des premiers éléments du tableau sont consécutives ; entrez ensuite la boucle for et laissez le bloc mémoire précédent pointer vers le bloc mémoire suivant. Le dernier bloc mémoire pointe vers NULL. Le nombre d'itérations de la boucle for est le nombre de blocs mémoire n_blks moins 1 ( par exemple : 3 nœuds sont connectés pour former une liste chaînée unique, seules deux connexions sont nécessaires ). ③ Initialisez les éléments du bloc de contrôle du pool de mémoire. Y compris la position de départ du pool de mémoire, l'adresse du bloc de mémoire libre, le nombre maximum de blocs de mémoire, le nombre de blocs de mémoire libres et la taille du bloc de mémoire. ④ Si la liste de débogage est activée, appelez OS_MemDbgListAdd() pour ajouter le pool de mémoire à la liste de débogage. La variable globale OSMemQty qui compte le nombre de pools de mémoire est incrémentée de 1 et enfin un type sans erreur est renvoyé.

}

OSMemGet() : fonction d'application mémoire 

{

Idée de fonction : Vous ne pouvez demander qu'un seul bloc de mémoire, et vous pouvez l'appeler autant de fois que vous le souhaitez. S'il y a encore un bloc mémoire disponible, l'adresse mémoire correspondante est renvoyée ; sinon, NULL est renvoyé.

2 paramètres d'entrée : pointeur de bloc de contrôle du pool de mémoire p_mem ; type d'erreur renvoyé p_err.

Retour : Cette fonction est un type de fonction pointeur et renvoie un pointeur void *. S'il n'y a pas d'erreur, un pointeur vers le bloc mémoire demandé est renvoyé ; s'il y a une erreur, NULL est renvoyé.

Processus fonctionnel : ① Assurer la sécurité. Vérification des paramètres. ② Pour demander un bloc de mémoire, il est bien entendu nécessaire de déterminer s'il existe un bloc de mémoire libre dans le pool de mémoire. L'élément NbrFree dans le bloc de contrôle du pool de mémoire représente le nombre de blocs de mémoire libres. S'il n'y a pas de bloc de mémoire libre (0), le type d'erreur renvoyé est "OS_ERR_MEM_NO_FREE_BLKS" et renvoie (void *)0. ③ S'il y a un bloc de mémoire libre, obtenez l'adresse du bloc de mémoire libre actuel (élément de bloc de contrôle du pool de mémoire FreeListPtr), puis mettez à jour le bloc de mémoire libre, c'est-à-dire laissez FreeListPtr pointer vers le prochain bloc de mémoire libre, c'est-à-dire p_mem->FreeListPtr = *( void **)p_blk. Le nombre de blocs mémoire disponibles NbrFree est réduit de 1, aucune erreur n'est renvoyée et l'adresse du bloc mémoire demandée est renvoyée.

}

OSMemPut : fonction de libération de mémoire

{

Idée de fonction : Lorsque le bloc mémoire est épuisé, il doit être immédiatement libéré pour une autre utilisation. Libérer un bloc mémoire consiste à réinsérer le bloc mémoire dans la liste libre du pool mémoire. J'ai trouvé non. La fonction d'application de mémoire est obtenue une par une selon la liste libre du pool de mémoire FreeListPtr. Elle est appliquée depuis le début, et le dernier bloc mémoire pointe vers NULL. Par conséquent, le bloc de mémoire libéré par la fonction de libération de mémoire doit également être inséré en tête de la liste libre du pool de mémoire.

3 paramètres d'entrée : pointeur de pool mémoire p_mem ; pointeur de bloc mémoire à libérer p_blk ; type d'erreur renvoyé p_err.

Processus fonctionnel : ① Effectuer un contrôle de sécurité et une vérification des paramètres. ② La fonction de libération d'uCOS semble être appelée un nombre illimité de fois. Tout d'abord, déterminez si le nombre de blocs de mémoire disponibles NbrFree est supérieur au nombre maximum de blocs de mémoire dans le pool de mémoire NbrMax. S'il est supérieur ou égal à cela, cela signifie que tous les blocs de mémoire ont été libérés et qu'il n'est pas nécessaire de continuer. Pour les étapes, renvoyez simplement le type d'erreur correspondant et revenez directement. ③ S'il existe effectivement un bloc de mémoire non libéré, insérez-le en tête de la liste des pools de mémoire libres. Cela nécessite uniquement de modifier le pointeur FreeListPtr pour pointer vers le bloc de mémoire libéré, puis de pointer le bloc de mémoire libéré vers le bloc de mémoire vers lequel FreeListPtr a initialement pointé. Mettez ensuite à jour le nombre de blocs mémoire disponibles : NbrFree plus 1 ; aucune erreur n'est renvoyée après l'interface utilisateur.

}

}

Guess you like

Origin blog.csdn.net/m0_43443861/article/details/126442364