WCH et Linux

Introduction

Développer pour n'importe quel micro-contrôleur suppose de disposer au minimum des outils suivants :

  • Une "toolchain", c'est-à-dire un compilateur, un assembleur, un éditeur de liens et divers utilitaires connexes. Une toolchain complète est intégrée à MounRiver Studio, l'IDE de WCH, et peut aussi être téléchargée indépendamment sur le même site pour automatiser vos compilations et vos tests (intégration continue).

  • Un outil de "programmation" (ou "flashage") du micro-contrôleur, c'est-à-dire un utilitaire permettant de transférer le code de votre application ("firmware") dans la mémoire flash du micro-contrôleur. WCH fournit pour cela une application Windows, WCHISPTool, mais celle-ci n'est pas pleinement fonctionnelle sous Wine. WCH fournit également une application multi-plateforme en ligne de commande, WCHISPTool_CMD et c'est elle que vous devrez utiliser sous Linux.

  • Un utilitaire d'interfaçage entre le micro-contrôleur et le debugger de votre IDE. WCH fournit pour cela une version modifiée de OpenOCD, conçue pour fonctionner avec la gamme d'adaptateurs WCH-Link / WCH-LinkE / etc. Cette version d'OpenOCD est intégrée à la toolchain de MounRiver Studio.

Le présent document aborde l'installation et l'utilisation de ces différents outils.

Préparation

Le bon fonctionnement du flashage et du debugging exigent que votre utilisateur ait le droit d'accéder à l'adaptateur WCH-LinkE et à votre carte de développement. Pour cela, nous supposerons qu'un groupe plugdev existe et que votre utilisateur en est membre. Si ce n'est pas le encore le cas, faites le nécessaire puis déconnectez-vous (log out) et reconnectez-vous (log in) avant de poursuivre.

Pour savoir si le groupe plugdev existe, tapez :

grep plugdev /etc/group

Si rien ne s'affiche, c'est que le groupe n'existe pas et vous devrez le créer à l'aide de la commande suivante :

sudo groupadd plugdev

Si le groupe existe, vous verrez une ligne de la forme :

plugdev:x:46:vincent

S'il n'y a rien d'autre que ':' après l'identifiant de groupe, ou que votre nom d'utilisateur n'y figure pas, vous devrez vous ajouter au groupe à l'aide de la commande suivante :

sudo usermod -a -G plugdev votre_mom_d'utilisateur

IDE et toolchain

Pour télécharger l'IDE MounRiver Studio (MRS en abbrégé) ou la toolchain séparée, rendez-vous sur http://www.mounriver.com/download, puis cliquez sur le lien 1 pour télécharger l'IDE complet, ou 2 si vous ne voulez installer que la toolchain. Nous ne traiterons ici que du cas de l'IDE.

Décompactez l'archive dans le répertoire de votre choix, par exemple /opt. Pour faciliter les mises à jour ultérieures, créez un lien symbolique /opt/mrs vers le répertoire résultant du décompactage de l'archive, par exemple :

cd /opt
sudo tar xJf MounRiver_Studio_Community_Linux_x64_V170.tar.xz
sudo rm MounRiver_Studio_Community_Linux_x64_V170.tar.xz
sudo ln -s MounRiver_Studio_Community_Linux_x64_V170 mrs

Pour que l'adaptateur WCH-LinkE et les cartes de développement soient correctement détectés, il est impératif de copier les fichiers de règles udev dans /etc/udev/rules.d. Seul 50-wch.rules nous intéresse, mais si vous voulez utiliser OpenOCD avec d'autres familles de micro-contrôleurs, vous voudrez aussi copier 60-openocd.rules. Voici la procédure :

cd /opt/mrs/beforeinstall
# Création du répertoire destination s'il n'existe pas déjà
sudo mkdir -p /etc/udev/rules.d
# Correction des permissions des fichiers
chmod a-x *.rules
# Copie des règles
sudo cp *.rules /etc/udev/rules.d/
# Prise en compte des nouvelles règles udev
sudo sudo udevadm control --reload

Enfin, vous devrez créer un lanceur pour pouvoir démarrer l'IDE :

