<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wikifr.techno-innov.fr/index.php?action=history&amp;feed=atom&amp;title=Technique%2FLogiciel%2FAPI%2FUse%2FCore%2FInstruction_Set</id>
	<title>Technique/Logiciel/API/Use/Core/Instruction Set - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wikifr.techno-innov.fr/index.php?action=history&amp;feed=atom&amp;title=Technique%2FLogiciel%2FAPI%2FUse%2FCore%2FInstruction_Set"/>
	<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Technique/Logiciel/API/Use/Core/Instruction_Set&amp;action=history"/>
	<updated>2026-04-04T02:30:48Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Technique/Logiciel/API/Use/Core/Instruction_Set&amp;diff=33&amp;oldid=prev</id>
		<title>Nathael : Page créée avec « == Jeu d&#039;instructions == L&#039;ensemble des micro-contrôleurs supportés par cette API utilisent un cœur ARM Cortex-M* (M0, M3, M4, ...). La majorité des informations relat... »</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Technique/Logiciel/API/Use/Core/Instruction_Set&amp;diff=33&amp;oldid=prev"/>
		<updated>2020-09-02T03:37:50Z</updated>

		<summary type="html">&lt;p&gt;Page créée avec « == Jeu d&amp;#039;instructions == L&amp;#039;ensemble des micro-contrôleurs supportés par cette API utilisent un cœur ARM Cortex-M* (M0, M3, M4, ...). La majorité des informations relat... »&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Jeu d&amp;#039;instructions ==&lt;br /&gt;
L&amp;#039;ensemble des micro-contrôleurs supportés par cette API utilisent un cœur ARM Cortex-M* (M0, M3, M4, ...).&lt;br /&gt;
La majorité des informations relatives au jeu d&amp;#039;instruction concerné sont décrites sur le site [http://infocenter.arm.com/help/topic/com.arm.doc.set.cortexm/index.html infocenter.arm.com dans la section &amp;quot;Cortex-M series processors&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
La majorité des instructions sont utilisées de façon transparentes par le compilateur lors de la compilation du code C.&amp;lt;br /&amp;gt;&lt;br /&gt;
Ces instructions et leur utilisation ne seront pas détaillées ici.&lt;br /&gt;
&lt;br /&gt;
== Instructions spéciales ==&lt;br /&gt;
 #include &amp;quot;core/lpc_core.h&amp;quot;&lt;br /&gt;
Cependant, certaines instructions spécifiques ne sont pas présentes dans le langage C, et il est nécessaire d&amp;#039;utiliser quelques lignes d&amp;#039;assembleur pour y accéder.&lt;br /&gt;
&lt;br /&gt;
Pour simplifier l&amp;#039;écriture du code C, ces lignes d&amp;#039;assembleur ont été regroupées dans le fichier d&amp;#039;entêtes &amp;quot;include/core/lpc_core.h&amp;quot; et placées à l&amp;#039;intérieur de fonctions ou de macro écrites en C.&lt;br /&gt;
&lt;br /&gt;
=== Instructions &amp;quot;simples&amp;quot; ===&lt;br /&gt;
* No operation : nop&lt;br /&gt;
 #define nop() __asm volatile (&amp;quot;nop&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction permet de &amp;quot;ne rien faire&amp;quot; pendant un cycle horloge. La fonction nop() permet de faire appel à cette instruction.&lt;br /&gt;
* Send event : sev&lt;br /&gt;
 #define sev() __asm volatile (&amp;quot;sev&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction permet de &amp;quot;générer&amp;quot; un événement de façon logicielle. La fonction sev() permet de faire appel à cette instruction.&lt;br /&gt;
* Wait For Event : wfe&lt;br /&gt;
 #define wfe() __asm volatile (&amp;quot;wfe&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction permet de mettre en pause le micro-contrôleur en attendant le prochain événement. La fonction wfe() permet de faire appel à cette instruction.&lt;br /&gt;
