Table des matières
Accéder aux entrées/sorties depuis l'espace utilisateur via les pilotes du noyau LED et KEY
Une alternative à l'accès aux GPIO est d'utiliser les pilotes du noyau pré-construits gpio-keys, gpio-keys-polled et leds-gpio. Il est alors possible de les utiliser pour générer des ensembles prédéfinis et utiliser les interruptions1).
Création du fichier de description des périphériques .dts
Après avoir exporté votre conception dans Vivado, et avoir ouvert SDK concernant ce projet, il faut créer une structure BSP ( Device Tree Board Support Package)2).
- Cliquer sur le nom du projet dans le project explorer. Exemple : allume_LED
- Menu: File > New > Board Support Package > Board Support Package OS: device-tree > Finish
- une fenêtre Board Support Package Settings apparait. > OK
Entre autres, les fichiers .dts/.dtsi apparaissent désormais dans le project explorer sous la partie device_tree_bsp_0 et ils sont situés dans le répertoire du projet.sdk/device_tree_bsp_0/ .
Informations du Device Tree
Dans le fichier system.dts on peut y voir :
/include/ "zynq-7000.dtsi" /include/ "pl.dtsi" ... &gpio0 { emio-gpio-width = <64>; gpio-mask-high = <0x0>; gpio-mask-low = <0x5600>; }; ...
En éditant le fichier inclus zynq-7000.dtsi on peut y voir des descriptions de périphériques. Entre autres :
/ { compatible = "xlnx,zynq-7000"; ... amba: amba { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&intc>; ranges; ... gpio0: gpio@e000a000 { compatible = "xlnx,zynq-gpio-1.0"; #gpio-cells = <2>; #interrupt-cells = <2>; clocks = <&clkc 42>; gpio-controller; interrupt-controller; interrupt-parent = <&intc>; interrupts = <0 20 4>; reg = <0xe000a000 0x1000>; }; ... }; };
Puis en éditant le fichier inclus pl.dtsi on peut y voir :
/ { amba_pl: amba_pl { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges ; axi_gpio_0: gpio@41200000 { #gpio-cells = <2>; compatible = "xlnx,xps-gpio-1.00.a"; gpio-controller ; reg = <0x41200000 0x10000>; xlnx,all-inputs = <0x0>; xlnx,all-inputs-2 = <0x1>; xlnx,all-outputs = <0x1>; xlnx,all-outputs-2 = <0x0>; xlnx,dout-default = <0x00000000>; xlnx,dout-default-2 = <0x00000000>; xlnx,gpio-width = <0x8>; xlnx,gpio2-width = <0x8>; xlnx,interrupt-present = <0x0>; xlnx,is-dual = <0x1>; xlnx,tri-default = <0xFFFFFFFF>; xlnx,tri-default-2 = <0xFFFFFFFF>; }; }; };
Ces fichiers serviront de base pour la création des périphériques dans le noyau Linux. Une personnalisation de ces fichiers sera nécessaire pour y inclure nos propres périphériques. Nous verrons cela juste après avoir créé un nouveau projet Petalinux.
Création d'un nouveau projet Petalinux
Dans une console, se placer dans le répertoire désiré puis créer le projet type pour Zynq et enfin importer la configuration du projet créé sous SDK. Par exemple :
$ cd ~/projets_zync/Linux_LEDs $ petalinux-create --type project --template zynq --name Petalinux_LEDs_2 $ cd Petalinux_LEDs_2 $ petalinux-config --get-hw-description=~/projets_zync/Linux_LEDs/Linux_LEDs.sdk
Vous accédez alors au menu de configuration par défaut. Choisissez Exit. Plusieurs lignes d'informations apparaissent. Remarquez celle-ci:
... [INFO ] generate DTS to /home/XXXX/projets_zync/Linux_LEDs/Petalinux_LEDs_2/subsystems/linux/configs/device-tree ...
Elle correspond à l'emplacement où se trouveront les informations pour la construction de l’arborescence des périphériques.
Créer un périphérique type led pour LD9
Sur la Zedboard, LD9 est reliée directement au MIO7 de la partie processeur. Nous voir comment la configurer à partir du driver générique led fourni par le noyau.
Éditer le fichier zynq-7000.dtsi. Par exemple avec nano :
$ nano subsystems/linux/configs/device-tree/zynq-7000.dtsi <code> Après le bloc déclarant //gpio0//, nous allons déclarer //led-LD9// comme un périphérique de type //gpio-led//, comme suit : <code> gpio0: gpio@e000a000 { compatible = "xlnx,zynq-gpio-1.0"; #gpio-cells = <2>; #interrupt-cells = <2>; clocks = <&clkc 42>; gpio-controller; interrupt-controller; interrupt-parent = <&intc>; interrupts = <0 20 4>; reg = <0xe000a000 0x1000>; }; gpio-leds { compatible = "gpio-leds"; led-LD9 { label = "led-LD9"; gpios = <&gpio0 7 0>; default-state = "on"; linux,default-trigger = "heartbeat"; }; };
La déclaration <&gpio0 7 0> fait référence au contrôleur de GPIO gpio0 vu plus haut. Le bit 7 du contrôleur est utilisée et la sortie est active à l'état haut (indiqué par le dernier 0).
La déclaration default-trigger avec la propriété “heartbeat” indique le comportement de la LED par défaut.La LED va avoir une illumination de type double-impulsion avec une fréquence relative à la charge du CPU.
Ensuite il va falloir contrôler que le driver de type led est bien activé dans la configuration du noyau. Pour cela vérifier que sont coché les options suivantes :
- Device Drivers
- GPIO Support
- Xilinx GPIO support
- Xilinx Zynq GPIO support
- LED Support
- LED Class Support
- LED Support for GPIO connected LEDs
- LED Trigger support
- all desired triggers
Gràce à la commande :
$ petalinux-config -c kernel
Une fois sorti de cette configuration et l'avoir sauvée, il va falloir compiler le projet, créer le fichier BOOT.INI et regénerer l'image pré-construite pour démarrer le projet par la liaison JTAG.
$ petalinux-build $ petalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga /home/utilisateur/projets_zync/Linux_LEDs/Linux_LEDs.runs/impl_1/proc_et_LEDs_wrapper.bit --force $ petalinux-package --prebuilt --fpga /home/utilisateur/projets_zync/Linux_LEDs/Linux_LEDs.runs/impl_1/proc_et_LEDs_wrapper.bit --force
Après avoir démarré un terminal série sur /dev/ttyACM , il faut copier le fichier de programmation oproc_et_LEDs_wrapper.bit puis on peut lancer la programmation
$ cp pre-built/linux/implementation/proc_et_LEDs_wrapper.bit pre-built/linux/implementation/download.bit $ petalinux-boot --jtag --prebuilt 3
Une fois le module démarré, on remarquera :
root@Petalinux_LEDs_2:~# ls /sys/class/leds/ led-LD9 mmc0:: root@Petalinux_LEDs_2:~# ls /sys/class/leds/led-LD9/ brightness max_brightness subsystem uevent device power trigger root@Petalinux_LEDs_2:~# cat /sys/class/leds/led-LD9/trigger none nand-disk mmc0 timer oneshot [heartbeat] backlight gpio cpu0 cpu1 default-on transient flash torch root@Petalinux_LEDs_2:~# cat /sys/class/leds/led-LD9/brightness 0
Ce qui veut dire :
- [heartbeat] : mode double-impulsion fonction de la charge du processeur
- brightness=0 : normalement éteinte, mais le mode trigger [heartbeat] reste actif.
si on veux l'éteindre, puis l'allumer :
# echo 0 > /sys/class/leds/led-LD9/brightness # cat /sys/class/leds/led-LD9/trigger [none] nand-disk mmc0 timer oneshot heartbeat backlight gpio cpu0 cpu1 default-on transient flash torch # echo 1 > /sys/class/leds/led-LD9/brightness # cat /sys/class/leds/led-LD9/trigger [none] nand-disk mmc0 timer oneshot heartbeat backlight gpio cpu0 cpu1 default-on transient flash torch
- [none] : pas de mode trigger