# Création du répertoire destination s'il n'existe pas déjà
mkdir -p ~/.local/share/applications
# Création du lanceur
cat <<EOF > ~/.local/share/applications/mounriver-studio.desktop
[Desktop Entry]
Name=MounRiver Studio Community IDE
Comment=MounRiver Studio Community IDE
Exec=sh -c "LD_LIBRARY_PATH=/opt/mrs/beforeinstall /opt/mrs/MRS_Community/MounRiver\ Studio_Community"
Icon=mounriver-studio
Terminal=false
Type=Application
StartupNotify=false
Categories=Development;IDE;
EOF

Notez que le LD_LIBRARY_PATH=/opt/mrs/beforeinstall dans le lanceur vous dispense de copier les fichiers .so du répertoire /opt/mrs/beforeinstall dans /usr/lib. Vous évitez ainsi le risque de casser votre système en cas de conflit et vous assurez du même coup à MRS de trouver les versions de bibliothèques qu'il attend.

Enfin, téléchargez cette icône et copiez-la dans le répertoire /usr/share/pixmaps (avec sudo).

Votre IDE est maintenant prêt à l'utilisation. Si vous souhaitez utiliser sa toolchain directement pour compiler vos projets en ligne de commande (ex. pour faire de l'intégration continue), vous pouvez créer une série de liens symboliques pour mettre à disposition ses outils plus simplement :

sudo mkdir -p /opt/toolchain
cd /opt/toolchain
# GCC 9.3 modifié par WCH (utilisé par défaut par MRS)
sudo ln -s ../mrs/MRS_Community/toolchain/RISC-V\ Embedded\ GCC riscv-none-embed-wch
# GCC 12 modifié par WCH (si vous préférez l'utiliser)
sudo ln -s ../mrs/MRS_Community/toolchain/RISC-V\ Embedded\ GCC\ 12 riscv-none-elf-wch
# OpenOCD 0.11 modifié par WCH
sudo ln -s ../mrs/MRS_Community/toolchain/OpenOCD openocd-wch

Remarques sur les identifiants USB du WCH-LinkE

Lorsqu'il est utilisé en mode RISC-V (aussi appelé WCH-LinkRV), votre WCH-LinkE apparaît dans lsusb avec les identifiants 1a86:8010.

Lorsqu'il est utilisé en mode ARM-WINUSB (aussi appelé WCH-DAPLink), il apparaît comme 1a86:8012.

Lorsqu'il est utilisé en mode ISP, pendant la mise à jour de son firmware, il apparaît comme 4348:55e0. C'est également le cas de tous les micro-contrôleurs WCH qui ont un port USB device (ex. CH32V203, CH32V307, CH582, etc.) lorsqu'ils sont démarrés en mode BOOT, qui est le mode utilisé par WCHISPTool_CMD et le driver ch37x.

En conséquence, pour un bon fonctionnement dans tous les cas de figure, les règles udev suivantes doivent être présentes :

ATTR{idVendor}=="1a86", ATTR{idProduct}=="8010", MODE="0660", GROUP="plugdev"
ATTR{idVendor}=="1a86", ATTR{idProduct}=="8012", MODE="0660", GROUP="plugdev"
ATTR{idVendor}=="4348", ATTR{idProduct}=="55e0", MODE="0660", GROUP="plugdev"

C'est normalement le cas si vous avez utilisé le fichier 50-wch.rules fourni avec MRS, comme nous l'avons fait plus haut.

Notez que si la dernière ligne (4348:55e0) est manquante, votre WCH-LinkE sera mis hors service lors de la mise à jour de son firmware. Le problème peut être corrigé, MRS fournit les fichiers de firmware des différents modèles de WCH-Link dans le sous-répertoire MRS_Community/update/Firmware_Link et le fichier WCH‑LinkUserManual.pdf donne les instructions pour le flasher, mais vérifier que la ligne est bien présente vous évitera ce tracas.

Interfaces de debugging

Les micro-contrôleurs WCH disposent d'une interface de debugging, appelée Serial Debug Interface (SDI), permettant de flasher et de debugger le micro-contrôleur avec un adaptateur WCH-LinkE.

Sur les micro-contrôleurs d'entrée de gamme, une seule broche (SWIO) est utilisée pour connecter le WCH-LinkE et l'interface est appelée "single-wire SDI" ou "1-wire interface", c'est-à-dire interface à un fil.

Sur les autres micro-contrôleurs, 2 broches sont utilisées, SWDIO (sur les CH32xxxx) ou TIO (sur les CH5xx), et SWCLK (CH32xxxx) ou TCK (CH5xx). L'interface est appelée "2-wire SDI" or "2-wire interface", c'est-à-dire interface à 2 fils.

