Sto lavorando a un progetto incorporato (destinazione PowerPC, compilatore Freewale Metrowerks Codewarrior) in cui i registri sono mappati in memoria e definiti in bitfield di qualità per rendere facile il twittling dei singoli bit.Cosa fa il compilatore C con i bitfield?
Al momento, stiamo utilizzando questa funzione per cancellare i flag di interrupt e controllare il trasferimento dei dati. Sebbene non abbia ancora notato alcun bug, ero curioso di sapere se questo è sicuro. C'è un modo per utilizzare in modo sicuro i campi di bit, o ho bisogno di avvolgere ciascuno in DISABLE_INTERRUPTS ... ENABLE_INTERRUPTS?
Per chiarire: l'intestazione fornito con il micro ha campi come
union {
vuint16_t R;
struct {
vuint16_t MTM:1; /* message buffer transmission mode */
vuint16_t CHNLA:1; /* channel assignement */
vuint16_t CHNLB:1; /* channel assignement */
vuint16_t CCFE:1; /* cycle counter filter enable */
vuint16_t CCFMSK:6; /* cycle counter filter mask */
vuint16_t CCFVAL:6; /* cycle counter filter value */
} B;
} MBCCFR;
presumo impostando un bit in un campo di bit non è atomica. Questa è una supposizione corretta? Che tipo di codice genera realmente il compilatore per i bitfield? Eseguire personalmente la maschera utilizzando il campo R (raw) potrebbe rendere più facile ricordare che l'operazione non è atomica (è facile dimenticare che un compito come CAN_A.IMASK1.B.BUF00M = 1
non è atomico).
Il tuo consiglio è apprezzato.
Sono corretto nel pensare che il 'v' in' vuint16_t' sta per "volatile"? – JAB
Sì, i tipi sono volatili poiché sono tutti percorsi di registrazione mappati in memoria. Ci sono anche le istruzioni di allineamento che ho tralasciato per mantenere le cose corte. –
Evita i bitfield e usa invece maschera e shift. – starblue