* Wait For Interrupt : wfi&lt;br /&gt;
 #define wfi() __asm volatile (&amp;quot;wfi&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction permet de mettre en pause le micro-contrôleur en attendant la prochaine interruption. La fonction wfi() permet de faire appel à cette instruction.&amp;lt;br /&amp;gt;&lt;br /&gt;
Cette instruction est aussi utilisée pour la mise en veille du micro-contrôleur une fois la configuration correspondante effectuée.&lt;br /&gt;
* Instruction Synchronization Barrier : isb&lt;br /&gt;
 #define isb() __asm volatile (&amp;quot;isb&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction est une opération de synchronisation qui temporise l&amp;#039;exécution de nouvelles instructions jusqu&amp;#039;à ce que les instructions présentes dans le &amp;quot;pipeline&amp;quot; aient fini de s&amp;#039;exécuter.&lt;br /&gt;
* Data Synchronization Barrier&lt;br /&gt;
 #define dsb() __asm volatile (&amp;quot;dsb&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction est une opération de synchronisation qui temporise l&amp;#039;exécution de nouvelles instructions jusqu&amp;#039;à ce que l&amp;#039;ensemble des accès en mémoire aient été complétés.&lt;br /&gt;
* Data Memory Barrier&lt;br /&gt;
 #define dmb() __asm volatile (&amp;quot;dmb&amp;quot; : : : &amp;quot;memory&amp;quot;)&lt;br /&gt;
Cette instruction est une opération de synchronisation qui temporise l&amp;#039;exécution de nouvelles instructions pour que l&amp;#039;ordre apparent des accès en mémoire soit respecté, même si les accès ne sont pas forcément complétés (seules les écritures relatives à des adresses accédées par les instructions en attente devront être complétées).&lt;br /&gt;
* Enable IRQ Interrupts&lt;br /&gt;
 static inline void lpc_enable_irq(void)&lt;br /&gt;
Cette instruction autorise les interruptions qui ont été activées. Les interruptions externes sont autorisées par défaut lors du démarrage du micro-contrôleur, mais pas activées.&lt;br /&gt;
* Disable IRQ Interrupts&lt;br /&gt;
 static inline void lpc_disable_irq(void)&lt;br /&gt;
Cette instruction interdit toutes les interruptions.&amp;lt;br /&amp;gt;&lt;br /&gt;
Voir la section sur les [[Technique/Logiciel/API/Use/Core/Interrupts|Interruptions]] pour plus d&amp;#039;informations sur l&amp;#039;utilisation des deux dernières instructions.&lt;br /&gt;
&lt;br /&gt;
=== Accès aux registres spéciaux ===&lt;br /&gt;
* Application Program Status Register (APSR)&lt;br /&gt;
 static inline uint32_t get_APSR(void)&lt;br /&gt;
 #define APSR_SATURATION  (get_APSR() &amp;amp; (0x1 &amp;lt;&amp;lt; 27))  /* bit 27  Saturation condition flag */&lt;br /&gt;
 #define APSR_OVERFLOW    (get_APSR() &amp;amp; (0x1 &amp;lt;&amp;lt; 28))  /* bit 28  Overflow condition code flag */&lt;br /&gt;
 #define APSR_CARRY       (get_APSR() &amp;amp; (0x1 &amp;lt;&amp;lt; 29))  /* bit 29  Carry condition code flag */&lt;br /&gt;
 #define APSR_ZERO        (get_APSR() &amp;amp; (0x1 &amp;lt;&amp;lt; 30))  /* bit 30  Zero condition code flag */&lt;br /&gt;
 #define APSR_NEGATIVE    (get_APSR() &amp;amp; (0x1 &amp;lt;&amp;lt; 31))  /* bit 31  Negative condition code flag */&lt;br /&gt;
