Galerie de cartes mentales Noyau léger OpenHarmony
Le noyau est le cœur informatique d'un système d'exploitation autonome et détermine les performances et la stabilité du système. Il s'agit de la première couche d'extension logicielle basée sur le matériel, qui fournit les fonctions de base du système d'exploitation et constitue la base du fonctionnement du système d'exploitation. Il est responsable de la gestion des processus, de la mémoire, des pilotes de périphériques, des composants et des systèmes réseau du système.
Modifié à 2024-02-08 16:08:42Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
La gestion de projet est le processus qui consiste à appliquer des connaissances, des compétences, des outils et des méthodologies spécialisés aux activités du projet afin que celui-ci puisse atteindre ou dépasser les exigences et les attentes fixées dans le cadre de ressources limitées. Ce diagramme fournit une vue d'ensemble des 8 composantes du processus de gestion de projet et peut être utilisé comme modèle générique.
Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
Cent ans de solitude est le chef-d'œuvre de Gabriel Garcia Marquez. La lecture de ce livre commence par l'analyse des relations entre les personnages, qui se concentre sur la famille Buendía et raconte l'histoire de la prospérité et du déclin de la famille, de ses relations internes et de ses luttes politiques, de son métissage et de sa renaissance au cours d'une centaine d'années.
La gestion de projet est le processus qui consiste à appliquer des connaissances, des compétences, des outils et des méthodologies spécialisés aux activités du projet afin que celui-ci puisse atteindre ou dépasser les exigences et les attentes fixées dans le cadre de ressources limitées. Ce diagramme fournit une vue d'ensemble des 8 composantes du processus de gestion de projet et peut être utilisé comme modèle générique.
Noyau léger OpenHarmony
Aperçu
Le noyau est le cœur informatique d'un système d'exploitation autonome et détermine les performances et la stabilité du système. Il s'agit de la première couche d'extension logicielle basée sur le matériel, qui fournit les fonctions de base du système d'exploitation et constitue la base du fonctionnement du système d'exploitation. Il est responsable de la gestion des processus du système, de la mémoire, des pilotes de périphériques, des composants et des systèmes réseau.
LiteOS-M
Aperçu
Dispositif de mémoire de niveau CentK
Supporte l'unité de protection de la mémoire
Convient aux systèmes légers
Appliqués aux systèmes légers, les MCU disposent généralement de centaines de mémoire de niveau K et peuvent prendre en charge l'isolation MPU. Les noyaux similaires dans l'industrie incluent FreeRToS ou Threadx, etc.
Présentation du noyau
L'architecture du noyau LiteOS-M comprend des couches liées au matériel et des couches indépendantes du matériel. Les couches liées au matériel sont classées selon différentes chaînes d'outils de compilation et architectures de puces. Fournir un HAL (Hardware Abstraction Layer) unifié Les autres modules de l'interface appartiennent à la couche indépendante du matériel. Parmi eux, le module de base du noyau fournit des fonctionnalités de base. Les modules d'extension fournissent des fonctionnalités de réseau, de système de fichiers et d'autres composants Le module KAL (Kernel Abstraction Layer) fournit une interface standard unifiée
L'interface HAL (HardwareAbstractionLayer) améliore l'adaptabilité du matériel et répond à l'expansion des riches types de matériel et des chaînes d'outils de compilation d'AloT.
Gestion de la mémoire
mémoire statique
mémoire dynamique
mécanisme de communication
événement
verrouillage
file d'attente des messages
signal
CMSIS (Cortex Microcontroller Software InterfaceStandard, norme d'interface logicielle pour microcontrôleur) et POSIX (interface de système d'exploitation portable, interface de système d'exploitation portable) Ce sont toutes des normes pour les interfaces d'exploitation portables et appartiennent à la couche d'interface d'application, ce qui peut améliorer la portabilité des logiciels d'application et réduire les difficultés de développement.
CMSIS (Cortex Microcontroller Software InterfaceStandard, norme d'interface logicielle pour microcontrôleur)
CMSIS est une couche d'abstraction matérielle indépendante du fournisseur pour les microcontrôleurs basés sur les processeurs ARM Cortex. Il contient plusieurs couches de composants, dont la couche RTOS. Cette couche définit un ensemble d'interfaces API RTOS communes et standardisées, ce qui réduit la dépendance des développeurs d'applications à l'égard de RTOS spécifiques et facilite la transplantation et la réutilisation des logiciels utilisateur. Cet ensemble d'API comporte 2 versions, à savoir la version 1 (CMSIS-RTOSv1) et la version 2 (CMSIS-RTOSv2) OpenHarmonyLiteos-M fournit uniquement l'implémentation de la version 2.
POSIX (interface de système d'exploitation portable, interface de système d'exploitation portable)
Le noyau OpenHarmony utilise la bibliothèque musl libc et des interfaces auto-développées, et prend en charge certaines interfaces POSIX standard. Les développeurs peuvent développer des composants et des applications sur le noyau basés sur des interfaces standard POSIX.
Processus de démarrage du noyau LiteOS-M
1. Configurez l'horloge système et les ticks par seconde dans le fichier de configuration de la carte de développement targetconfig.h. Vous pouvez personnaliser la configuration des modules de tâches, de mémoire, d'IPC et de gestion des exceptions.
2. Lorsque le système est redémarré, la configuration racine initialisera le module spécifié.
3. Le processus de démarrage du noyau comprend l'initialisation des périphériques, la configuration de l'horloge système, l'initialisation du noyau, le démarrage du système d'exploitation, etc. Pour plus de détails, consultez le processus de démarrage du noyau.
LiteOS-M prend déjà en charge les architectures grand public telles que ARMCortex-M3, ARMCortex-M4, ARMCortex-M7, ARM Cortex-M33 et RISc-V.
Bases du noyau
gestion des tâches
décrire
Du point de vue du système, une tâche est la plus petite unité en cours d'exécution qui est en compétition pour les ressources système. Les tâches peuvent attendre le processeur, utiliser l'espace mémoire et d'autres ressources système et s'exécuter indépendamment des autres tâches.
Le module de tâches de Liteos-M peut fournir aux utilisateurs plusieurs tâches, réaliser la commutation entre les tâches et aider les utilisateurs à gérer les processus des programmes métier.
Le module de tâches a les caractéristiques suivantes
Prise en charge du multitâche
Une tâche représente un fil
Mécanisme de planification préemptive
Les tâches à haute priorité peuvent interrompre les tâches à faible priorité, et les tâches à faible priorité doivent être bloquées ou terminées avant de pouvoir être planifiées.
Les tâches avec la même priorité prennent en charge la planification de rotation des tranches de temps.
Il y a 32 priorités [0-31], la priorité la plus élevée est 0 et la priorité la plus basse est 31
Statut de la tâche
L'état bloqué inclut les tâches suspendues (état de suspension), les tâches retardées (état de retard), les tâches qui attendent des sémaphores, des files d'attente de lecture-écriture ou des événements en attente, etc.
État prêt -> État en cours d'exécution : une fois la tâche créée, elle passe à l'état prêt. Lorsqu'un changement de tâche se produit, la tâche la plus prioritaire dans la file d'attente prête est exécutée et passe en même temps à l'état d'exécution. de la file d'attente prête.
État d'exécution -> État prêt : après la création ou la restauration d'une tâche de priorité plus élevée, la planification des tâches se produit à ce moment-là, la tâche la plus prioritaire dans la file d'attente prête passe à l'état d'exécution, puis la tâche en cours d'exécution passe de l'état d'exécution. à l'état prêt, et toujours dans la file d'attente prête
État prêt -> État bloqué : la tâche peut également être bloquée (suspendue) à l'état prêt. À ce moment, l'état de la tâche passe de l'état prêt à l'état bloquant. La tâche est supprimée de la file d'attente prête et ne participera pas. dans la planification des tâches jusqu'à ce que la tâche soit restaurée
État bloqué -> État prêt : une fois la tâche bloquée récupérée (récupération de tâche, délai d'attente, délai d'attente de lecture du sémaphore ou lecture du sémaphore, etc.), la tâche récupérée sera ajoutée à la file d'attente prête, passant ainsi de l'état bloqué à prêt : si la priorité de la tâche reprise est supérieure à la priorité de la tâche en cours d'exécution, un changement de tâche se produira et la tâche passera de prête à en cours d'exécution.
État d'exécution -> État bloqué : lorsqu'une tâche en cours d'exécution est bloquée (suspension, retard, lecture du sémaphore, etc.), la tâche est insérée dans la file d'attente de blocage correspondante, et l'état de la tâche passe de l'état d'exécution à l'état de blocage, puis se produit Le changement de tâche exécute la tâche la plus prioritaire dans la file d'attente prête
État d'exécution -> État de sortie : la tâche en cours d'exécution se termine et l'état de la tâche passe de l'état d'exécution à l'état de sortie. L'état de sortie inclut l'état de sortie normal et l'état non valide à la fin de la tâche. Par exemple, si la tâche se termine mais ne se supprime pas, le statut lnyalid sera affiché au monde extérieur, c'est-à-dire le statut de sortie.
État bloqué -> État quitté : la tâche bloquée appelle l'interface de suppression et l'état de la tâche passe de bloqué à quitté.
Concepts liés à la gestion des tâches
ID de tâche
Il est restitué à l'utilisateur via des paramètres lors de la création de la tâche, ce qui constitue une identification importante de la tâche.
Priorité des tâches
Indique l'ordre de priorité d'exécution des tâches
Fonction de saisie de tâches
La fonction qui sera exécutée après la planification de la nouvelle tâche. Cette fonction est implémentée par l'utilisateur et est définie via la structure de création de tâche lors de la création de la tâche.
pile de tâches
Chaque tâche possède son propre espace de pile indépendant, que nous appelons pile de tâches. Les informations enregistrées dans l'espace de pile incluent les variables locales, les registres, les paramètres de fonction, les adresses de retour de fonction, etc.
contexte de la tâche
Certaines ressources utilisées par les tâches lors de leur exécution, telles que les registres, etc., sont appelées contexte de tâche.
Bloc de contrôle des tâches TCB
Chaque tâche contient un bloc de contrôle de tâche (TCB)
Le changement de tâche
Y compris des actions telles que l'obtention de la tâche la plus prioritaire dans la file d'attente prête, l'enregistrement du contexte de la tâche lors de la sortie et la restauration du contexte de la tâche lors de la connexion.
Processus de développement des tâches
1. Verrouillez la planification des tâches LOs_TaskLock pour empêcher la planification des tâches hautement prioritaires. 2. Créez la tâche Los_TaskCreate. 3. Déverrouillez la tâche LOs_TaskUnlock et autorisez la planification des tâches en fonction de leur priorité. 4. Retarder la tâche LOs_TaskDelay, attente de retard de tâche. 5. Suspendez la tâche spécifiée Los_TaskSuspend et la tâche est suspendue en attendant les opérations de récupération. 6. Reprenez la tâche suspendue Los_TaskResume.
Instructions de gestion des tâches
Interface du module de gestion des tâches
gestion du temps
décrire
Basé sur l'horloge système
La gestion du temps s'appuie sur l'horloge système et fournit tous les services liés au temps aux applications.
L'horloge système est générée par une interruption déclenchée par une impulsion de sortie générée par un compteur de minuterie. L'une est définie comme un nombre entier ou un nombre entier long. La période de l'impulsion de sortie est appelée « tick d'horloge ». L'horloge système est également appelée horodatage ou Tick
Les temps du système d'exploitation en ticks
L'utilisateur mesure le temps en secondes et en millisecondes, tandis que le système d'exploitation mesure le temps en Tick. Lorsque l'utilisateur doit faire fonctionner le système, comme la suspension d'une tâche, le retard, etc., le module de gestion du temps est requis pour convertir le Tick et les secondes/millisecondes. .
Le module de gestion du temps du noyau LiteOS-M fournit des fonctions de conversion du temps et de statistiques
unité de gestion du temps
La plus petite unité de chronométrage du système Cycle
La durée du cycle est déterminée par la fréquence de l'horloge principale du système. La fréquence de l'horloge principale du système est le nombre de cycles par seconde.
Tick est l'unité de temps de base du système d'exploitation, déterminée par le nombre de ticks par seconde configuré par l'utilisateur.
La gestion du temps n'est pas un module fonctionnel distinct et s'appuie sur les deux options de configuration OS_SYS_CLOCK et LOSCFGBASE_CORE_TICKPERSECOND
Le nombre de ticks dans le système n'est pas compté lorsque les interruptions sont désactivées, de sorte que le nombre de ticks dans le système d'exploitation ne peut pas être utilisé comme heure précise.
La relation entre cycle et tick. Cycle est l'unité de synchronisation du noyau système, et tick est l'unité de synchronisation du système d'exploitation. Les deux n'appartiennent pas au même type de synchronisation. Les utilisateurs n'ont qu'à actionner le tick, mais généralement pas le cycle.
La valeur par défaut de LOSCFG_BASE_CORE_TICK_PER_SECOND dans le noyau LiteOS-M est de 100, 100 ticks par seconde
Interface du module de gestion du temps
Gestion des interruptions
décrire
Pendant l'exécution du programme, lorsqu'une transaction doit être traitée immédiatement par la CPU, la CPU suspend temporairement l'exécution du programme en cours et traite la transaction. Ce processus est appelé une interruption.
Grâce au mécanisme d'interruption, le CPU peut effectuer d'autres tâches lorsque le périphérique ne nécessite pas l'intervention du CPU : lorsque le périphérique nécessite le CPU, le CPU interrompra la tâche en cours pour répondre à la demande d'interruption. Cela peut empêcher le processeur de passer beaucoup de temps à attendre et à interroger l'état des périphériques, améliorant ainsi efficacement les performances en temps réel et l'efficacité de fonctionnement à chaud du système.
Lorsque le matériel génère une interruption, son gestionnaire d'interruption correspondant est trouvé via le numéro d'interruption et le gestionnaire d'interruption est exécuté pour terminer le traitement de l'interruption.
Concepts de base de la gestion des interruptions
numéro d'interruption
Un indicateur spécifique pour le signal de demande d'interruption. L'ordinateur peut déterminer quel périphérique a effectué la demande d'interruption en fonction du numéro d'interruption.
demande d'interruption
Un « événement d'urgence » s'applique au processeur (envoie un signal d'impulsion électrique) et demande une interruption, ce qui oblige le processeur à suspendre la tâche en cours d'exécution pour traiter « l'événement d'urgence ». Ce processus est appelé demande d'interruption.
Priorité d'interruption
Afin de permettre au système de répondre et de gérer toutes les interruptions en temps opportun, le système divise les sources d'interruption en plusieurs niveaux en fonction de l'importance et de l'urgence de l'événement d'interruption, appelés priorités d'interruption.
Gestionnaire d'interruption
Lorsque le périphérique envoie une demande d'interruption, la CPU suspend la tâche en cours et répond à la demande d'interruption, c'est-à-dire en exécutant le gestionnaire d'interruption. Chaque périphérique qui génère une interruption a un gestionnaire d'interruption correspondant
Déclencheur d'interruption
La source d'interruption envoie un signal d'interruption au contrôleur d'interruption, et le contrôleur d'interruption arbitre l'interruption, détermine la priorité et envoie le signal d'interruption à la CPU.
Table vectorielle d'interruption
Stockez le vecteur d'interruption, qui correspond au numéro d'interruption. Le vecteur d'interruption est stocké dans la table des vecteurs d'interruption dans l'ordre du numéro d'interruption.
vecteur d'interruption
Adresse d'entrée de la routine de service d'interruption
Instructions de gestion des interruptions
Le gestionnaire d'interruption ne peut pas prendre trop de temps, sinon cela affecterait la réponse rapide du processeur aux interruptions.
Pendant le processus de réponse à l'interruption, les fonctions telles que LOS_Schedule qui provoquent la planification ne peuvent pas être exécutées directement ou indirectement.
Le paramètre d'entrée de la récupération d'interruption LOsIntRestore() doit être la valeur de retour du LOSIntLock() correspondant (c'est-à-dire la valeur CPSR avant de désactiver l'interruption)
Interface du module de gestion des interruptions
Minuterie logicielle
décrire
Il s'agit d'une minuterie basée sur l'interruption de l'horloge Tick du système et simulée par un logiciel. Lorsque la valeur de comptage d'horloge Tick définie passe, une fonction de rappel définie par l'utilisateur sera déclenchée. La précision du timing est liée à la période de l'horloge du système.
Les minuteries matérielles sont limitées par le matériel et leur nombre n'est pas suffisant pour répondre aux besoins réels des utilisateurs. Par conséquent, afin de répondre aux besoins des utilisateurs, davantage de minuteries sont fournies. Le noyau LiteOS-M fournit des fonctions de minuterie logicielle.
Le minuteur logiciel augmente le nombre de minuteurs, permettant la création de davantage de services programmés
Les minuteries logicielles sont des ressources système. Un morceau de mémoire continue a été alloué lors de l'initialisation du module. Le nombre maximum de minuteries prises en charge par le système est configuré par la macro LOSCFG BASE_CORE_SWTMR_LIMIT dans los_config.h.
Fonctionnalités de la minuterie logicielle
Recadrage statique, la fonction de minuterie logicielle peut être désactivée via une macro
Création de minuterie logicielle, démarrage de la minuterie logicielle
Le temporisateur logiciel est arrêté et le temporisateur logiciel est supprimé.
Obtenir le nombre de ticks restants du timer logiciel
Mécanisme de fonctionnement de la minuterie logicielle
Le timer logiciel utilise une file d'attente et une ressource tâche dans le système : son déclenchement suit les règles de file d'attente, premier entré, premier sorti. Un temporisateur avec un temps de chronométrage court est toujours plus proche de la tête de file d'attente qu'un temporisateur avec un temps de chronométrage plus long, répondant au critère d'être déclenché en premier.
Les minuteries logicielles utilisent Tick comme unité de synchronisation de base : lorsque l'utilisateur crée et démarre une minuterie logicielle, le noyau LiteOS-M déterminera l'heure d'expiration de la minuterie en fonction de l'heure actuelle du système et de l'intervalle de synchronisation défini par l'utilisateur, et will La structure de contrôle du timer est liée à la liste chaînée globale de timing
Lorsqu'une interruption Tick arrive : parcourez la liste liée de synchronisation globale des temporisateurs logiciels dans la fonction de traitement des interruptions Tick pour voir si un temporisateur expire. Si c'est le cas, enregistrez le temporisateur.
Une fois la fonction de traitement d'interruption Tick terminée : la tâche de minuterie logicielle (avec la priorité la plus élevée) est réveillée et la fonction de rappel de délai d'attente de la minuterie enregistrée précédemment est appelée dans la tâche.
État de la minuterie du logiciel
OS_SWTMR_STATUS_UNUSED (inutilisé)
Le système initialise toutes les ressources de minuterie du système dans cet état lorsque le module de minuterie est initialisé.
OS_SWTMR_STATUS_CREATED (Création non démarrée/arrêtée)
Après avoir appelé l'interface LOS_SwtmrCreate dans un état inutilisé ou appelé l'interface LOS_SwtmrStop après le démarrage, le minuteur passera à cet état.
OS_SWTMR STATUS_TICKING (nombre)
Une fois le minuteur créé, l'interface LOS_SwtmrStart est appelée et le minuteur deviendra cet état, indiquant l'état dans lequel le minuteur est en cours d'exécution.
Mode minuterie logicielle
Minuterie à un coup
Ce type de minuterie ne déclenchera un événement de minuterie qu'une seule fois après son démarrage, puis la minuterie sera automatiquement supprimée.
Minuterie de déclenchement périodique
Ce type de minuterie déclenchera périodiquement des événements de minuterie jusqu'à ce que l'utilisateur arrête manuellement la minuterie, sinon elle continuera à s'exécuter pour toujours.
Minuterie à déclenchement unique (ne sera pas automatiquement supprimée)
La différence avec le premier type est que ce type de minuterie ne sera pas automatiquement supprimé après l'expiration du délai. Vous devez appeler l'interface de suppression de minuterie pour supprimer la minuterie.
Instructions d'utilisation de la minuterie logicielle
N'effectuez pas trop d'opérations dans la fonction de rappel du minuteur logiciel et n'utilisez pas d'interfaces ou d'opérations susceptibles de provoquer la suspension ou le blocage des tâches.
Le temporisateur logiciel utilise une file d'attente et une ressource de tâche du système. La priorité de la tâche du temporisateur logiciel est définie sur 0 et aucune modification n'est autorisée.
Le nombre de ressources de minuterie logicielle pouvant être configurées dans le système fait référence au nombre total de ressources de minuterie logicielle pouvant être utilisées par l'ensemble du système, et non au nombre de ressources de minuterie logicielle pouvant être utilisées par les utilisateurs. Par exemple, si le temporisateur logiciel système occupe une ressource de temporisateur logiciel supplémentaire, le nombre de ressources de temporisateur logiciel que l'utilisateur peut utiliser sera réduit d'une.
Pour créer un minuteur avec un attribut unique non auto-supprimant, l'utilisateur doit appeler l'interface de suppression du minuteur pour supprimer le minuteur et recycler les ressources du minuteur afin d'éviter les fuites de ressources.
Créez un minuteur logiciel unique. Une fois le délai écoulé et l'exécution de la lettre de rappel, le système supprimera automatiquement le minuteur logiciel et recyclera les ressources.
Processus de développement de minuterie logicielle
Configurer les minuteries du logiciel
Confirmez que les éléments de configuration LOSCFG_BASE_CORE_SWTMR et LOSCFG_BASE_IPC_QUEUE sont à l'état ouvert de 1.
Configurer le nombre maximum de minuteries logicielles prises en charge par LOSCFG_BASE_CORE_SWTMR_LIMIT
Configurer la longueur maximale de la file d'attente du minuteur logiciel OS_SWTMR_HANDLE_QUEUE_SIZE
Créer une minuterie LOS_SwtmrCreate
Créez un minuteur logiciel qui spécifie la durée du timing, la fonction de traitement du délai d'attente et le mode de déclenchement.
Renvoie le résultat de l'exécution de la fonction, succès ou échec
Démarrer le minuteur LOS_SwtmrStart
Obtenez le nombre de ticks restants du minuteur logiciel LOS_SwtmrTimeGet
Arrêter le minuteur LOs_SwtmrStop
Supprimer le minuteur LOS SwtmrDelete
Interface du module de minuterie logicielle
Gestion de la mémoire
décrire
Le module de gestion de la mémoire gère les ressources mémoire du système. C'est l'un des modules centraux du système d'exploitation et comprend principalement l'initialisation, l'allocation et la libération de la mémoire.
Pendant le fonctionnement du système, le module de gestion de mémoire gère l'utilisation de la mémoire par les utilisateurs et le système d'exploitation en alimentant/libérant la mémoire, de manière à optimiser l'utilisation et l'efficacité de la mémoire, et en même temps à résoudre le problème de fragmentation de la mémoire. du système dans la plus grande mesure.
La gestion de la mémoire de LiteOS-M est divisée en gestion de mémoire statique et gestion de mémoire dynamique, fournissant l'initialisation, l'allocation, la libération et d'autres fonctions de la mémoire.
Gestion de la mémoire statique
La mémoire statique est essentiellement un tableau statique. La taille des blocs dans le pool de mémoire statique est définie lors de l'initialisation. La taille des blocs ne peut pas être modifiée après l'initialisation.
Le pool de mémoire statique est constitué d'un bloc de contrôle LOS_MEMBOX_INFO et de plusieurs blocs de mémoire LOS_MEMBOX_NODE de même taille.
Le nombre de blocs de mémoire dans le pool de mémoire initialisé n'est pas égal à la taille totale divisée par la taille du bloc de mémoire, car il y a une surcharge de mémoire dans le bloc de contrôle du pool de mémoire et dans l'en-tête de contrôle de chaque bloc de mémoire lors de la définition du total. taille, ces facteurs doivent être pris en compte.
scènes à utiliser
Lorsque les utilisateurs ont besoin d'utiliser une mémoire de longueur fixe, ils peuvent obtenir la mémoire via une allocation de mémoire statique. Une fois utilisée, la mémoire occupée est restituée via la fonction de libération de mémoire statique afin qu'elle puisse être réutilisée.
Le bloc de contrôle est situé en tête du pool de mémoire et est utilisé pour la gestion des blocs de mémoire uwBlkSize, le nombre de blocs de mémoire uwBlkNum, le nombre de blocs de mémoire alloués uwBlkCnt et la liste des blocs de mémoire libres stFreeList. L'application et la libération des blocs de mémoire sont basées sur la taille du bloc. Chaque bloc de mémoire contient un pointeur pstNext pointant vers le bloc de mémoire suivant.
Processus de développement de la mémoire statique
Planifier une zone mémoire comme pool de mémoire statique
Appelez LOS_Memboxlnit pour initialiser le pool de mémoire statique. L'initialisation divisera la zone mémoire spécifiée par le paramètre d'entrée en N blocs (la valeur N dépend de la taille totale de la mémoire statique et de la taille du bloc), suspendra tous les blocs de mémoire à la liste chaînée libre et placera l'en-tête de contrôle au début du souvenir.
Appelez l'interface LOS_MemboxAlloc pour allouer de la mémoire statique. Le système obtiendra le premier bloc libre de la liste chaînée libre et renverra l'adresse de départ du bloc mémoire.
Appelez l'interface LOS_MemboxClr. Effacez le bloc mémoire correspondant à l’adresse du paramètre d’entrée.
Appelez l'interface LOs MemboxFree. Ajouter le bloc mémoire à la liste chaînée gratuite
sujet de branche
Interface du module de mémoire statique
Gestion dynamique de la mémoire
décrire
Gestion dynamique de la mémoire : lorsque les ressources mémoire sont suffisantes, des blocs de mémoire de toute taille sont alloués à partir d'une mémoire continue plus grande (pool de mémoire, également mémoire tas) configurée dans le système en fonction des besoins de l'utilisateur. Lorsque l'utilisateur n'a pas besoin du bloc de mémoire, celui-ci peut être restitué au système pour une prochaine utilisation.
La mémoire dynamique LiteOS-M optimise la division des intervalles basée sur l'algorithme TLSF pour obtenir de meilleures performances et réduire le taux de fragmentation.
scènes à utiliser
La tâche principale de la gestion dynamique de la mémoire est d'allouer et de gérer dynamiquement la plage de mémoire demandée par l'utilisateur. La gestion dynamique de la mémoire est principalement utilisée dans les scénarios où les utilisateurs doivent utiliser des blocs de mémoire de différentes tailles. Lorsque les utilisateurs ont besoin d'utiliser de la mémoire, ils peuvent demander un bloc de mémoire d'une taille spécifiée via la fonction d'application de mémoire dynamique du système d'exploitation. l'utilisateur peut demander un bloc de mémoire d'une taille spécifiée via la fonction de libération de mémoire dynamique. Restituer la mémoire occupée afin qu'elle puisse être réutilisée.
TLSF : algorithme de stratégie de segmentation à deux niveaux Two-Level Segregated Fit
Comparaison entre la mémoire dynamique et la mémoire statique
mémoire dynamique
avantage
Allouer sur demande
défaut
Une fragmentation peut se produire dans le pool de mémoire
mémoire statique
avantage
Efficacité élevée d'allocation et de libération, pas de fragmentation dans le pool de mémoire statique
défaut
Vous ne pouvez postuler que pour des blocs de mémoire avec des tailles prédéfinies initialisées et ne pouvez pas postuler sur demande.
Algorithme de mémoire dynamique
Basée sur l'algorithme TLSF (Two Level Segregated Fit memory allocator), la mémoire tas OpenHarmony a optimisé la division par intervalles, obtenant de meilleures performances et réduisant le taux de fragmentation.
Selon la taille du bloc de mémoire libre, plusieurs tables lotus libres sont utilisées pour le gérer. Selon la taille du bloc de mémoire libre, il est divisé en deux parties : [4, 127] et [2^7, 2^. 31]
Divisez la mémoire dans l'intervalle [4,127] de manière égale, comme indiqué dans la moitié inférieure de la figure, en 31 petits intervalles. Chaque petit intervalle correspond à une taille de bloc mémoire qui est un multiple de 4 octets. Chaque petit intervalle correspond à un espace libre. mémoire La liste chaînée et un bit sont utilisés pour marquer si la liste chaînée de mémoire libre correspondante est vide. Lorsque la valeur est 1, la liste chaînée libre n'est pas vide. Les 31 bits correspondants dans l'intervalle [4,127] marquent si la liste chaînée. est vide.
Les blocs de mémoire libres de plus de 127 octets sont gérés par la liste chaînée libre selon la puissance de 2 tailles d'intervalle. Il est divisé en 24 cellules au total, et chaque cellule est également divisée en 8 cellules secondaires. Voir les parties Classe de taille et Sous-classe de taille dans la partie supérieure de la figure. Chaque cellule secondaire correspond à une liste chaînée libre et à un bit utilisé pour marquer si la liste chaînée mémoire libre correspondante est vide. Il y a un total de 24*8=192 intervalles de cellules secondaires, correspondant à 192 listes chaînées libres et 192 bits pour indiquer si la liste chaînée est vide.
Structure de gestion de mémoire dynamique
Basée sur l'algorithme TLSF, la mémoire dynamique OpenHarmonyLiteOS-M optimise la division des intervalles pour obtenir de meilleures performances et réduire le taux de fragmentation.
Instructions d'utilisation de la mémoire dynamique
Étant donné que la gestion dynamique de la mémoire nécessite des structures de données de bloc de contrôle de gestion pour gérer la mémoire, ces structures de données consommeront de la mémoire supplémentaire, de sorte que la quantité totale de mémoire disponible pour l'utilisateur réel est inférieure à la taille de l'élément de configuration OS_SYS_MEM_SIZE.
L'interface de mémoire d'allocation alignée LOs_MemAllocAlign/LOs_MemMallocAlign peut consommer de la mémoire supplémentaire en raison de l'alignement des adresses, il y a donc une perte de mémoire. Lorsque le système libère la mémoire alignée, il récupère également la mémoire perdue causée par l'alignement.
Les zones de mémoire non contiguës transmises par le paramètre de tableau LosMemRegion de l'interface de zone de mémoire non contiguë LOS_MemRegionsAdd doivent être classées par ordre croissant en fonction de l'adresse de début de mémoire de chaque zone de mémoire, et les zones de mémoire ne peuvent pas se chevaucher.
Processus de développement de la mémoire dynamique
1.Initialiser Los_Memlnit
Après l'initialisation d'un pool de mémoire, une tête de contrôle du pool de mémoire et un nœud de queue EndNode sont générés, et la mémoire restante est marquée comme nœud de mémoire FreeNode. Remarque : EndNode est le nœud final du pool de mémoire et sa taille est o.
2. Demander une mémoire dynamique de n'importe quelle taille Los_MemAlloc
Déterminez s'il existe un espace de bloc de mémoire libre dans le pool de mémoire dynamique qui est supérieur à la taille demandée. S'il existe, mettez de côté un bloc de mémoire et renvoyez-le sous la forme d'un pointeur. S'il n'existe pas, renvoyez NULL. Si le bloc de mémoire libre est supérieur à la quantité demandée, le bloc de mémoire doit être divisé et la partie restante est montée sur la liste de mémoire libre en tant que bloc de mémoire libre.
3. Libérez la mémoire dynamique LOS_MemFree
Le bloc mémoire peut être collecté pour une prochaine utilisation. L’appel de LOS_MemFree pour libérer le bloc de mémoire récupérera le bloc de mémoire et le marquera comme FreeNode. Lorsque le bloc de mémoire peut être collecté, les FreeNodes adjacents seront automatiquement fusionnés.
interface mémoire dynamique
Mécanisme de communication du noyau
événement
décrire
Les événements sont un mécanisme permettant d'établir une communication entre les tâches et peuvent être utilisés pour réaliser une synchronisation entre les tâches. Cependant, la communication d'événements ne peut être qu'une communication de type événement sans transmission de données. Une tâche peut attendre l'apparition de plusieurs événements : elle peut réveiller la tâche pour le traitement des événements lorsqu'un événement se produit, elle peut également réveiller la tâche pour le traitement des événements après que plusieurs événements se produisent ; La collection d'événements est représentée par une variable entière non signée de 32 bits et chaque bit représente un événement.
Le 25ème bit de l'événement est un bit réservé et ne peut pas être défini.
Comment fonctionnent les événements
L'événement est un mécanisme de communication entre tâches et peut être utilisé pour des opérations de synchronisation entre tâches.
modèle de gestion des événements
LOS_WAITMODE_AND
ET logique, ce n'est que lorsque ces événements se sont produits que la lecture peut réussir, sinon la tâche bloquera l'attente ou renverra un code d'erreur.
LOS_WAITMODE_OR
OU logique, tant que l'un de ces événements se produit, la lecture peut réussir, sinon la tâche bloquera l'attente ou retournera un code d'erreur
LOS_WAITMODE_CLR
Il s'agit d'un mode de lecture supplémentaire qui doit être utilisé conjointement avec le mode tous les événements ou avec n'importe quel mode d'événement ( LOS_WAITMODE AND I LOS_ WAITMODE CLR ou LOS_WAITMODE_OR / LOS_WAITMODE CLR ) Dans ce mode, lorsque le mode tous les événements ou l'un des événements est défini après le modèle est lu avec succès, le bit de type d'événement correspondant dans le bloc de contrôle d'événement sera automatiquement effacé.
Instructions de développement d'événements et processus de développement
La synchronisation des événements entre les tâches peut être une vers plusieurs ou plusieurs vers plusieurs.
Un-à-plusieurs : indique qu'une tâche peut attendre plusieurs événements
Plusieurs à plusieurs : indique que plusieurs tâches peuvent attendre plusieurs événements. Un événement d'écriture peut déclencher la sortie du blocage d'au plus une tâche.
Mécanisme de délai d'attente de lecture d'événement
Synchronise uniquement les tâches et ne transmet pas de données spécifiques
interface d'événement
verrouillage mutex
décrire
Le verrouillage mutex, également connu sous le nom de sémaphore d'exclusion mutuelle, est un sémaphore binaire spécial utilisé pour réaliser un traitement exclusif des ressources partagées.
Il n'y a que deux états d'un verrou mutex à tout moment, déverrouillé ou verrouillé. Lorsqu'une tâche détient le mutex, celui-ci est dans un état verrouillé et la tâche en acquiert la propriété. Lorsque la tâche le libère, le verrouillage est déverrouillé et la tâche perd la propriété du verrouillage. Lorsqu'une tâche détient un verrouillage mutuel, les autres tâches ne pourront plus déverrouiller ou maintenir le verrouillage mutuel.
Dans un environnement multitâche, il existe souvent des scénarios d'application dans lesquels plusieurs tâches se disputent la même ressource partagée. Les verrous Mutex peuvent être utilisés pour protéger les ressources partagées afin d'obtenir un accès exclusif. De plus, les verrous mutex peuvent résoudre le problème du retournement prioritaire des sémaphores.
Instructions d'utilisation du verrouillage arrière mutuel
Deux tâches ne peuvent pas verrouiller le même mutex. Si une tâche verrouille un mutex déjà détenu, la tâche sera suspendue jusqu'à ce que la tâche détenant le verrou déverrouille le mutex avant que le mutex puisse être verrouillé.
Les verrous mutex ne peuvent pas être utilisés dans les routines de service d'interruption
En tant que système d'exploitation en temps réel, le noyau LiteOS-M doit garantir la nature en temps réel de la planification des tâches et essayer d'éviter le blocage à long terme des tâches. Par conséquent, après avoir obtenu le verrou mutex, le verrou mutex doit être libéré. dès que possible.
Pendant le processus de maintien du verrou mutex, des interfaces telles que LOS_TaskPriSet ne doivent pas être appelées pour modifier la priorité de la tâche détenant le verrou mutex.
Processus de développement du verrou Mutex
mode non bloquant
La tâche doit demander un verrou mutex. Si aucune tâche ne détient actuellement le verrou mutex, ou si la tâche détenant le verrou mutex et la tâche demandant le verrouillage mutex sont les tâches de la même personne, l'appel réussira.
mode de blocage permanent
La tâche doit demander un verrou mutex. Si le verrou mutex n'est pas actuellement occupé, l'application réussit. Sinon, la tâche entre dans l'état bloquant et le système passe à la tâche prête avec la priorité la plus élevée pour poursuivre l'exécution. Une fois que la tâche entre dans l'état bloqué, la tâche bloquée ne sera plus exécutée jusqu'à ce que d'autres tâches libèrent le verrou de responsabilité mutuelle.
mode de blocage temporisé
La tâche doit demander un verrouillage mutex. Si le verrouillage n'est pas actuellement occupé, veuillez réussir. Sinon, la tâche entre dans l'état bloquant et le système passe à la tâche prête avec la priorité la plus élevée pour poursuivre l'exécution. Une fois que la tâche entre dans l'état bloqué, d'autres tâches libéreront le verrou mutex avant l'expiration du délai spécifié, ou la tâche bloquée sera à nouveau exécutée après l'expiration du délai spécifié.
Interface de verrouillage Mutex
file d'attente des messages
décrire
Le texte de la file d'attente est appelé file d'attente de messages, qui est une structure de données couramment utilisée pour la communication entre les tâches. La file d'attente reçoit des messages de longueur variable provenant de tâches ou d'interruptions et détermine si le message délivré est stocké dans l'espace de file d'attente selon différentes interfaces.
La tâche peut lire les messages de la file d'attente. Lorsque le message dans la file d'attente est vide, la tâche de lecture est suspendue ; lorsqu'il y a un nouveau message dans la file d'attente, la tâche de lecture suspendue est réveillée et traite le nouveau message. Les tâches peuvent également écrire des messages dans la file d'attente. Lorsque la file d'attente est pleine de messages, la tâche d'écriture est suspendue ; lorsqu'il y a des nœuds de messages inactifs dans la file d'attente, la tâche d'écriture suspendue est réveillée et écrit le message.
Vous pouvez ajuster le mode de blocage de l'interface de lecture et d'écriture en ajustant le délai d'expiration de la file d'attente de lecture et de la file d'attente d'écriture. Si le délai d'expiration de la file d'attente de lecture et de la file d'attente d'écriture est défini sur 0, la tâche ne sera pas suspendue et l'interface reviendra. directement. Il s’agit d’un modèle non bloquant. Au contraire, si le délai d'attente de la file d'attente et de la file d'attente d'écriture est défini sur un temps supérieur à 0, il fonctionnera en mode plug.
Fonctionnalités de la file d'attente des messages
Les messages sont mis en file d'attente selon le principe du premier entré, premier sorti et prennent en charge la lecture et l'écriture asynchrones.
Chaque fois qu'un message est lu, le nœud de message est mis en veille
Le type de message envoyé est convenu par les deux parties communicantes, et des messages de différentes longueurs (ne dépassant pas la taille du nœud de message de la file d'attente) peuvent être autorisés.
Une tâche peut recevoir et envoyer des messages à partir de n'importe quelle file d'attente de messages
Plusieurs tâches peuvent recevoir et envoyer des messages à partir de la même file d'attente de messages
L'espace de file d'attente requis lors de la création d'une file d'attente. Le système dans l'interface demande lui-même de la mémoire de manière dynamique.
Les files d'attente de lecture et d'écriture prennent en charge le mécanisme de délai d'attente
Instructions d'utilisation de la file d'attente de messages
Nombre maximum de files d'attente prises en charge par le système : le nombre total de ressources de file d'attente dans l'ensemble du système, et non le nombre que les utilisateurs peuvent utiliser. Par exemple, si le temporisateur du logiciel système occupe une ressource de file d'attente supplémentaire, les ressources de file d'attente disponibles pour l'utilisateur seront réduites d'une unité.
Le nom de la file d'attente et les flaqs transmis lors de la création de la file d'attente ne sont pas utilisés pour le moment et sont utilisés comme paramètres réservés pour le futur.
Le paramètre d'entrée timeOut dans la fonction d'interface de file d'attente est le temps relatif
LOS_QueueReadCopy, LOS_QueueWriteCopy et LOS_QueueWriteHeadCopy sont un ensemble d'interfaces. LOS_QueueRead, LOS_QueueWrite et LOS_QueueWriteHead sont un ensemble d'interfaces. Chaque ensemble d'interfaces doit être utilisé ensemble.
timeOut est le temps relatif : le temps relatif entre la file d'attente des messages et les tâches de lecture et d'écriture
Compte tenu du fait que les interfaces LOS_QueueWrite, LOS_QueueWriteHead et LOS_QueueRead fonctionnent effectivement sur des adresses de données, l'utilisateur doit s'assurer que la zone mémoire pointée par le pointeur obtenu en appelant LOS_QueueRead n'est pas anormalement modifiée ou libérée lors de la lecture de la file d'attente, sous peine de entraîner des conséquences imprévisibles.
Étant donné que les interfaces LOS_QueueWrite, LOS_QueueWriteHead et LOS_QueueRead fonctionnent en fait sur des adresses de données, ce qui signifie que la longueur réelle du message écrit et lu n'est qu'une donnée de pointeur, donc avant d'utiliser cet ensemble d'interfaces, les utilisateurs doivent s'assurer que la longueur du message lors de la création la file d'attente est La taille du nœud est la longueur d'un pointeur pour éviter les gaspillages inutiles et les échecs de lecture.
La longueur en lecture de l'interface LOS_QueueReadCopy doit être supérieure à la longueur réelle, sinon le message sera tronqué
interface de file d'attente de messages
signal
décrire
Le sémaphore est un mécanisme de communication entre les tâches, qui peut réaliser une synchronisation entre les tâches ou un accès mutuel aux ressources partagées.
Une structure de données de sémaphore a généralement une valeur de comptage, Utilisé pour compter le nombre de ressources efficaces, indiquant que celles restantes peuvent être utilisées Le nombre de ressources partagées a deux significations :
0, indiquant que le sémaphore est actuellement indisponible, il peut donc y avoir des tâches en attente du sémaphore.
Valeur positive, indiquant que le sémaphore peut actuellement être obtenu
Il existe les différences d'utilisation suivantes entre les sémaphores pour la synchronisation et les sémaphores pour l'exclusion mutuelle :
Lorsqu'il est utilisé comme exclusion mutuelle
Lorsqu'elle est utilisée comme exclusion mutuelle, la valeur initiale du nombre de sémaphores n'est pas 0, indiquant le nombre de ressources partagées disponibles. Avant de devoir utiliser une ressource partagée, obtenez d'abord le sémaphore, puis utilisez une ressource partagée et libérez le sémaphore après utilisation. De cette manière, lorsque les ressources partagées sont récupérées, c'est-à-dire lorsque le nombre de sémaphores est réduit à 0, les autres tâches nécessitant l'obtention du sémaphore seront bloquées, garantissant ainsi un accès mutuellement exclusif aux ressources partagées. De plus, lorsque le nombre de ressources partagées est de 1, il est recommandé d'utiliser un sémaphore binaire, mécanisme similaire à un verrou mutex.
Lorsqu'il est utilisé pour la synchronisation
Lorsqu'il est utilisé pour la synchronisation, la valeur initiale du nombre de sémaphores est 0. La tâche 1 est bloquée car elle ne peut pas obtenir le sémaphore. Jusqu'à ce que la tâche 2 ou une interruption libère le sémaphore, la tâche 1 peut entrer dans l'état Prêt ou En cours d'exécution, réalisant ainsi la synchronisation entre les tâches.
Processus de développement du sémaphore
initialisation du sémaphore
Demandez de la mémoire pour les N sémaphores configurés (la valeur N peut être configurée par l'utilisateur et implémentée via la macro LOSCFG_BASE_IPC_SEM_LIMIT), initialisez tous les sémaphores pour qu'ils soient inutilisés, et ajoutez-les à la liste chaînée inutilisée pour une utilisation par le système.
Créer un sémaphore LOS_SemCreate
Pour créer un sémaphore binaire, appelez LOs_BinarySemCreate, obtenez un sémaphore dans la liste des sémaphores inutilisés et définissez la valeur initiale.
Demander le sémaphore LOS_SemPend
Si la valeur du compteur est supérieure à 0, elle est directement décrémentée de 1 et renvoie le succès. Sinon, la tâche est bloquée et attend que d'autres tâches libèrent le sémaphore. Le délai d'attente peut être défini. Lorsqu'une tâche est bloquée par un sémaphore, la tâche est placée en fin de file d'attente des tâches en attente du sémaphore.
Libérer le sémaphore LOS_SemPost
Si aucune tâche n'attend le sémaphore, le compteur est directement augmenté de 1 et renvoyé. Sinon, réveillez le sémaphore et attendez la tâche à la première personne dans la file d'attente des tâches.
Supprimer le sémaphore LOS_SemDelete
Définissez le sémaphore utilisé sur un sémaphore inutilisé et raccrochez-le à la liste chaînée inutilisée
Interface sémaphore
Extensions du noyau
l'utilisation du processeur
décrire
L'occupation du CPU (Central Processing Unit, Central Processing Unit) est divisée en occupation du CPU du système et occupation du CPU des tâches
Utilisation du processeur système (pourcentage du processeur)
Le taux d'occupation du processeur du système (CPUPerCent) fait référence au taux d'occupation du processeur du système sur une période donnée. Il est utilisé pour indiquer l'inactivité et l'activité du système sur une période donnée, et indique également la charge du processeur. La plage valide d'utilisation du processeur système est de 0 à 100 et sa précision (peut être ajustée via la configuration) est un pourcentage. 100 signifie que le système fonctionne à pleine capacité
Utilisation du processeur par la tâche
L'utilisation du processeur par tâche fait référence à l'utilisation du processeur d'une seule tâche et est utilisée pour indiquer le degré d'occupation d'une seule tâche sur une période donnée. La plage de représentation effective de l'utilisation du processeur par tâche est de 0 à 100, et sa précision (peut être ajustée via la configuration) est un pourcentage. 100 signifie que le système exécute la tâche depuis un certain temps
Les utilisateurs peuvent utiliser l'utilisation du processeur au niveau du système pour déterminer si la charge actuelle du système dépasse les spécifications de conception.
Grâce à l'utilisation du processeur de chaque tâche du système, déterminez si l'utilisation du processeur de chaque tâche répond aux attentes de conception.
Mécanisme de fonctionnement de l'utilisation du processeur
Le CPUP (CPUPercent, utilisation du processeur système) de LiteOS-M utilise l'enregistrement au niveau des tâches. Lorsque les tâches sont commutées, l'heure de démarrage de la tâche, l'heure d'arrêt de la tâche ou l'heure de sortie sont enregistrées à chaque fois qu'une tâche se termine, le système accumule le nombre total. de tâches.
LiteOS-M fournit les deux types suivants de requêtes d'informations sur l'utilisation du processeur :
Utilisation du processeur système
Utilisation du processeur par la tâche
Comment calculer l'utilisation du processeur
Utilisation du processeur du système = durée d'exécution totale des autres tâches du système, à l'exception des tâches inactives/durée d'exécution totale du système
Utilisation du processeur de la tâche = durée totale d'exécution de la tâche/durée d'exécution totale du système
L'opération d'utilisation du processeur peut être configurée dans target_config.h
chargement dynamique
décrire
Dans les petits appareils dotés de ressources matérielles limitées, le problème de l’impossibilité de déployer simultanément plusieurs algorithmes doit être résolu grâce aux capacités de déploiement dynamique de l’algorithme. Prenant comme principale considération la facilité d'utilisation pour les développeurs et considérant la polyvalence multiplateforme, LiteOS-M choisit la solution de chargement ELF standard de l'industrie pour faciliter l'expansion de l'écosystème d'algorithmes.
LiteOS-M fournit des interfaces similaires à dlopen, dlsym, etc. APP peut charger et décharger la bibliothèque d'algorithmes correspondante via l'interface fournie par le module de chargement dynamique.
Exportation de table de symboles chargée dynamiquement
Les bibliothèques partagées appelant les interfaces du noyau nécessitent que le noyau expose activement les interfaces requises par la bibliothèque dynamique. Ce mécanisme compile les informations sur les symboles dans le segment spécifié, et l'appel de la macro SYM_EXPORT peut terminer l'exportation des informations sur les symboles spécifiés.
Les informations sur les symboles sont décrites via la structure Symlnfo, et ses membres incluent des informations sur le nom et l'adresse du symbole. La macro SYM EXPORT importe les informations sur les symboles dans la section .Sym.* via l'attribut de compilation _attribute_.
Charger dynamiquement le chargement du fichier ELF
Pendant le processus de chargement, le segment LOAD qui doit être chargé dans la mémoire peut être obtenu en fonction du handle du fichier ELF et du décalage de segment de la table d'en-tête du programme. Il existe généralement deux segments, un segment en lecture seule et un. segment en lecture-écriture Vous pouvez utiliser readelf -L pour afficher les informations du fichier ELF.
Demandez de la mémoire physique en fonction des attributs d'alignement correspondants et écrivez le segment de code ou le segment de données dans la mémoire via l'adresse de base de chargement et le décalage de chaque segment.
Charger dynamiquement les liens de fichiers ELF
Obtenez la table de relocalisation via la section .dynamic du fichier ELF, parcourez chaque entrée de la table qui doit être déplacée, puis recherchez le symbole correspondant dans la bibliothèque partagée et la table des symboles d'exportation fournie par le noyau en fonction du symbole nom qui doit être déplacé et mettez à jour les informations de déplacement correspondantes.
Types de support ELE
Lors de la compilation d'une bibliothèque partagée, ajoutez -fPIC pour compiler du code indépendant de la position (-fPIC est l'option de compilation). À l'heure actuelle, le type de fichier de bibliothèque partagée est ET_DYN, qui peut être chargé dans n'importe quelle plage d'adresses valide.
Exemple : arm-none-eabi-gcc -fPic -shared -o lib.so lib.c
Liteos-A
Dispositif de mémoire de classe M
Prise en charge de l'unité de gestion de la mémoire
Convient aux petits systèmes
Il est principalement utilisé dans les petits systèmes. Les appareils utilisent généralement une mémoire de classe M et peuvent prendre en charge l'isolation MMU. Les noyaux similaires dans l'industrie incluent Zircon ou Dawin, etc.