Sur la plupart des micro-contrôleurs avec une interface à 2 fils, celle-ci est désactivée lors de la fabrication, ce qui empêche de flasher et debugger le micro-contrôleur. C'est bien sûr un problème pour le développeur et c'est pourquoi WCH active l'interface à 2 fils sur les cartes de développement qu'ils produisent. Ce n'est cependant pas le cas des autres fabricants de cartes de développement, ni celui des cartes que vous faites vous-même.

Les micro-contrôleurs dont l'interface à 2 fils est désactivée à la fabrication disposent tous d'un périphérique USB device et d'une (ex. PB22 sur les CH5xx) ou deux (BOOT0 et BOOT1 sur les CH32xxxx) broches permettant de sélectionner leur code exécuté au démarrage : soit le firmware présent en mémoire flash, soit le bootloader système, soit encore le code présent en RAM (pour les mises à jour de firmware OTA, c'est-à-dire via une connexion réseau).

En démarrant sur le bootloader système (PB22 = 0 sur les CH5xx, ou BOOT0 = 1 et BOOT1 = 0 sur les CH32xxxx), le périphérique USB device entre dans un mode spécial permettant de flasher le micro-contrôleur ou d'activer son interface à 2 fils. Il est également possible de réaliser les mêmes opérations via le périphérique USART1 du micro-contrôleur. Ce mode spécial ne reste actif qu'environ 20 secondes et le micro-contrôleur redémarre automatiquement sur le firmware de la mémoire flash une fois le délai expiré.

Les cartes de développement mettent à disposition de l'utilisateur soit un bouton poussoir, soit un cavalier, généralement marqués "BOOT", pour activer le bootloader système. Avec un bouton poussoir, il suffit de le maintenir appuyé en mettant la carte sous tension. Avec un cavalier, il faut relier la broche BOOT à la broche GND adjacente avant de mettre la carte sous tension.

Installation du driver CH37x

Pour pouvoir activer l'interface à 2 fils de votre micro-contrôleur, vous devrez le connecter à votre PC au moyen de son périphérique USB device en activant le bootloader système, puis utiliser WCHISPTool_CMD ou wch-unlock.

Cependant, pour que cette procédure fonctionne, il faut avoir installé au préalable un pilote de périphérique pour la série CH37x de WCH. Celui-ci est fourni sous forme de sources à télécharger ici. Nous supposerons que vous avez enregistré ce fichier sous le nom de CH37X_LINUX.ZIP et que vous avez ouvert un terminal dans le répertoire où se trouve ce fichier. Voici la procédure à suivre pour compiler et installer le driver :

