La cuestión
En un contexto incrustado bare-metal de bajo nivel , me gustaría crear un espacio en blanco en la memoria, dentro de una estructura C ++ y sin ningún nombre, para prohibir al usuario acceder a dicha ubicación de memoria.
En este momento, lo he logrado poniendo un uint32_t :96;
campo de bits feo que ocupará convenientemente el lugar de tres palabras, pero generará una advertencia de GCC (campo de bits demasiado grande para caber en uint32_t), lo cual es bastante legítimo.
Si bien funciona bien, no es muy limpio cuando desea distribuir una biblioteca con varios cientos de esas advertencias ...
¿Cómo lo hago correctamente?
¿Por qué hay un problema en primer lugar?
El proyecto en el que estoy trabajando consiste en definir la estructura de memoria de diferentes periféricos de toda una línea de microcontroladores (STMicroelectronics STM32). Para hacerlo, el resultado es una clase que contiene una unión de varias estructuras que definen todos los registros, dependiendo del microcontrolador objetivo.
Un ejemplo simple de un periférico bastante simple es el siguiente: una entrada / salida de uso general (GPIO)
union
{
struct
{
GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
};
struct
{
GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
};
struct
{
uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
};
};
Donde todo GPIO_MAPx_YYY
es una macro, definida como uint32_t :32
o el tipo de registro (una estructura dedicada).
Aquí ves el uint32_t :192;
que funciona bien, pero activa una advertencia.
Lo que he considerado hasta ahora:
Podría haberlo reemplazado por varios uint32_t :32;
(6 aquí), pero tengo algunos casos extremos en los que tengo uint32_t :1344;
(42) (entre otros). Por lo tanto, preferiría no agregar unas cien líneas sobre otras 8k, aunque la generación de la estructura esté programada.
El mensaje de advertencia exacto es algo como:
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(Me encanta lo sombrío que es).
Preferiría no resolver esto simplemente eliminando la advertencia, sino usando
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
puede ser una solución ... si la encuentro TheRightFlag
. Sin embargo, como se señala en este hilo , gcc/cp/class.c
con esta triste parte del código:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
Lo que nos dice que no hay una -Wxxx
bandera para eliminar esta advertencia ...
uint32_t :192;
.
:42*32
lugar de:1344
char unused[12];
y demás?