04/03/2023
202303040800 bit perl
Les bits
J'ai toujours eu un peu de mal à avoir la représentation binaire d'une valeur, qu'elle soit au format décimal ou hexadécimal (là j'ai vraiment beaucoup de mal). Mais jouer avec des microcontrôleurs impose tôt ou tard de se retrouver avec ce genre de chose:
RCC->APB1ENR |= 0x200000;
APB1ENR est une valeur sur 32 bits décomposés en bit (parfois en groupe de bit) et ici on active un de ces bits. Mais lequel ? Pour me simplifier la vie, je me suis donc fendu d'un script (Perl, what else ?) sans prétention qui m'affiche, pour chaque argument, sa valeur binaire:
$ perl bits.pl 0x200000 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -------------------------------------------------------------------------------------------------------------------------------- 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0x200000 (2097152)
En consultant la documentation, je comprend que le bit 21 du registre APB1ENR correspond (pour une blue pill) à l'activation de I2C1. Parce que certains registres sont sur 16 bits, je peux aussi réduire le nombre de bit à afficher:
$ perl bits.pl -16 0x800 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ---------------------------------------------------------------- 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0x800 (2048)
ou modifier la largeur de chaque colonne (pas le plus simple à lire, j'en conviens):
$ perl bits.pl -8 -w 1 5 7 9 76543210 -------- 00000101 5 (5) 00000111 7 (7) 00001001 9 (9)
Je peux aussi utiliser des valeurs binaires directement à des fins de comparaison:
$ perl bits.pl -8 0b00000111 0b10101010 5 0xa 7 6 5 4 3 2 1 0 -------------------------------- 0 0 0 0 0 1 1 1 0b00000111 (7) 1 0 1 0 1 0 1 0 0b10101010 (170) 0 0 0 0 0 1 0 1 5 (5) 0 0 0 0 1 0 1 0 0xa (10)
Les opérateurs et fonctions Perl
Avec l'opérateur .. je peux facilement obtenir la liste des nombres de 0 à 15:
$ perl -le 'print 0 .. 15' 0123456789101112131415
Mais pas ceux de 15 à 0:
$ perl -le 'print 15 .. 0' <rien, nada, que dalle>
Pour afficher mes nombres dans l'ordre décroissant, il me suffit d'utiliser reverse:
$ perl -le 'print reverse 0 .. 15' 1514131211109876543210
Pour afficher une valeur sur 3 caractères j'utilise %3s. Pour formater size bits sur une largeur de width il me suffit d'utiliser l'opérateur x:
$fmt = "%${width}s" x $size-- . '%s'; // on n'oublie pas le '%s' pour le retour à la ligne
Parce que j'utilise reverse, je dois commencer par le retour chariot:
printf $fmt, reverse "\n", 0 .. $size;
Pour connaitre la valeur d'un bit à la position $pos d'une valeur $value, je dois déplacer la valeur 1 de $pos positions:
1 << $pos
faire un et avec la valeur:
$value & (1 << $pos)
et redécaler ce résultat de pos positions (les parenthèses sont nécessaires du fait de la priorité des opérateurs):
($value & (1 << $pos)) >> $pos
Pour obtenir la valeur des $size premiers bits de $register:
map { ($register & (1 << $_)) >> $_ } 0 .. $size;
map va appliquer le block ({ .. }) pour chaque valeur ($_) de la list 0 .. $size
Le script
Comme d'habitude, pour quelques lignes de code, on se trouve avec une gestion des options, de l'aide, de la vérification d'arguments ... et paf, 50 lignes:
$ cat -n bits.pl 1 #!/usr/bin/perl 2 3 use strict; 4 use warnings FATAL => 'all'; 5 use utf8; 6 7 use Getopt::Long; 8 9 sub usage { 10 print <<EOT 11 Usage: $0 [-8|-16|-32] [--width=width] [-h] number ... 12 13 Example: 14 $0 42 0xcafe 0b101 15 $0 -8 -w 1 5 16 EOT 17 ; 18 exit; 19 } 20 21 my ($size, $width, $help) = (32, 4); 22 GetOptions( 23 '8' => sub { $size = 8 }, 24 '16' => sub { $size = 16 }, 25 '32' => sub { $size = 32 }, 26 27 'width=i' => \$width, 28 'help' => \$help, 29 ) or usage(); 30 31 if ($help || !scalar @ARGV) { usage(); } 32 33 my $fmt; 34 sub dump_register { 35 my $register = $_[0] =~ /^0[bx]/i ? oct $_[0] : $_[0]; 36 printf $fmt, reverse " $_[0] ($register)\n", map { ($register & (1 << $_)) >> $_ } 0 .. $size; 37 } 38 39 if ($width < 2 && $size > 8) { $width = 3; } 40 $fmt = "%${width}s" x $size-- . '%s'; 41 42 printf $fmt, reverse "\n", 0 .. $size; 43 printf $fmt, (('-' x $width)) x ($size + 1) , "\n"; 44 45 foreach (@ARGV) { dump_register($_); }
Pour finir
Quand je tombe sur ce genre de chose:
GPIOA->CRL &= ~(0xf << (2 * 4)); GPIOA->CRL |= 0xA << (2 * 4);
Il me suffit de rajouter en fin de script:
my $register = $ARGV[0] =~ /^0[bx]/i ? oct $ARGV[0] : $ARGV[0]; $register &= ~(0xf << (2 * 4)); dump_register($register); $register |= 0xA << (2 * 4); dump_register($register);
et de le lancer avec 0xffffffff (pour que tous les bits soient à 1):
$ perl bits.pl 0xffffffff 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -------------------------------------------------------------------------------------------------------------------------------- 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0xffffffff (4294967295) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 4294963455 (4294963455) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 4294966015 (4294966015)
La première instruction initialise à zéro le 3ème groupe de 4 bits, la seconde active les bits 1 (9) et 3 (11) de ce 3ème groupe. Et tout est plus clair !
Commentaires: https://github.com/bsdsx/blog_posts/issues/17
09/10/2022
202210090800 stm32 bluepill elf
FreeBSD et bluepill, corrections
J'ai raconté plusieurs conneries dans mon billet FreeBSD et bluepill qu'il me faut corriger.
openocd et mon adaptateur
Quand openocd affiche le message suivant:
$ openocd -f openocd.cfg -c "init" Open On-Chip Debugger 0.11.0 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD none separate Info : clock speed 1000 kHz Info : STLINK V2J17S4 (API v2) VID:PID 0483:3748 Info : Target voltage: 3.137032 Warn : UNEXPECTED idcode: 0x2ba01477 Error: expected 1 of 1: 0x1ba01477
Ce n'est pas l'adaptateur qui pose problème mais bien la bluepill comme on peut le lire sur hackaday.com:
[ snip bluepill version Chang ] ... A major difference one will quickly encounter with this chip is when programming it and getting the message "UNEXPECTED idcode: 0x2ba01477". The reason for this is that the STM32F103 MCU reports the ID 0x1ba01477, confusing the programmer. ....
core.S
Toujours depuis ce fichier assembleur, avec une nouvelle modification en provenance directe du jardin magique (merki miod@ et semarie@): utiliser le préprocesseur pour définir la valeur du registre r7:
$ fetch -o - https://raw.githubusercontent.com/WRansohoff/STM32F0_minimal/master/core.S | sed -e 's/cortex-m0/cortex-m3/' -e 's/reset_handler/Reset_Handler/g' -e 's/_estack/__end_stack/' -e 's/0xDEADBEEF/R7_REGISTER/' > core.S
On compile avec l'option -x assembler-with-cpp et la valeur:
$ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -x assembler-with-cpp -DR7_REGISTER=0xDEADBEEF -c core.S -o core.o
On génère le binaire avec le linker script :
$ fetch -o stm32-base.zip https://github.com/STM32-base/STM32-base/archive/refs/heads/master.zip $ tar xf stm32-base.zip STM32-base-master/linker $ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -nostdlib -L STM32-base-master/linker -T STM32-base-master/linker/STM32F1xx/STM32F103xB.ld core.o -o core.elf
Pour vérifier la prise en compte de la valeur:
$ readelf -x .text main.elf Hex dump of section '.text': 0x08000000 00500020 09000008 02488546 024f0020 .P. .....H.F.O. 0x08000010 401cfde7 00500020 efbeadde @....P. ....
Où efbeadde correspond bien à la version petit boutiste de DEADBEEF.
objcopy
Partie la plus sensible qui va me jouer des tours pendant plusieurs semaines, la conversion du .elf en .bin . On peut lire un peu partout cette commande:
$ objcopy -O binary main.elf main.bin
Mais sur FreeBSD on trouve 2 objcopy:
$ ls -l /usr/bin/*objcopy -r-xr-xr-x 2 root wheel 4025248 May 21 09:32 /usr/bin/llvm-objcopy -r-xr-xr-x 2 root wheel 129560 May 21 09:32 /usr/bin/objcopy $ file /usr/bin/*objcopy /usr/bin/llvm-objcopy: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, FreeBSD-style, stripped /usr/bin/objcopy: ELF 64-bit LSB pie executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 13.1, FreeBSD-style, stripped
En partant d'un fichier source aussi simple que celui-ci:
void __libc_init_array(void) {} // startup_common.s
int integer_in_data_section = 1; // la section .data ne doit pas être vide int main(void) { int i = 0; while (1) { i += integer_in_data_section; } return i; }
Je commence par compiler un fichier assembleur correspondant à la carte:
$ tar xf stm32-base.zip STM32-base-master/startup $ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -I STM32-base-master/startup -c STM32-base-master/startup/STM32F1xx/STM32F103xB.s -o startup.o STM32-base-master/startup/startup_common.s:24:1: warning: Reset_Handler changed binding to STB_WEAK .weak Reset_Handler
puis mon fichier source:
$ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -c main.c -o main.o $ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -nostdlib -L STM32-base-master/linker -T STM32-base-master/linker/STM32F1xx/STM32F103xB.ld main.o startup.o -o main.elf $ size main.elf text data bss dec hex filename 416 4 1536 1956 0x7a4 main.elf
que je dois convertir en .bin :
$ objcopy -O binary main.elf main.bin $ ls -l main.bin -rwxr-xr-x 1 dsx wheel 402653188 2 nov. 19:39 main.bin
400 Mo pour incrémenter une variable, on dépasse un peu les bornes des limites. Avec le "bon" objcopy:
$ llvm-objcopy -O binary main.elf main.bin $ ls -l main.bin -rwxr-xr-x 1 dsx wheel 420 2 nov. 19:41 main.bin
A moi (enfin !) les <blink>leds</blink> qui clignottent !
Commentaires: https://github.com/bsdsx/blog_posts/issues/16
09/10/2022
202210090800 stm32 bluepill
FreeBSD et bluepill
A force de suivre les vidéos de Sieur Rancune j'ai fini par craquer pour une poignée de bluepill. Parce qu'il est conseillé sur tous les interweb d'utiliser arm-none-eabi-gcc pour programmer ces charmantes bestioles j'ai décidé d'utiliser clang/llvm livré de base.
Si allumer une led constitue le 'Hello World!' de l'électronique, j'ai découvert le niveau -1 en lisant cette série de billets: placer une valeur particulière dans un registre.
Les sources
Le fichier core.S requiert 3 modifications mineures:
- adapter le type de cpu
- modifier la casse de la fonction reset_handler
- renommer une variable
$ fetch -o - https://raw.githubusercontent.com/WRansohoff/STM32F0_minimal/master/core.S | sed -e 's/cortex-m0/cortex-m3/' -e 's/reset_handler/Reset_Handler/g' -e 's/_estack/__end_stack/' > core.S $ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -c core.S -o core.o
Le binaire
Pour que mon binaire final soit adapté à ma carte, je dois récupérer un 'linker script':
$ fetch https://github.com/STM32-base/STM32-base/archive/refs/heads/master.zip $ tar xf master.zip STM32-base-master/linker $ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -nostdlib -L STM32-base-master/linker -T STM32-base-master/linker/STM32F1xx/STM32F103xB.ld core.o -o main.elf
C'est pour se conformer à ce script qu'il faut modifier le fichier core.S.
Les soucis commencent
Avant d'envoyer le fichier sur la carte, il faut le convertir:
$ objcopy -O binary main.elf main.bin $ du -Ah main.bin 384M main.bin
Là je crois qu'on dépasse les bornes des limites: ça fait beaucoup de méga pour placer une valeur dans un registre. Si je regarde mon fichier elf:
$ readelf -l main.elf | grep 0x Entry point 0x8000009 LOAD 0x010000 0x08000000 0x08000000 0x0001c 0x0001c R E 0x10000 LOAD 0x020000 0x20000000 0x20000000 0x00600 0x00600 RW 0x10000 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0 ARM_EXIDX 0x01001c 0x0800001c 0x0800001c 0x00000 0x00000 R 0x4
Je peux me passer de GNU_STACK avec l'option -z nognustack:
$ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -z nognustack -nostdlib -L STM32-base-master/linker -T STM32-base-master/linker/STM32F1xx/STM32F103xB.ld core.o -o main.elf $ readelf -l main.elf | grep 0x Entry point 0x8000009 LOAD 0x010000 0x08000000 0x08000000 0x0001c 0x0001c R E 0x10000 LOAD 0x020000 0x20000000 0x20000000 0x00600 0x00600 RW 0x10000 ARM_EXIDX 0x01001c 0x0800001c 0x0800001c 0x00000 0x00000 R 0x4
Mais cela ne corrige pas le problème. J'ai fini par comprendre qu'une section n'avait pas le bon type:
$ readelf -S main.elf.OK | grep ._user_heap_stack [ 6] ._user_heap_stack NOBITS 20000000 020000 000600 00 WA 0 0 1 $ readelf -S main.elf.KO | grep ._user_heap_stack [ 7] ._user_heap_stack PROGBITS 20000000 020000 000600 00 WA 0 0 1
La correction la plus simple que j'ai trouvé est de passer cette section en 'NOLOAD':
$ grep ._user_heap_stack STM32-base-master/linker/common.ld ._user_heap_stack (NOLOAD) : { $ clang --target=arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -z nognustack -nostdlib -L STM32-base-master/linker -T STM32-base-master/linker/STM32F1xx/STM32F103xB.ld core.o -o main.elf $ readelf -S main.elf | grep ._user_heap_stack [ 8] ._user_heap_stack NOBITS 20000000 020000 000600 00 WA 0 0 1 $ objcopy -O binary main.elf main.bin $ du -Ah main.bin 512B main.bin
C'est déjà plus raisonnable.
Les soucis continuent
Il est temps de programmer la carte. J'utilise donc un adaptateur usb st link v2 et devel/openocd avec la configuration suivante:
$ cat openocd.cfg source [find interface/stlink.cfg] transport select hla_swd source [ find target/stm32f1x.cfg] reset_config none separate
Je connecte la bluepill à l'adaptateur, je branche l'adaptateur et paf:
$ openocd -f openocd.cfg -c "init" Open On-Chip Debugger 0.11.0 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD none separate Info : clock speed 1000 kHz Info : STLINK V2J17S4 (API v2) VID:PID 0483:3748 Info : Target voltage: 3.137032 Warn : UNEXPECTED idcode: 0x2ba01477 Error: expected 1 of 1: 0x1ba01477
Pour qu'openocd daigne utiliser mon adaptateur je dois lui dire qu'il est "de confiance" (kofkof):
$ cat openocd.cfg set CPUTAPID 0x2ba01477 source [find interface/stlink.cfg] transport select hla_swd source [ find target/stm32f1x.cfg] reset_config none separate $ openocd -f openocd.cfg -c "init" Open On-Chip Debugger 0.11.0 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD none separate Info : clock speed 1000 kHz Info : STLINK V2J17S4 (API v2) VID:PID 0483:3748 Info : Target voltage: 3.138581 Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints Info : starting gdb server for stm32f1x.cpu on 3333 Info : Listening on port 3333 for gdb connections Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections
Et quand y'en a plus y'en a encore
On va facilement trouver des exemples d'utilisation conjointe d'openocd et de gdb. Pas de bol pour moi, le debugger llvm n'est pas compatible, d'après https://stackoverflow.com/questions/36287351/how-to-setup-lldb-with-openocd-and-jtag-board:
"from what we were researching, it is not possible to debug remote (bare-metal!) targets with lldb without writing extra code."
Et autant dire que l'extra code en python, je passe.
Le bout du tunnel
Je vais donc utiliser l'interface "telnet" d'openocd:
$ echo 'reset halt' | nc -N 127.0.0.1 4444 Open On-Chip Debugger > reset halt target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x1fffe61c msp: 0x20000180 $ echo 'stm32f1x mass_erase 0' | nc -N 127.0.0.1 4444 Open On-Chip Debugger > stm32f1x mass_erase 0 device id = 0x20036410 flash size = 25616kbytes stm32x mass erase complete $ md5 main.bin MD5 (main.bin) = 09c6d874e631d40370b70a7bcc120f41 $ echo 'flash write_image erase main.bin 0x8000000' | nc -N 127.0.0.1 4444 Open On-Chip Debugger > flash write_image erase main.bin 0x8000000 auto erase enabled wrote 1024 bytes from file main.bin in 0.087373s (11.445 KiB/s) $ echo 'reset run' | nc -N 127.0.0.1 4444 Open On-Chip Debugger > reset run $ echo 'halt' | nc -N 127.0.0.1 4444 Open On-Chip Debugger > halt target halted due to debug-request, current mode: Handler HardFault xPSR: 0x00000003 pc: 0x012fff1e msp: 0xe59efff8 $ echo 'reg' | nc -N 127.0.0.1 4444 Open On-Chip Debugger > reg ===== arm v7m registers (0) r0 (/32): 0x008fec14 (1) r1 (/32): 0x00000000 (2) r2 (/32): 0x00000000 (3) r3 (/32): 0x00000000 (4) r4 (/32): 0x00000000 (5) r5 (/32): 0x00000000 (6) r6 (/32): 0x00000000 (7) r7 (/32): 0xdeadbeef (8) r8 (/32): 0x00000000 (9) r9 (/32): 0x00000000 (10) r10 (/32): 0x00000000 (11) r11 (/32): 0x00000000 (12) r12 (/32): 0x00000000 (13) sp (/32): 0x20005000 (14) lr (/32): 0xffffffff (15) pc (/32): 0x08000012 (16) xPSR (/32): 0x01000000 (17) msp (/32): 0x20005000 (18) psp (/32): 0x00000000 (20) primask (/1): 0x00 (21) basepri (/8): 0x00 (22) faultmask (/1): 0x00 (23) control (/3): 0x00 ===== Cortex-M DWT registers
Pour être sûr de mon coup, j'essaie avec les valeurs suivantes:
- OxCAFECAFE: MD5 (main.bin) = 45e3b36afd8ebd902675c26e804c21b5
- OxBABEBABE: MD5 (main.bin) = 4f03cd6b4a29ca80dc28fc49401cb1c5
- Ox12345678: MD5 (main.bin) = 908fc5196f85ade8321d1d951d8035f7
A moi les qui clignottent !
Commentaires: https://github.com/bsdsx/blog_posts/issues/15
21/05/2022
202205210800 yubikey
FreeBSD 13.1, OpenSSH et Yubikey
Cette nouvelle mouture de FreeBSD vient entre autre avec une mise à jour d'OpenSSH et ça cause FIDO/U2F. Il serait temps d'utiliser enfin cette Yubikey qui traine sur mon porte-clefs depuis des lustres:
$ dmesg | tail -n 6 ugen0.3: <Yubico YubiKey OTP+FIDO+CCID> at usbus0 ukbd1 on uhub0 ukbd1: <Yubico YubiKey OTP+FIDO+CCID, class 0/0, rev 2.00/5.12, addr 7> on usbus0 kbd3 at ukbd1 uhid1 on uhub0 uhid1: <Yubico YubiKey OTP+FIDO+CCID, class 0/0, rev 2.00/5.12, addr 7> on usbus0
On va s'éparger du temps et des cheveux avec ce petit paquet kivabien:
$ doas pkg install u2f-devd $ doas service devd restart $ doas pw groupmod u2f -m MonLogin [ snip déco/reco pour que le nouveau groupe soit pris en compte ] $ ssh-keygen -t ed25519-sk Generating public/private ed25519-sk key pair. You may need to touch your authenticator to authorize key generation. Key enrollment failed: requested feature not supported
Pas de soucis, c'est juste que le firmware de la clef est trop vieux pour utiliser ed25519-sk. Avec ecdsa-sk:
$ ssh-keygen -t ecdsa-sk Generating public/private ecdsa-sk key pair. You may need to touch your authenticator to authorize key generation. [ la clef clignotte et attend une pression ] Enter file in which to save the key (/home/MonLogin/.ssh/id_ecdsa_sk): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/MonLogin/.ssh/id_ecdsa_sk Your public key has been saved in /home/MonLogin/.ssh/id_ecdsa_sk.pub$ ssh-keygen -t ecdsa-sk ...
Reste à déployer cette clef:
$ cat .ssh/id_ecdsa_sk.pub | ssh MonServeur "cat >> .ssh/authorized_keys" $ unsetenv SSH_AUTH_SOCK $ ssh -i .ssh/id_ecdsa_sk MonServeur Confirm user presence for key ECDSA-SK SHA256:gkWxSHUxZjN5Q6svr51Mi0N+vMc051YPwXo7L1JkaQw [ la clef clignotte et attend une pression ] User presence confirmed Last login: Sat May 21 10:07:59 2022 from dd.bsdsx.fr ...
Parfois la clef ne semble pas répondre:
$ ssh -i .ssh/id_ecdsa_sk nuc date Confirm user presence for key ECDSA-SK SHA256:gkWxSHUxZjN5Q6svr51Mi0N+vMc051YPwXo7L1JkaQw User presence confirmed sam. 21 mai 2022 10:17:09 CEST $ ssh -i .ssh/id_ecdsa_sk nuc date Confirm user presence for key ECDSA-SK SHA256:gkWxSHUxZjN5Q6svr51Mi0N+vMc051YPwXo7L1JkaQw User presence confirmed sam. 21 mai 2022 10:17:14 CEST $ ssh -i .ssh/id_ecdsa_sk nuc date Confirm user presence for key ECDSA-SK SHA256:gkWxSHUxZjN5Q6svr51Mi0N+vMc051YPwXo7L1JkaQw User presence confirmed sam. 21 mai 2022 10:17:20 CEST $ ssh -i .ssh/id_ecdsa_sk nuc Confirm user presence for key ECDSA-SK SHA256:gkWxSHUxZjN5Q6svr51Mi0N+vMc051YPwXo7L1JkaQw [ la clef ne clignotte pas ]
Pas grand chose à faire:
^C $ ssh -i .ssh/id_ecdsa_sk nuc Confirm user presence for key ECDSA-SK SHA256:gkWxSHUxZjN5Q6svr51Mi0N+vMc051YPwXo7L1JkaQw User presence confirmed Last login: Sat May 21 10:14:38 2022 from dd.bsdsx.fr
Lien utile: https://cryptsus.com/blog/how-to-configure-openssh-with-yubikey-security-keys-u2f-otp-authentication-ed25519-sk-ecdsa-sk-on-ubuntu-18.04.html (anglais)
Commentaires: https://github.com/bsdsx/blog_posts/issues/14
16/04/2022
202204160800 esp8266 python
esp8266 et MicroPython
Il y a déjà plusieurs mois, au détour d'une commande de composants électronique, j'avais ajouté dans mon panier un choupi bouzin àpacher qui non seulement faisait wifi mais intégrait en plus un écran oled. Vite oublié pendant ma découverte de l'Arduino, revoila t'y pas que je tombe dessus en faisant un peu de tri dans mon bazar.
Le bouzin
C'est un heltec wifi kit 8. Il existe une autre version plus péchue du bouzin, le wifi kit 32 pour qui il faudra faire en gros
s/8266/32/gc
Installer de quoi causer avec le bouzin:
$ doas pkg install py38-esptool
Tester qu'on peut causer avec le bouzin:
$ esptool.py --port /dev/cuaU0 --chip ESP8266 read_mac esptool.py v3.3 Serial port /dev/cuaU0 Connecting......... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: dc:4f:22:19:18:88 Uploading stub... Running stub... Stub running... MAC: dc:4f:22:19:18:88 Hard resetting via RTS pin
$ esptool.py --port /dev/cuaU0 --chip ESP8266 flash_id esptool.py v3.3 Serial port /dev/cuaU0 Connecting......... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: dc:4f:22:19:18:88 Uploading stub... Running stub... Stub running... Manufacturer: ef Device: 4016 Detected flash size: 4MB Hard resetting via RTS pin...
On a bien un bouzin avec 4 Mo de RAM (Detected flash size: 4MB), on va pouvoir jouer avec MicroPython
- https://www.micropython.fr/
- http://docs.micropython.org/en/latest/esp8266/quickref.html
- https://randomnerdtutorials.com/projects-esp32-esp8266-micropython/
MicroPython
L'installation de MicroPython est largement décrite dans les liens précédents, mais histoire d'avoir une version FreeBSD:
On nettoie le bouzin:
Tout en pressant le bouton 'PRG' (on peut le relacher quand apparait 'Erasing flash (this may take a while)...')
$ esptool.py --port /dev/cuaU0 --chip ESP8266 erase_flash esptool.py v3.3 Serial port /dev/cuaU0 Connecting...... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: dc:4f:22:19:18:88 Uploading stub... Running stub... Stub running... Erasing flash (this may take a while)... Chip erase completed successfully in 7.4s Hard resetting via RTS pin...
Et on installe micropython fraîchement téléchargé depuis https://micropython.org/download/esp8266/ :
Tout en pressant le bouton 'PRG' (on peut le relacher quand apparait le pourcentage de progression)
$ esptool.py --port /dev/cuaU0 --chip ESP8266 write_flash --flash_mode dio --flash_size detect 0x0 /tmp/esp8266-20220117-v1.18.bin esptool.py v3.3 Serial port /dev/cuaU0 Connecting...... Chip is ESP8266EX Features: WiFi Crystal is 26MHz MAC: dc:4f:22:19:18:88 Uploading stub... Running stub... Stub running... Configuring flash size... Auto-detected Flash size: 4MB Flash will be erased from 0x00000000 to 0x0009bfff... Flash params set to 0x0240 Compressed 635992 bytes to 418428... Wrote 635992 bytes (418428 compressed) at 0x00000000 in 37.2 seconds (effective 136.9 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...
Et maintenant magie du bouzin:
Taper Enter pour afficher l'invite de l'interpréteur python (>>>), tilde + point pour quitter cu
$ cu -l /dev/cuaU0 -s 115200 can't open log file /var/log/aculog. Connected >>> import esp >>> esp.check_fw() size: 635976 md5: 40b5ad861d83667d6c8ea59fd38c7ff9 True
Il ne me serait jamais venu à l'esprit d'utiliser un language de si haut niveau avec un microcontrôleur (le C c'est bon, mangez-en) mais je dois avouer que la simplicité du truc m'a laissé sur le cul.
L'interpréteur python c'est bien pratique pour tester en direct mais pour survivre à un reset il faut télécharger le code sur le bouzin:
$ doas pkg install py38-adafruit-ampy $ ampy --port /dev/cuaU0 ls /boot.py
Reste à lire https://pythonforundergradengineers.com/upload-py-files-to-esp8266-running-micropython.html, envoyer son premier main.py et reset le bouzin.
Le traditionnel clignotement de led se verra remplacé ici par l'affichage d'un "Hello world" (il n'y a pas de led pilotable sur la carte). J'ai suivi les liens suivants:
- https://robotzero.one/heltec-wifi-kit-8/
- https://micropython.fr/modules_center/seriel_i2c/oled_128x64_0_96_ssd_1306/
- https://resource.heltec.cn/download/WiFi_Kit_8/WIFI_Kit_8_Pinout_Diagram.pdf
- https://resource.heltec.cn/download/WiFi_Kit_8/WIFI_Kit_8_Schematic_diagram.PDF
Je commence par scanner le bus i2c:
>>> from machine import Pin, I2C >>> i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) >>> devices = i2c.scan() >>> print('i2c devices found:', len(devices)) i2c devices found: 1 >>> for device in devices: ... print("Decimal address: ", device, " | Hexa address: ", hex(device)) ... [ appui sur backspace puis enter ] Decimal address: 60 | Hexa address: 0x3c
Je récupère le module kivabien:
$ cd /tmp && fetch https://raw.githubusercontent.com/micropython/micropython/master/drivers/display/ssd1306.py && ampy --port /dev/cuaU0 put ssd1306.py && ampy --port /dev/cuaU0 ls /boot.py /ssd1306.py
Et c'est parti:
>>> from machine import Pin, I2C >>> import ssd1306 >>> i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) >>> oled = ssd1306.SSD1306_I2C(128, 32, i2c, 0x3c) >>> oled.fill(0) >>> oled.text("Hello World", 0, 0) >>> oled.show()
Je ne dirais pas que le python est ma tasse de thé ou mon bol de chocolat ou mon mug de café mais il faut bien reconnaitre que:
- l'installation de micropython est neuneuproof
- la documentation est abondante
- la liste des modules disponibles est plus que conséquente (https://micropython.fr/modules_center/)
- l'accès à un interpréteur est redoutable d'efficacité lors des tests
Commentaires: https://github.com/bsdsx/blog_posts/issues/13