Con i due core presenti nel processore ARM a bordo, Pico può essere programmato per il multi-threading, l’esecuzione in parallelo di codice.
Se provieni dal mondo dello sviluppo software, sarai abituato al fatto che i tuoi programmi siano in grado di fare più di una cosa alla volta – stiamo parlando di multi-threading. Questo tipo di funzionamento si basa sul passaggio del sistema operativo da un processo all’altro, per dare l’impressione che più cose accadano contemporaneamente, o sull’utilizzo di più processori. La maggior parte dei microcontrollori non utilizza un sistema operativo per pianificare i processi e opera su un singolo processore (core). Di solito è possibile aggirare questa limitazione utilizzando gli interrupt (come abbiamo visto in precedenza),ma il Pico può effettivamente eseguire due task contemporaneamente.
Il Pico è un dispositivo dual-core (due processori), il che significa che, anche senza sistema operativo, può assegnare attività a due processi diversi, permettendogli di compiere realmente due compiti allo stesso tempo. Spesso, in un sistema embedded, è corretto eseguire due task in parallelo: un ciclo eterno può far funzionare l’interfaccia utente (aspettando la pressione dei pulsanti e visualizzando le cose) mentre l’altro controlla interattivamente le attività.
Possiamo riscrivere il nostro esempio di interrupt (articoli precedenti) per utilizzare due core: un core conta e basta, mentre l’altro attende la pressione di un pulsante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from machine import Pin from utime import sleep import _thread interruttore = Pin(10, Pin.IN, Pin.PULL_UP) def core0(): x = 0 while True: x += 1 print(x) sleep(1) def core1(): while True: if interruttore.value() == 0: print('interruttore premuto') sleep(0.1) _thread.start_new_thread(core1, ( )) core0() |
Un buon modo per separare ciò che farà ciascun core è definire una funzione in cui andrà il codice di quel core. Quindi, in questo caso, core0 inizializza una variabile contatore ( x ) su 0 e poi esegue un ciclo infinito, aggiungendo 1 a x e stampandola.
L’altro core ( core1 ) ha un secondo ciclo eterno, che stampa un messaggio quando avviene la pressione di un interruttore.
La funzione core1 viene avviata chiamando il metodo start_new_thread su _thread . Nel caso del Pico, _thread è solo un modo per identificare
il secondo core ( core 1 ).
La funzione core0 è appena stata avviata come una normale chiamata di funzione.
E’ facile notare che, anche in presenza di timer bloccanti (sleep()) all’interno di cicli infiniti, l’applicazione non subirà alcun rallentamento: infatti ciascun ramo del codice verrà eseguito ssu di un core separato.
Link utili:
- Programmazione interrupts sul Raspberry RP2040 1/2
- Programmazione interrupts sul Raspberry RP2040 2/2
- Programmiamo il Pico: Impariamo l’elettronica e la programmazione con il Raspberry PI Pico
- Raspberry PI Pico
- Raspberry PI Pico W
- Raspberry PI Pico kit
Join our groups on Telegram…