Architettura del Dominio di Backup
Il dominio di backup comprende:
- RTC — calendario (ore/minuti/secondi + data/giorno/mese/anno) alimentato da LSE (32.768 kHz) o LSI (~32 kHz)
- 20 registri di backup da 32 bit (
BKPxRsu F4,RTC_BKPxRsulle serie recenti) — mantengono i dati durante la sola alimentazione VBAT - Rilevamento tamper — fino a 3 pin tamper con sensibilità di fronte/livello configurabile, cattura timestamp opzionale
- Wake-up timer — un contatore alla rovescia indipendente che può risvegliare il sistema da STOP 0/1/2 e STANDBY
- Allarmi RTC — due allarmi configurabili (A e B) che attivano l'uscita
RTC_ALARM
Il commutatore di alimentazione tra VDD e VBAT è interno: quando VDD scende sotto la soglia VBAT, il dominio di backup passa trasparentemente a VBAT. Su STM32L4/U5, il dominio di backup include anche LPTIM e i GPIO PC13–PC15 configurati come uscite RTC.
Accesso e Protezione da Scrittura
I registri del dominio di backup risiedono sul bus APB1 ma sono protetti in scrittura per impostazione predefinita. Scrivere nei registri RTC, registri di backup o registri di controllo RTC richiede lo sblocco del Power Control e del Backup Domain:
// Step 1: Abilita l'interfaccia PWR e il clock RTC
RCC->APB1ENR |= RCC_APB1ENR_PWREN; // abilita interfaccia PWR
PWR->CR1 |= PWR_CR1_DBP; // abilita accesso scrittura backup domain
while (!(PWR->CR1 & PWR_CR1_DBP));
// Step 2: Abilita clock RTC, seleziona LSE come sorgente
RCC->BDCR |= RCC_BDCR_RTCEN; // abilita clock RTC
RCC->BDCR |= RCC_BDCR_RTCSEL; // seleziona LSE come sorgente
L'ordine conta. Scrivere nei registri RTC prima di impostare DBP viene silenziosamente ignorato — nessun errore, nessun effetto. È una delle trappole di debug RTC più comuni.
Inizializzazione del Calendario RTC
Su STM32F4 e successivi, il periferico RTC usa un set di registri unificato. Il calendario viene configurato attraverso la modalità di inizializzazione, uno stato protetto che può essere inserito solo quando l'RTC non è inizializzato o dopo un reset di sistema.
// Entra in modalità init
RTC->ISR |= RTC_ISR_INIT;
while (!(RTC->ISR & RTC_ISR_INITF));
// Configura prescaler (LSE = 32768 Hz)
RTC->PRER = (0x7F << 16) // prescaler async = 128 → 256 Hz
| (0xFF << 0); // prescaler sync = 256 → 1 Hz
// Imposta ora iniziale: 14:30:00
RTC->TR = (0 << RTC_TR_PM_Pos)
| (0x14 << RTC_TR_HT_Pos)
| (4 << RTC_TR_HU_Pos)
| (3 << RTC_TR_MNT_Pos)
| (0 << RTC_TR_MNU_Pos)
| (0 << RTC_TR_ST_Pos)
| (0 << RTC_TR_SU_Pos);
// Imposta data iniziale: 2026-06-20
RTC->DR = (0 << RTC_DR_YT_Pos)
| (6 << RTC_DR_YU_Pos)
| (0 << RTC_DR_WDU_Pos)
| (6 << RTC_DR_MU_Pos) // giugno
| (2 << RTC_DR_DT_Pos)
| (0 << RTC_DR_DU_Pos); // 20
RTC->CR &= ~RTC_CR_FMT; // formato 24 ore
// Esci da modalità init
RTC->ISR &= ~RTC_ISR_INIT;
// Attendi sincronizzazione registri (~2 cicli RTCCLK)
RTC->ISR &= ~RTC_ISR_RSF;
while (!(RTC->ISR & RTC_ISR_RSF));
I registri shadow (RTC_TR, RTC_DR) vengono aggiornati asincronamente dal contatore RTC. Leggerli immediatamente dopo la scrittura può restituire dati obsoleti. Il flag RSF garantisce che i registri shadow siano sincronizzati.
Registri di Backup: Persistenza dello Stato tra i Reset
I 20 registri di backup (RTC_BKP0R...RTC_BKP19R su L4/G4/U5, o BKPxR su F4 con un periferico BKP separato) sopravvivono al reset di sistema, al wake-up da STANDBY e all'alimentazione solo VBAT. Sono il modo più semplice per rilevare se il software si è avviato per la prima volta dopo una perdita completa di alimentazione:
// All'avvio, controlla un valore magico nel registro di backup 0
if (RTC->BKP0R != 0xDEADBEEF) {
// Primo avvio dopo perdita completa di alimentazione
init_rtc_calendar();
RTC->BKP0R = 0xDEADBEEF; // segna come inizializzato
RTC->BKP1R = conteggio_avvii; // traccia eventi di accensione
} else {
// RTC funziona da VBAT — non serve reinizializzare
leggi_contatore_backup();
}
// Salva un evento con timestamp prima dello spegnimento
RTC->BKP2R = codice_evento;
RTC->BKP3R = RTC->TR;
RTC->BKP4R = RTC->DR;
I registri di backup sono anche il modo più semplice per comunicare tra la CPU principale e un firmware updater in esecuzione dalla memoria di sistema, poiché sopravvivono a un reset software.
Rilevamento Tamper con Timestamp
Il periferico tamper RTC monitora fino a 3 pin esterni (TAMP1–TAMP3). Quando rileva un evento tamper (fronte di salita, fronte di discesa o livello basso), può:
- Cancellare i registri di backup (funzione anti-forense)
- Catturare il timestamp esatto in
RTC_TSTR/RTC_TSDR - Generare un interrupt
- Attivare l'uscita RTC_ALARM su PC13
// Configura TAMP1 su PC13
RTC->TAMPCR |= RTC_TAMPCR_TAMP1E; // abilita tamper 1
RTC->TAMPCR |= RTC_TAMPCR_TAMP1TRG; // fronte di discesa
RTC->TAMPCR |= RTC_TAMPCR_TAMPIE; // abilita interrupt
RTC->TAMPCR |= RTC_TAMPCR_TSIE; // abilita interrupt timestamp
RTC->TAMPCR |= RTC_TAMPCR_TAMPFLT_0; // 2 campioni consecutivi
RTC->CR |= RTC_CR_TSE; // abilita timestamp
RTC->CR |= RTC_CR_TSIE; // interrupt timestamp
void RTC_IRQHandler(void) {
if (RTC->ISR & RTC_ISR_TAMP1F) {
uint32_t ora_tamper = RTC->TSTR;
uint32_t data_tamper = RTC->TSDR;
RTC->ISR &= ~RTC_ISR_TAMP1F;
}
if (RTC->ISR & RTC_ISR_TSF) {
RTC->ISR &= ~RTC_ISR_TSF;
}
}
Su STM32L4+/U5, il tamper è migliorato con contatore monotono e tamper attivo — l'RTC guida attivamente un pattern sul pin tamper e verifica la risposta attesa, rilevando cortocircuiti e tagli delle tracce. Disponibile su U575 e L4P5/L4Q5.
Wake-up da STOP/STANDBY con l'RTC
Il wake-up timer RTC è un contatore alla rovescia a 16 bit che conta i cicli di clock RTC (o i suoi derivati prescalati) e genera un evento di wake-up quando raggiunge zero. È il metodo standard per ottenere wake-up periodici in prodotti a batteria.
// Configura wake-up timer per intervallo di 10 secondi
// WUCKSEL = 3 → CK_SPRE (1 Hz)
// Tempo di wake-up = (WUT + 1) * 1 secondo
RTC->ISR |= RTC_ISR_INIT;
while (!(RTC->ISR & RTC_ISR_INITF));
RTC->WUTR = 9999;
RTC->CR = (RTC->CR & ~RTC_CR_WUCKSEL_Msk)
| (3 << RTC_CR_WUCKSEL_Pos)
| RTC_CR_WUTE;
RTC->CR |= RTC_CR_WUTIE;
RTC->ISR &= ~RTC_ISR_INIT;
// Entra in STOP mode
PWR->CR1 |= PWR_CR1_LPDS;
PWR->CR1 |= PWR_CR1_PDDS;
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
Il wake-up timer funziona da LSE o LSI indipendentemente dallo stato del clock di sistema. Funziona anche quando HSI/HSE/PLL è fermo durante STOP. Per STANDBY, il wake-up timer è l'unica opzione basata su RTC (gli allarmi non sono disponibili in STANDBY su F4).
Esempio Pratico: Ciclo di Risveglio ogni 15 Minuti per Nodo IoT
Un pattern comune per nodi IoT a batteria: dormi 15 minuti, leggi sensore, trasmetti dati, dormi di nuovo. Il dominio di backup RTC è l'abilitatore chiave.
#define INTERVALLO_WAKEUP_S 900 // 15 minuti
void entra_ciclo_basso_consumo(void) {
RTC->BKP2R = ultimo_valore_sensore;
RTC->BKP3R = RTC->TR;
RTC->ISR |= RTC_ISR_INIT;
while (!(RTC->ISR & RTC_ISR_INITF));
RTC->WUTR = INTERVALLO_WAKEUP_S - 1;
RTC->CR = (RTC->CR & ~RTC_CR_WUCKSEL_Msk)
| (3 << RTC_CR_WUCKSEL_Pos)
| RTC_CR_WUTE
| RTC_CR_WUTIE;
RTC->ISR &= ~RTC_ISR_INIT;
RTC->TAMPCR |= RTC_TAMPCR_TAMP1E
| RTC_TAMPCR_TAMP1TRG
| RTC_TAMPCR_TAMPIE;
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
}
void RTC_WKUP_IRQHandler(void) {
if (RTC->ISR & RTC_ISR_WUTF) {
RTC->ISR &= ~RTC_ISR_WUTF;
EXTI->PR1 |= EXTI_PR1_PR20;
}
}
Checklist Pratica
| Check | Perché |
|---|---|
| Bit DBP impostato prima di scrivere registri di backup? | Tutte le scritture vengono ignorate senza accesso al dominio di backup |
| LSE stabile prima di selezionare clock RTC? | L'RTC potrebbe funzionare alla frequenza sbagliata |
| Flag RSF controllato prima di leggere il calendario? | I registri shadow potrebbero contenere dati obsoleti |
| Valore magico nel registro di backup all'avvio? | Previene la reinizializzazione dell'RTC a ogni reset |
| Pull sul pin tamper configurato? | Un pin tamper flottante causa falsi eventi |
| WUCKSEL corrisponde all'intervallo desiderato? | Prescaler sbagliato = secondi o minuti fuori di un fattore 256 |
| Linea EXTI wake-up abilitata in SYSCFG? | L'interrupt RTC wake-up deve passare attraverso EXTI per svegliarsi da STOP |
| Wake-up STANDBY vs STOP? | Gli allarmi non svegliano da STANDBY su F4; solo WUT lo fa |
| Pin VBAT connesso a batteria o supercap? | Senza VBAT, il dominio di backup perde stato quando VDD viene rimosso |
Come lo Affronterei su un Progetto Cliente
Su un recente prodotto STM32L4 per sensori ambientali, dovevamo mantenere l'ora UTC accurata per mesi di funzionamento a batteria con la CPU in STOP 2 per il 99.8% del tempo. Il dominio di backup RTC era la spina dorsale:
- I registri di backup contenevano un contatore di avvii monotono, l'ultimo offset di calibrazione e un seed nonce AES-GCM — tutti sopravvissuti ai reset di sistema.
- Il wake-up timer ciclava il sistema ogni 15 minuti per lettura sensore + trasmissione LoRa, usando l'uscita LSE calibrata a 1 Hz come WUCKSEL.
- Il tamper su TAMP1 (connesso a un interruttore reed sull'involucro) cancellava i registri di backup all'apertura del contenitore — soddisfacendo il requisito anti-manomissione per un'applicazione di meter reading.
Il problema che ci costa un giorno: il wake-up timer occasionalmente si attivava 1–2 secondi prima. Causa: l'uscita CK_SPRE deriva dalla cascata di prescaler asincroni, e l'ingresso in RTC_ISR_INIT fermava brevemente i divisori di clock, resettando la fase del prescaler. La soluzione: configurare il wake-up timer senza entrare in init mode quando si cambia solo WUTR — WUTR può essere scritto con WUTE = 1 usando RTC_ISR_WUTWF.
Su STM32U5, il dominio di backup guadagna tre importanti miglioramenti: tamper attivo (basato su pattern), contatore monotono (rilevamento rollback) e alimentazione VBAT dedicata per la ritenzione SRAM2. Se il cliente richiede certificazione di sicurezza, le funzionalità del dominio di backup U5 valgono il premium rispetto a L4.
Fonti consultate:
- STM32F4 Reference Manual (RM0090) — Chapter 14: RTC, Chapter 5: Reset and clock control (RCC)
- STM32L4 Reference Manual (RM0351) — Chapter 14: RTC, Chapter 6.4: Backup domain
- STM32G4 Reference Manual (RM0440) — Chapter 16: RTC
- STM32U5 Reference Manual (RM0456) — Chapter 19: RTC
- ST Application Note AN4759 — RTC tamper and timestamp configuration
- ST Application Note AN3371 — Using the STM32 real-time clock
- CMSIS-Core 5.6.0 —
stm32l4xx.hregister definitions - STMicroelectronics — LSE crystal tuning and RTC calibration (AN2867)

💬 Commenti
Hai domande o esperienze con il dominio di backup RTC STM32? Scrivimi un'email. Includi lo slug dell'articolo nell'oggetto.