# Installation des packages nécessaires pour compiler le driver.
sudo apt -y install dkms build-essential linux-headers-generic
# Décompactage du driver fourni par WCH et préalablement téléchargé ici:
# https://www.wch-ic.com/downloads/CH37X_LINUX_ZIP.html
# et stocké dans le répertoire courant.
unzip CH37X_LINUX.ZIP
# Création du fichier de configuration de DKMS.
# Les options choisies permettent de recompiler automatiquement le driver
# à chaque mise à jour du noyau Linux.
cat <<EOF > CH37X_LINUX/driver/dkms.conf
PACKAGE_NAME=ch37x
PACKAGE_VERSION=1.0
AUTOINSTALL=y
BUILT_MODULE_NAME[0]=ch37x
DEST_MODULE_LOCATION[0]=/kernel/usb/misc
EOF
# Création du répertoire d'accueil des sources du driver.
sudo mkdir -p /usr/src/ch37x-1.0
# Copie des sources du driver.
sudo cp CH37X_LINUX/driver/* /usr/src/ch37x-1.0/
# Suppression des fichiers temporaires.
rm -rf CH37X_LINUX CH37X_LINUX.ZIP
# Compilation et installation du driver.
sudo dkms install ch37x/1.0
# Création du répertoire au cas où il n'existerait pas déjà.
sudo mkdir -p /etc/modules-load.d
# Configuration du chargement automatique du driver au démarrage de la machine.
sudo sh -c 'echo ch37x > /etc/modules-load.d/ch37x.conf'
# Création du répertoire au cas où il n'existerait pas déjà.
sudo mkdir -p /etc/udev/rules.d
# Association du driver au groupe plugdev afin de pouvoir l'utiliser 
# avec un utilisateur autre que root.
sudo sh -c 'echo "KERNEL==\"ch37x0\", OWNER=\"root\", GROUP=\"plugdev\", MODE=\"660\"" \
    > /etc/udev/rules.d/70-ch37x.rules'
# Prise en compte des nouvelles règles udev
sudo udevadm control --reload

Si vous voulez vérifier sa présence, le module se trouve dans le répertoire /lib/module/${kernelVersion}/kernel/usb/misc/.

wch-unlock

L'utilitaire wch-unlock permet d'activer l'interface à 2 fils d'un micro-contrôleur connecté à votre PC via USB et démarrant sur son bootloader système.

Le code source de wch-unlock est disponible ici : https://codeberg.org/20-100/Awesome_RISC-V/src/branch/master/WCH/wch-unlock.

Les instructions de compilation et d'utilisation sont données dans les commentaires au début de wch-unlock.cpp. Un exécutable pré-compilé pour x86_64 est également fourni, ainsi qu'un fichier de configuration (optionnel) commenté. La ligne de commande à utiliser dépend de la famille de micro-contrôleurs :

  • Pour les familles CH32xxxx :

    wch-unlock -m CH32 -c CH32V203C8T6.ini
  • Pour les familles CHxxx :

    wch-unlock -m CH5xx -c CH582.ini

Bien sûr, les paramètres en italique doivent être remplacés par vos propres valeurs. Concernant les fichiers .ini, voyez ce paragraphe pour vous les procurer, ou cette section si vous voulez les générer vous-même.

IMPORTANT : dans votre fichier .ini, le paramètre IsCodeProtect doit être égal à 0, de même que IsRSTAsInputPin lorsqu'il existe. Les fichiers que je mets à votre disposition sont déjà corrects.

WCHISPTool_CMD

Installation de WCHISPTool_CMD

L'utilitaire WCHISPTool_CMD permet d'activer l'interface à 2 fils (CH32xxxx seulement, contrairement à wch-unlock qui gère aussi les CH5xx) ou flasher vos micro-contrôleurs via leur port USB device.

Si vous avez déjà activé l'interface à 2 fils de votre micro-contrôleur avec wch-unlock, vous pouvez utiliser OpenOCD pour flasher et debugger votre code de manière plus confortable.

La procédure d'installation est simple, il suffit d'enregistrer le fichier .zip à télécharger ici dans le répertoire de votre choix, par exemple /opt/toolchain, puis d'appliquer la procédure suivante :

sudo unzip WCHISPTool_CMD.ZIP
sudo rm WCHISPTool_CMD.ZIP
cd WCHISPTool_CMD
# Correction des permissions
sudo chmod -R a+rX Linux
sudo find Linux -type f -name WCHISPTool_CMD -exec chmod a+x {} ';'
# Déplacement des fichiers qui nous intéressent
sudo mv Linux/* .
# Suppression des fichiers inutiles
sudo rm -rf Linux macOS Windows

Après exécution de ces commandes, vous pourrez utiliser WCHISPTool_CMD en lançant /opt/toolchain/WCHISPTool_CMD/bin/x64/WCHISPTool_CMD.

Utilisation de WCHISPTool_CMD

WCHISPTool_CMD a besoin d'un fichier .ini de configuration pour lui indiquer le modèle de micro-contrôleur et ses options de configuration. Ces données correspondent à ce qu'on peut saisir dans l'interface utilisateur du logiciel Windows WCHISPTool.

pour vous éviter de vous battre avec Wine et WCHISPTool, j'ai généré un fichier .ini avec les options de configuration par défaut pour chaque micro-contrôleur supporté et je les ai mis à disposition ici.

WCHISPTool_CMD peut utiliser 2 types d'interfaces, le port USB device de la carte de développement et un port série. L'utilisation du port USB est obligatoire pour activer l'interface à 2 fils et optionnelle pour flasher le micro-contrôleur.

Pour utiliser le port USB, vous devez avoir installé le driver CH37x. D'autre part, vous devez activer le bootloader système du micro-contrôleur comme déjà décrit plus haut. Vous disposez ensuite d'environ 20 secondes pour exécuter la commande WCHISPTool_CMD. Ensuite, le micro-contrôleur redémarrera et exécutera son firmware.

Pour utiliser le port série, vous devez avoir créé un lien symbolique /dev/ttyISP0 pointant vers le port série utilisé (ex. /dev/ttyUSB0 ou /dev/ttyACM0). WCHISPTool_CMD vérifie le nom du lien symbolique et refuse de fonctionner si on lui donne directement le nom du bon device.

Voici les commandes dont vous aurez besoin - je suppose que le répertoire /opt/toolchain/WCHISPTool_CMD/bin/x64 est dans votre PATH, ou que vous avez créé un alias pour WCHISPTool_CMD :

  • Désactiver Code-Protect via le port USB device (CH32xxxx seulement) :

    WCHISPTool_CMD -p /dev/ch37x0 -c CH32V208WBU6.ini -r 1
  • Réactiver Code-Protect via le port USB device :

    WCHISPTool_CMD -p /dev/ch37x0 -c CH32V208WBU6.ini -r 0
  • Flasher le micro-contrôleur via son port USB device :

    WCHISPTool_CMD -p /dev/ch37x0 -c CH32V208WBU6.ini -o program -f votre-firmware.hex
  • Vérifier le flashage via le port USB device :

    WCHISPTool_CMD -p /dev/ch37x0 -c CH32V208WBU6.ini -o verify -f votre-firmware.hex
  • Flasher le micro-contrôleur via le port série :

    WCHISPTool_CMD -p /dev/ttyISP0 -b 115200 -c CH32V208WBU6.ini -o program -f votre-firmware.hex
  • Vérifier le flashage via le port série :

    WCHISPTool_CMD -p /dev/ttyISP0 -b 115200 -c CH32V208WBU6.ini -o verify -f votre-firmware.hex

Bien sûr, les paramètres en italique dans les commandes ci-dessus sont à remplacer par vos valeurs.

Utilisation de WCHISPTool pour générer les fichiers .ini

L'application Windows WCHISPTool fonctionne mal sous Wine, mais suffisamment pour pouvoir générer vos fichiers .ini si vous le souhaitez. Je suppose que vous avez installé Wine et que vous avez installé WCHISPTool à l'aide de l'installateur disponible ici.

Le programme principal, WchISpStudio, ne fonctionne pas du tout sous Wine, mais son rôle est de lancer des programmes spécialisés pour chaque famille de micro-contrôleurs et ces derniers fonctionnent plus ou moins. Pour les lancer manuellement, vous devrez vous placer dans le répertoire d'installation de WCHISPTool et exécuter le programme dédié depuis ce répertoire. Exemple :

cd ~/.wine/drive_c/WCHISPTool
wine WCHISPTool_CH32Vxxx/WCHISPTool_CH32Vxxx.exe

Une autre possibilité est d'ajouter le répertoire d'installation de WCHISPTool (ici "~/.wine/drive_c/WCHISPTool") au PATH de Wine et de lancer directement l'exécutable approprié avec Wine.

Une fois ce programme lancé, sélectionnez la série puis le modèle de micro-contrôleur (ex. CH32V20x puis CH32V208WBU6), puis de cliquer sur l'icône d'exportation de configuration et d'indiquer le nom du .ini. La démarche est résumée sur la copie d'écran ci-dessous :

Utilisation d'OpenOCD

Je suppose que vous avez créé les liens symboliques dans /opt/toolchain tels que décrits dans la section IDE et toolchain. Je suppose également que vous avez activé l'interface à 2 fils de votre micro-contrôleur, sans quoi rien ne fonctionnera.

Vous pouvez utiliser OpenOCD pour flasher votre micro-contrôleur de la manière suivante :

/opt/toolchain/openocd-wch/bin/openocd \
    -f /opt/toolchain/openocd-wch/bin/wch-riscv.cfg \
    -c "program votre_firmware.elf verify reset exit"

Contrairement à WCHISPTool_CMD, OpenOCD ne nécessite aucune autre manipulation que d'exécuter la ligne de commande. Vous pouvez donc l'utiliser pour flasher votre micro-contrôleur dans un contexte de développement "hardware in the loop" (intégration continue, déploiement automatique, exécution de tests sur une carte prototype).

Pour utiliser OpenOCD comme serveur pour debugger votre application avec GDB, la commande suivante suffit :

/opt/toolchain/openocd-wch/bin/openocd \
    -f /opt/toolchain/openocd-wch/bin/wch-riscv.cfg

Reportez-vous à la documentation d'OpenOCD pour démarrer votre session de debugging et à celle de GDB pour de plus amples informations. Utiliser MRS vous dispense d'affronter cette complexité supplémentaire.


Copyright (c) 2024 Vincent DEFERT - Tous droits réservés