Application bare-metal avec Vitis
Créer une plateforme logicielle, comprendre le BSP et piloter une IP AXI GPIO avec les pilotes de bas et de haut niveau.
Chargement…
Créer une plateforme logicielle, comprendre le BSP et piloter une IP AXI GPIO avec les pilotes de bas et de haut niveau.
Une application bare-metal exécute du C ou C++ sur le processeur sans système d'exploitation complet. Le domaine standalone fournit démarrage, bibliothèques et services minimaux, sans l'isolation des processus ni l'ordonnancement de Linux.
Importez le XSA dans Vitis, créez la plateforme et choisissez le domaine processeur. L'application console LED UART reçoit des commandes par UART et pilote un AXI GPIO.
| Élément | Contenu |
|---|---|
| Plateforme | Description du matériel importée depuis le XSA |
| Domaine | Processeur cible, système d'exploitation et BSP |
| Application | Sources C ou C++, script de liens et options de compilation |
La compilation est croisée : le compilateur tourne sur votre poste et produit du code ARM pour la carte. L'ELF contient code, données et informations de débogage. JTAG peut le charger dans une mémoire initialisée ; un démarrage autonome exige ensuite une image de boot.
Le BSP fournit les pilotes et les symboles de xparameters.h correspondant au matériel :
#include "xgpio.h"
#include "xparameters.h"
XGpio leds;
int init_leds(void)
{
int status;
status = XGpio_Initialize(&leds, XPAR_FPT_LED_BANK_DEVICE_ID);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
XGpio_SetDataDirection(&leds, 1, 0x0U);
XGpio_DiscreteWrite(&leds, 1, 0x0U);
return XST_SUCCESS;
}XGpio_Initialize associe l'instance logicielle au GPIO. Le code de retour est contrôlé, puis le canal 1 est placé en sortie et ses données à zéro. Ce listing utilise l'API avec identifiant de périphérique ; adaptez l'initialisation aux en-têtes du BSP si votre flux utilise une adresse de base à la place.
Le pilote structuré de niveau 1 facilite la gestion de plusieurs instances :
void write_led_pattern(u32 pattern)
{
XGpio_DiscreteWrite(&leds, 1, pattern & 0xFFU);
}Le masque 0xFFU vise huit LED. Pour quatre LED, utilisez 0x0FU.
Le niveau 0 évite la structure d'instance, au prix d'une connaissance explicite de l'adresse et des offsets :
#include "xgpio_l.h"
void configure_led_registers(void)
{
XGpio_WriteReg(XPAR_ZCU_LED_BASEADDR, XGPIO_TRI_OFFSET, 0x0U);
XGpio_WriteReg(XPAR_ZCU_LED_BASEADDR, XGPIO_DATA_OFFSET, 0x0U);
}Dans XGPIO_TRI_OFFSET, un bit à zéro choisit la sortie. XGPIO_DATA_OFFSET porte les données. Les noms de base doivent correspondre au BSP réel ; ce second fragment représente une autre instance.
Dans la console LED, + et - déplacent le motif et 0 à 7 choisissent une LED. Pour un mini-chronomètre, la boucle peut lire les boutons, traiter l'anti-rebond et les commandes série, puis mettre à jour l'état :
| Commande | Effet |
|---|---|
g | Démarre le chronomètre |
s | Arrête le chronomètre |
r ou c | Remet le temps à zéro |
Le booléen timer_is_running définit une petite machine d'états. UART et LED rendent le résultat visible.
Une attente logicielle proche de 10 ms sert seulement à illustrer l'enchaînement. Sa durée varie avec fréquence, optimisation et caches ; une base de temps précise demande un timer matériel, éventuellement avec interruption.
Lisez platform.c pour savoir ce que fait init_platform() : caches ou UART standard selon la cible, parfois presque rien. Elle n'initialise pas automatiquement tous les périphériques.
Placez cleanup_platform() sur les chemins de sortie réels, notamment les échecs d'initialisation. Après une boucle infinie, cet appel ne sera pas atteint.
Dans Vitis, vérifiez la configuration qui programme la PL, initialise le PS et charge l'ELF. Pour un GPIO inactif, contrôlez XSA, symboles du BSP, retour du pilote, direction, adresse puis contraintes et brochage.
Le guide Vitis UG1400 décrit le flux ; embeddedsw fournit les sources des pilotes.
Tester mes connaissances - Quiz du chapitre