- C 99.2%
- Python 0.3%
- Assembly 0.3%
- CMake 0.2%
|
|
||
|---|---|---|
| cmake | ||
| Core | ||
| Drivers | ||
| .gitignore | ||
| .mxproject | ||
| BADUINO-32.png | ||
| beduino_setup.py | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| GPIO.ioc | ||
| logo.png | ||
| mini_logo.png | ||
| README.md | ||
| startup_stm32f411xe.s | ||
| STM32F411XX_FLASH.ld | ||
BADUINO
BADUINO (Bebbo + Arduino) è un framework che trasforma un progetto STM32 CubeMX in un ambiente di sviluppo semplice come Arduino, ma con la potenza e l'efficienza del CMSIS puro.
Nasce per lo studio della Black Pill STM32F411CEU6 sul canale YouTube Bebbo's Lab, con l'idea di abbassare la barriera d'ingresso per chi si avvicina ai microcontroller STM32.
Filosofia
STM32CubeMX è un tool eccellente per la configurazione grafica delle periferiche, ma il codice generato è verboso, pieno di commenti ST, e usa l'HAL (Hardware Abstraction Layer) che nasconde i registri e appesantisce il binario.
BADUINO non sostituisce CubeMX — lo affianca:
CubeMX (configurazione pin/periferiche) → GPIO.ioc
↓
BADUINO (codice utente pulito) → Core/BADUINO/
Dopo aver configurato i pin con CubeMX, l'utente scrive solo in Core/BADUINO/loop.c e setup.c, con API semplici e dirette. Il resto del progetto (Core/Src, Drivers, CMSIS) rimane intatto ma nascosto all'utente.
B-HAL (Bebbo Hardware Abstraction Layer)
B-HAL è la libreria Arduino-like che rende tutto semplice. Scritta in puro CMSIS, zero overhead.
| Funzione | Descrizione | Costo |
|---|---|---|
pinMode(pin, mode) |
Configura direzione/pull | call |
digitalWrite(pin, val) |
Scrive HIGH/LOW | inline |
digitalRead(pin) |
Legge stato pin | inline |
digitalToggle(pin) |
Inverte stato pin | inline |
delay(ms) |
Pausa in millisecondi | inline |
delayMicroseconds(us) |
Pausa in microsecondi | inline |
millis() |
ms dall'avvio | inline |
micros() |
µs dall'avvio | inline |
analogWrite(pin, val) |
PWM (0-255, stub) | call |
analogRead(pin) |
ADC (stub) | call |
Le funzioni inline hanno zero overhead rispetto a scrivere i registri a mano.
Pin encoding
PA(0) // PORTA pin 0
PC(13) // PORTC pin 13 (LED built-in sulla Black Pill)
PB(5) // PORTB pin 5
Primi passi
1. Clona il progetto
git clone <url-del-tuo-repo>
cd GPIO
2. Esegui lo script di setup (opzionale, solo su nuovi progetti)
# Con Python normale
python3 BADUINO_setup.py
# Oppure con uv
uv run BADUINO_setup.py
Nota: Se parti da questo progetto già configurato, lo script non è necessario. Serve solo se crei un nuovo progetto da CubeMX.
3. Compila
cmake --preset Debug
cmake --build --preset Debug
4. Scrivi il tuo codice
Apri Core/BADUINO/loop.c e scrivi:
digitalWrite(PC(13), LOW); // Accendi LED
delay(500);
digitalWrite(PC(13), HIGH); // Spegni LED
delay(500);
Oppure usa tutta la potenza del CMSIS:
GPIOC->ODR ^= (1 << 13); // Toggle LED (un ciclo!)
5. Usa printf su USART1
#include <stdio.h>
printf("Hello da BADUINO! tick=%lu\r\n", millis());
L'output esce su USART1 (PA9 TX, 115200 baud) — zero configurazione.
6. Abilita CMSIS puro negli IRQ
In Core/BADUINO/BADUINO.h, sblocca:
#define NO_HAL
Con questo flag, gli handler IRQ in Core/Src/stm32f4xx_it.c saltano le chiamate HAL e includono i file in Core/BADUINO/irq/, dove puoi scrivere codice CMSIS diretto.
Struttura del progetto
GPIO/
├── Core/
│ ├── Inc/ ← Header CubeMX (nascosto)
│ ├── Src/ ← Sorgenti CubeMX (nascosto)
│ └── BADUINO/ ← ★ ZONA UTENTE ★
│ ├── BADUINO.h ← Include principale (NO_HAL, stdio)
│ ├── bhal.h ← B-HAL API (inline, zero overhead)
│ ├── bhal_impl.c ← B-HAL implementazione (pinMode, ecc.)
│ ├── serial_io.c ← printf su USART1 via CMSIS
│ ├── loop.c ← ← Corpo del while(1) — scrivi qui
│ ├── setup.c ← ← Inizializzazione utente
│ ├── lib/
│ │ ├── lib.h ← Dichiarazioni funzioni helper
│ │ └── lib.c ← ← Funzioni helper personali
│ └── irq/
│ ├── TIM3_IRQHandler.c ← Handler TIM3 (CMSIS)
│ └── USART1_IRQHandler.c ← Handler USART1 (CMSIS)
├── Drivers/ ← HAL/CMSIS ST (nascosto)
├── cmake/ ← Toolchain CMake (nascosto)
├── build/ ← Build artifacts (gitignorato)
├── GPIO.ioc ← Configurazione CubeMX
├── BADUINO_setup.py ← Script di trasformazione
├── CMakeLists.txt ← Build system
└── STM32F411XX_FLASH.ld ← Linker script
Grazie a .vscode/settings.json, le cartelle Core/Inc, Core/Src, Drivers, cmake, build sono nascoste nell'esploratore di VS Code. L'utente vede solo:
Core/BADUINO/ ← scrivi qui
GPIO.ioc ← configura qui
Perché BADUINO e non Arduino?
| Arduino | BADUINO | |
|---|---|---|
| Performance | Layer di astrazione pesante | CMSIS puro — registro diretto |
| FLASH usata | ~30KB per bootloader + sketch | ~7KB per progetto completo |
| Config periferiche | Solo quelle supportate dal core | Tutte — via CubeMX (GPIO, TIM, UART, ADC, DMA, USB, ...) |
| Debug | Limitato | SWD completo (Black Pill + ST-Link) |
| Portabilità | Solo board Arduino | Qualsiasi STM32 cambiando .ioc |
| Senza HAL | Impossibile | #define NO_HAL — togli HAL quando vuoi |
| printf | Lento via Serial | Diretto su USART1 via CMSIS, zero librerie intermedie |
Con BADUINO impari il silicio, non una libreria.
NO_HAL — La via CMSIS
Di default, gli handler IRQ chiamano le funzioni HAL (HAL_TIM_IRQHandler, HAL_UART_IRQHandler, ecc.). Quando definisci NO_HAL in BADUINO.h:
// In stm32f4xx_it.c (blocchi USER CODE, preservati da CubeMX):
void TIM3_IRQHandler(void) {
#ifndef NO_HAL
HAL_TIM_IRQHandler(&htim3); // ← SKIPPATO con NO_HAL
#else
#include "irq/TIM3_IRQHandler.c" // ← IL TUO CODICE CMSIS
#endif
}
Scrivi il corpo dell'handler in Core/BADUINO/irq/TIM3_IRQHandler.c:
TIM3->SR = ~TIM_SR_UIF; // Clear flag
digitalToggle(PC(13)); // Toggle LED
Niente chiamate HAL, niente overhead, niente callback. Puro CMSIS.
flusso di esecuzione
Reset
└─ startup_stm32f411xe.s → Reset_Handler
└─ SystemInit() → Clock, FPU, vector table
└─ main()
├─ HAL_Init() ← SysTick 1ms
├─ SystemClock_Config() ← 100MHz
├─ MX_GPIO_Init() ← Pin modes
├─ MX_TIM3_Init() ← TIM3 via HAL
├─ MX_USART1_UART_Init() ← USART1 via HAL
│
├─ setup.c ← DWT init, TIM3 start
│
└─ while(1)
└─ loop.c ← Il tuo codice!
└─ delay() → DWT (CMSIS)
└─ printf() → serial_io.c (CMSIS)
└─ digitalWrite() → bhal.h (inline)
TIM3_IRQHandler → irq/TIM3_IRQHandler.c (se NO_HAL)
USART1_IRQHandler → irq/USART1_IRQHandler.c (se NO_HAL)
Toolchain richiesta
- STM32CubeMX — configurazione periferiche (gratuito, ST.com)
- STM32CubeIDE o toolchain GCC ARM — compilazione
- Inclusa in STM32CubeIDE
- O installabile separatamente:
arm-none-eabi-gcc
- CMake + Ninja — build system
- VS Code — IDE consigliato
- ST-Link — debugger/programmatore
- Black Pill STM32F411CEU6 — board target
Sviluppo futuro
analogWrite()PWM via timer hardwareanalogRead()ADC via polling/IT- Ring buffer per RX seriale non bloccante
- Board package per altri STM32 (F103, F030, G0, ecc.)
- CLI tool
BADUINO new MyProject --board=f411ce
Crediti
- Bebbo's Lab (YouTube) — idea e ispirazione
- Progetto generato con STM32CubeMX 6.17.0 — FW_F4 V1.28.3
- Target: STM32F411CEUx su Black Pill
- Build: CMake + GCC ARM 14.3.1 + Ninja