* Interrupt Program Status Register (IPSR)&lt;br /&gt;
 static inline uint32_t get_IPSR(void)&lt;br /&gt;
 #define IPSR      (get_IPSR() &amp;amp; 0x1FF)  /* bit:  0..8  Exception number */&lt;br /&gt;
 #define IPSR_IRQ0 16&lt;br /&gt;
 #define IRQ_NUM   (IPSR - IPSR_IRQ0)&lt;br /&gt;
* Control Register&lt;br /&gt;
 static inline uint32_t get_CONTROL(void)&lt;br /&gt;
 static inline void set_CONTROL(uint32_t control)&lt;br /&gt;
* Process Stack Pointer&lt;br /&gt;
 static inline uint32_t get_process_stack_pointer(void)&lt;br /&gt;
 static inline void set_process_stack_pointer(uint32_t top_of_stack)&lt;br /&gt;
* Main Stack Pointer&lt;br /&gt;
 static inline uint32_t get_main_stack_pointer(void)&lt;br /&gt;
 static inline void set_main_stack_pointer(uint32_t top_of_stack)&lt;br /&gt;
* Priority Mask&lt;br /&gt;
 static inline uint32_t get_priority_mask(void)&lt;br /&gt;
 static inline void set_priority_mask(uint32_t mask)&lt;br /&gt;
* Base Priority&lt;br /&gt;
 static inline uint32_t get_base_priority(void)&lt;br /&gt;
 static inline void set_base_priority(uint32_t prio)&lt;br /&gt;
* Fault Mask&lt;br /&gt;
 static inline uint32_t get_fault_mask(void)&lt;br /&gt;
 static inline void set_fault_mask(uint32_t mask)&lt;br /&gt;
&lt;br /&gt;
=== Opérations sur les bits et octets ===&lt;br /&gt;
* Double changement d&amp;#039;endianness 16-bit sur mot 32-bit&lt;br /&gt;
 static inline uint32_t double_byte_swap_16(volatile uint32_t value)&lt;br /&gt;
Cette fonction permet de changer simultanément l&amp;#039;endianness de deux mots de 16 bits, sans changer l&amp;#039;ordre des mots.&lt;br /&gt;
&lt;br /&gt;
* Changement d&amp;#039;endianness 16-bit&lt;br /&gt;
 static inline uint32_t byte_swap_16(volatile uint16_t value)&lt;br /&gt;
Cette fonction permet de changer l&amp;#039;endianness d&amp;#039;un mot de 16 bits. Le résultat est sur les 16 bits de poids faible de l&amp;#039;entier 32 bits retourné.&lt;br /&gt;
&lt;br /&gt;
* Changement d&amp;#039;endianness 32-bit&lt;br /&gt;
 static inline uint32_t byte_swap_32(volatile uint32_t value)&lt;br /&gt;
Cette fonction permet de changer l&amp;#039;endianness d&amp;#039;un mot de 32 bits.&lt;br /&gt;
&lt;br /&gt;
Voir aussi les fonctions ntohs(), ntohl(), htons() et htonl() pour la gestion de l&amp;#039;endianness et les fonctions clz(), ctz() et bits_set()(&amp;quot;include/lib/utils.h&amp;quot;) pour les opérations sur les bits.&lt;br /&gt;
&lt;br /&gt;
== Accès atomiques et Synchronisation ==&lt;br /&gt;
Certains cœurs de micro-contrôleurs Cortex-M* ne disposent pas d&amp;#039;instruction de synchronisation &amp;quot;atomiques&amp;quot; garantissant qu&amp;#039;il n&amp;#039;est pas possible que deux accès à la même variable n&amp;#039;aient pas été réalisés depuis deux points d&amp;#039;exécution différents (par exemple le programme principal et une routine de gestion d&amp;#039;une interruption) de façon concurrente (lecture de la variable dans le programme principal, puis interruption, lecture et modification dans la routine de gestion de l&amp;#039;interruption, et reprise du programme principal, qui écrase la valeur modifiée par la routine de gesion de l&amp;#039;interruption).&lt;br /&gt;
&lt;br /&gt;
Les fonctions suivantes permettent de palier à ce manque.&amp;lt;br /&amp;gt;&lt;br /&gt;
Lorsque ces instructions existent pour le micro-contrôleur concerné, l&amp;#039;implémentation de ces fonctions utilise les instructions spécialisées fournies par le micro-contrôleur.&lt;br /&gt;
=== Accès atomiques - Interruptions gardés actives ===&lt;br /&gt;
 static inline uint32_t sync_lock_test_and_set(volatile uint32_t *addr, uint32_t value)&lt;br /&gt;
 static inline void sync_lock_release(volatile uint32_t *addr)&lt;br /&gt;
