Nuuo NVRmini NV-4080S/Promise NS4600 (2)
Date: 2025-10-27
Tags: info linux réseau microcontrolleur
Je voulais utiliser le NAS montré dans un article précédent, avec un firmware alternatif, en installant Linux sur un disque dur ou une clé USB.
Pour des raisons inexpliquées, U-Boot n’alimente pas les périphériques SATA ni les périphériques USB lors du démarrage. Ça peut fonctionner avec le firmware original qui n’utilise que la mémoire flash, mais pas dans mon cas : seuls le noyau et l’initrd sont stockés dans la mémoire flash. Le reste de l’OS est stocké sur un disque-dur SATA.
Sauf qu’il est possible de démarrer lorsque l’on interrompt le démarrage automatique de U-Boot, puis que l’on tape une commande pour continuer son exécution.
Test manuel
On branche un PC avec un adaptateur USB-Série 3.3V sur le connecteur J11, on alimente le NAS, et on regarde ce qu’il affiche dans un terminal :
U-Boot 1.3.4 (NS4600p - 014 - 800MHz) (Nov 04 2010 - 14:03:07)
CPU: AMCC PowerPC 431EXr at 800 MHz (PLB=200, OPB=100, EBC=100 MHz)
Security/Kasumi support
Bootstrap Option F - Boot ROM Location NAND (8 bits), booting from NAND
Internal PCI arbiter disabled
32 kB I-Cache 32 kB D-Cache
Board: NS4600p - PROMISE 4-bay NAS Target Board, 1*PCIe/1*SATA
I2C: ready
DRAM: 256 MB
Enclosure: Load fan configurations from VPD
NAND: 128 MiB
eth0 MAC = 00:01:55:31:1f:21
eth1 MAC = 00:00:00:00:00:00
PCI: Bus Dev VenId DevId Class Int
PCIE1: successfully set as root-complex
01 00 105a 3f20 0104 00
SCSI: Net: ppc_4xx_eth0
Hit Ctrl + C to stop autoboot: 10
Si on n’appuie pas sur Ctrl-C, U-Boot charge le noyau et l’initrd en mémoire, mais n’alimente pas les disques, le noyau ne trouve pas de disque-dur et plante2.
Si on appuie sur Ctrl-C, U-Boot exécute quelques commandes avant de donner un shell :
Leave clock generator PD mode... OK
Leave net PHY PD mode... OK
Turn on all activity LED power... OK
FAN_SET mode... OK
Turn off all status LED... OK
Turn on disk power... OK
=>
On entend bien les disques SATA démarrer, on peut taper
boot, et la machine démarre correctement, puisque le noyau
est capable de détecter les disques-durs.
Automatisation
Exécuter une opération manuelle à chaque démarrage n’est pas très pratique, surtout en cas de re-démarrage imprévu. Comme l’opération est simple, on va utiliser un microcontrôleur.
Il faut les spécifications suivantes :
- Alimentation 3.3V
- UART 115200 bits/s 8N1
Arduino
Par habitude, l’environnement de développement Arduino est pratique pour des prototypes simples, et la variante hardware Pro Mini3 est compacte et s’alimente en 3.3V.
Je rencontre quelques soucis : il m’est impossible de faire fonctionner l’UART correctement à 115200 bit/s, puisque les cartes alimentées en 3.3V ont un quartz à 8MHz, et des diviseurs d’horloge qui ne permettent pas à l’UART de fonctionner à la bonne fréquence4.
J’avais commencé par suspecter les bibliothèques Arduino, avant d’utiliser le MCU bare-metal. Le code est plus long à écrire, mais l’exécution est plus rapide et on contrôle précisément ce que l’on fait. Comme mon problème d’UART était matériel, il n’a pas été résolu.
MSP430
J’ai une carte d’évaluation de MSP430 et un MSP430G2553 en stock, qui correspondent aux besoins5, avec l’intérêt supplémentaire d’avoir un oscillateur interne assez précis pour qu’aucun quartz ne soit nécessaire.
Energia
Energia est un port d’Arduino pour MSP430, qui permet de prototyper rapidement6.
L’intérêt est surtout de fournir une chaîne de développement quand les paquets ne sont plus présents dans Debian depuis 20197.
Pour utiliser la chaîne de développement sans l’IDE, il suffit d’adapter la commande suivante à l’endroit où les fichiers de Energia sont présents :
export PATH=$PATH:/opt/energia-1.8.10E23/hardware/tools/msp430/bin/
Le fonctionnement de Energia est correct, mais j’ai rencontré le même problème qu’avec le bibliothèques Arduino : le fichier exécutable est volumineux, et son exécution est lente. Ça fait une bonne excuse pour utiliser le MCU bare-metal.
Code
Le programme est construit avec deux machines d’état, et la réception des caractères se fait par interruptions.
On utilise un scheduler minimaliste8, où
une interruption de timer va exécuter ce scheduler à 1kHz, qui
va utiliser des variables (milliseconds et
seconds) pour exécuter d’autres tâches. Ça permet de
désactiver le CPU hors des interruptions, pour consommer moins
d’énergie9.
__attribute__ ((interrupt(TIMER0_A0_VECTOR))) void timer_A_ISR(void) {
milliseconds++;
if(!(milliseconds % 1000)) {
seconds++;
}
if(!(milliseconds % DELAY_FSM)) {
fsm(); // 100 Hz
}
}
On utilise une machine à 4 états pour recevoir les commandes et envoyer les commandes correspondantes.
void fsm() {
/*
* 0: default, listening for 1st string
* 1: 1st string matched, waiting 100ms, sending '^C'
* 2: listening for 2nd string
* 3: 2nd string matched, waiting 100ms, sending "boot\n"
*/
static unsigned long delay = 0;
switch(state) {
case 1:
if(delay == 0)
delay = milliseconds;
if(milliseconds - delay >= 100) {
putchar(0x03); // ^C
delay = 0;
state = 2;
//toggle_LED();
}
break;
case 2:
listening_cond(str2);
break;
case 3:
if(delay == 0)
delay = milliseconds;
if(milliseconds - delay >= 100) {
puts("boot\n");
delay = 0;
state = 0;
clearbuf();
//toggle_LED2();
}
break;
default:
listening_cond(str1);
break;
}
}
Les LEDs permettent de surveiller l’exécution lorsqu’on va tester la carte en conditions réelles, avec le debugger débranché.
Gestion de l’UART
La pratique par défaut est de stocker les caractères reçus dans un buffer circulaire10. Ensuite, on peut les extraire dans un buffer linéaire pour le comparer avec les chaînes de caractères de référence.
Ça fonctionne, mais ça utilise beaucoup de mémoire, et le parcours puis la copie du buffer sont lents. Il faut augmenter la taille du buffer pour ne pas rater de caractère, ce qui utilise encore plus de mémoire.
On va plutôt utiliser un buffer linéaire glissant, qui sont habituellement utilisés pour des opérations de filtrage. Le glissement du tableau se fait sur lui-même, et on peut comparer directement ce buffer avec les chaînes de caractères de référence.
Conditions réelles
Une fois les fonctions unitaires et le système validés, on peut brancher la carte d’évaluation au NAS.
Une fois l’alimentation du NAS branchée, les LEDs de la carte d’évaluation s’allument, et les disques durs du NAS se mettent à tourner.
Il ne reste plus qu’à câbler tout ça sur un morceau de plaque à trous.
Le code source est disponible11 sous license CC BY-NC.
Références
ATMega328P - Datasheet, section 19.11↩︎
MSP430F2xx, MSP430G2xx Family User’s Guide (Rev. K), MSP430G2553 - Datasheet↩︎
Il n’y a pas de drapeau pour forcer une exécution séquentielle, il faut s’assurer que les tâches se terminent assez vite et ne bloquent pas↩︎
La consommation théorique est de 4mA en mode Active à 16MHz et 3.3V, et <1uA en mode LPM3, heureusement que l’alimentation du NAS est capable de fournir 100W↩︎
- ← Previous page
Pi computation algorithms (2) - Next page →
cms
Electronics Électronique puissance semiconducteur semiconductors power Hardware CPE INSA Xavier Bourgeois
RSS - Blog