Estoy programando C en un sistema integrado. La arquitectura del procesador es 32 bits (sizeof(int)
es 32 bits, sizeof(short)
es 16 bits). Hay una variable de 32 bits que es un registro de control mapeado en la memoria (CTRL_REG
) que se especifica solo como los 16 bits inferiores que se usan, y contienen un valor entero de 16 bits con signo (escribir en los bits más altos no tiene ningún efecto). Los accesos a la memoria deben estar alineados a 32 bits, por lo que no puedo simplemente colocar el puntero sobre un par de bytes, y tampoco puedo suponer una endiancia. Me preocupa que la promoción automática de tipos vaya a interferir con lo que estoy almacenando al extender el bit de signo al bit 31 en lugar de dejarlo en el bit 15 donde lo desee. ¿Cuál es la mejor manera de almacenar algo en esta ubicación?almacenamiento corto firmado en los 16 bits inferiores de un unsigned int
Aquí fue mi código original, que estoy casi seguro que está mal:
#define CTRL_REG *((volatile unsigned int *)0x4000D008u)
short calibrationValue;
CTRL_REG = -2 * calibrationValue;
Luego he intentado esto, pero creo que aún podría estar sujeto a un entero promoción en el punto de la misión:
CTRL_REG = (short)(-2 * calibrationValue);
Entonces, finalmente pensé en esto:
CTRL_REG = (unsigned short)(short)(-2 * calibrationValue);
no puede evaluar estas opciones muy bien porque todos funcionan en mis pruebas porque calibrationValue
resulta ser negativo (es un parámetro de calibración específico para cada dispositivo, por lo que podría ser positivo en algunos dispositivos), así que después de multiplicar por -2, termino almacenando un valor positivo y por lo tanto, en realidad no me encuentro con el problema que estoy esperando en mis pruebas.
Su ayuda es muy apreciada, incluso si es solo para decir "usted está pensando demasiado".
Si quiere estar seguro de que su variable es de 32 bits, puede usar 'uint32_t' en su lugar, desde stdint.h. Tenga en cuenta que un 'int' [no tiene que ser de 32 bits] (http://codinghorror.typepad.com/.a/6a0120a85dcdae970b0128776ff992970c-pi), ni siquiera en sistemas de 32 bits. –
@WTP: gracias por su preocupación. tenemos un encabezado específico del compilador que contiene definiciones de tipo que garantizan el tamaño. No son la uint32_t estándar ni la nomenclatura, así que en lugar de confundir mi publicación con tipos no estándar, opté por convertir todo en tipos que todos hayan visto antes. – rmeador
Sugeriría al menos un par adicional de paréntesis alrededor de la macro: "(* ((volatile unsigned int *) 0x4000d008u))" – wildplasser