Ces deux fonctions permettent d&amp;#039;implémenter un mécanisme de mutex ou de rendez-vous, tout en laissant les interruptions actives entre la prise et la libération du verrou.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction sync_lock_test_and_set() enregistre la valeur &amp;quot;value&amp;quot; à l&amp;#039;adresse &amp;quot;addr&amp;quot; et renvoie l&amp;#039;ancienne valeur. Les interruptions sont désactivées pendant l&amp;#039;exécution de la fonction mais rétablies avant le retour de la fonction.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction sync_lock_release() met à zéro la variable dont l&amp;#039;adresse est passée en paramètre, sans désactiver les interruptions.&lt;br /&gt;
&lt;br /&gt;
=== Accès atomiques - Interruptions désactivées ===&lt;br /&gt;
 static inline uint32_t irq_sync_lock_test_and_set(volatile uint32_t *addr, uint32_t value)&lt;br /&gt;
 static inline void irq_sync_lock_release(volatile uint32_t *addr)&lt;br /&gt;
Ces deux fonctions permettent d&amp;#039;implémenter un mécanisme de mutex en désactivant les interruptions.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction irq_sync_lock_test_and_set() enregistre la valeur &amp;quot;value&amp;quot; à l&amp;#039;adresse &amp;quot;addr&amp;quot; et renvoie l&amp;#039;ancienne valeur. Lorsque l&amp;#039;ancienne valeur présente à l&amp;#039;adresse &amp;quot;addr&amp;quot; est non nulle, les interruptions sont réactivées (le mutex n&amp;#039;est pas pris). Sinon, le mutex est &amp;quot;pris&amp;quot; et les interruptions restent désactivées.&amp;lt;br /&amp;gt;&lt;br /&gt;
La fonction irq_sync_lock_release() met à zéro la variable dont l&amp;#039;adresse est passée en paramètre et réactive les interruptions.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention :&amp;#039;&amp;#039;&amp;#039; Ces deux fonctions ne peuvent pas être utilisées pour implémenter un mécanisme de rendez-vous car le verrou ne peut être libéré depuis une routine de gestion d&amp;#039;interruption.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Attention :&amp;#039;&amp;#039;&amp;#039; De nombreux modules de communication fonctionnent sur interruption, et ne seront plus fonctionnels pendant la durée du maintien du verrou.&amp;lt;br /&amp;gt;&lt;br /&gt;
Il est aussi préférable de limiter la quantité de code à exécuter entre la prise du mutex et sa libération.&lt;br /&gt;
&lt;br /&gt;
== Spécificités par micro-contrôleur ==&lt;br /&gt;
=== LPC82x ===&lt;br /&gt;
* Cœur ARM Cortex-M0 ARMv6-M ([http://infocenter.arm.com/help/topic/com.arm.doc.dui0497a/index.html Cortex-M0 Devices Generic User Guide])&lt;br /&gt;
&lt;br /&gt;
=== LPC122x ===&lt;br /&gt;
* Cœur ARM Cortex-M0 ARMv6-M ([http://infocenter.arm.com/help/topic/com.arm.doc.dui0497a/index.html Cortex-M0 Devices Generic User Guide])&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
</feed>