Processing math: 100%

4 votos

Problema en la escritura de registro de los mapas de uso de C estructura de un Microcontrolador TI

Estoy escribiendo registrar mapas en C para TI BRAZO de la Micro-controlador de la junta. Aquí está el enlace a la hoja de datos.

Estoy utilizando las siguientes pautas sobre cómo Registrar los mapas deben ser escritos en C: Registrar Mapas. Estas pautas son similares a las Armas CMSIS (Corteza Microcontrolador de la Interfaz de Software Estándar) para escribir código C.

Yo soy el problema que enfrentan con el Sistema de escritura de Registro de Control de mapas(consulte la sección 5.5 de la página 237 adelante en la hoja de datos) usando C struct. Todos los registros son de tamaño de 32 bits

  • La dirección base es 0x400F.E000.
  • Registro de 1: Identificación de Dispositivo 0(DID0), desplazamiento 0x000
  • Registro de 2: Identificación de Dispositivo 1 (DID1), desplazamiento 0x004
  • Registro de 3: Brown-Out Reset Control (PBORCTL), desplazamiento 0x030
  • Registro de 4: Raw de Estado de Interrupción (RIS), desplazamiento 0x050
  • etc..

Si me escribe ahora una estructura como esta:

typedef struct
{
   uint32_t DID0;      // offset 0x000. distance: 0
   uint32_t DID1;      // offset 0x004. distance: 4
   uint32_t PBORCTL;   // **HOW to place this at offset 0x030 ?**
   uint32_t RIS;       // **HOW  to place this at offset 0x050 ?**
   // ...and so on
 }PER_REG_MAP_T;

#define PERIPH_BASE ((uint32_t)0x400FE000)
#define MY_PERIPH_A ((PER_REG_MAP_T*)PERIPH_BASE)

void Reset(PER_REG_MAP_T* PERIPH_A)
{
  PERIPH_A->DID0 = 0;
  PERIPH_A->DID1= 0;
  PERIPH_A->PBORCTL= 1;
  PERIPH_A->RIS= 0;
  // .. and so on
}

El principal problema al que me estoy enfrentando es cómo colocar PBORCTL y RIS dentro de la estructura como son en el desplazamiento 0x030 y 0x050 con respecto a la dirección de la base de la estructura. No he hecho demasiado poco-nivel C-programación de antes, así que esta pregunta podría ser demasiado simple, pero yo nose sabe cómo hacerlo.

2voto

Neil Foley Puntos 1313

Las estructuras no son adecuados para la escritura de registro de los mapas, ya que una estructura puede tener bytes de relleno añadido en cualquier lugar dentro de ella, con fines de alineación. Esto depende del compilador - usted tiene que asegurarse de que no se usa relleno (por ejemplo a través de una estática valer).

Además, es fácil cometer errores al escribir grandes estructuras que supuestamente reflejan un mapa de registros, usted tiene que conseguir cada byte a la derecha o te voy a romper todo. Esto hace que la estructura vulnerables durante el mantenimiento.

Me gustaría sugerir fuertemente que usted escriba el registro de los mapas a través de macros, tales como:

#define PERIPH_A_DID0 (*(volatile uint32_t*)0x400FE000u))
#define PERIPH_A_DID1 (*(volatile uint32_t*)0x400FE004u))

Esto también tiene la ventaja de ser 100% portable a cualquier compilador de C.

Alternativamente, usted podría hacer algo más complejo como este:

typedef volatile uint8_t* SCI_port;
#ifndef SCI0
  #define SCI0 (&SCI0BDH)
  #define SCI1 (&SCI1BDH)
#endif

#define SCIBDH(x)   (*((SCI_port)x + 0x00))   /* SCI Baud Rate Register High             */
#define SCIBDL(x)   (*((SCI_port)x + 0x01))   /* SCI Baud Rate Register Low              */
#define SCICR1(x)   (*((SCI_port)x + 0x02))   /* SCI Control Register1                   */
#define SCICR2(x)   (*((SCI_port)x + 0x03))   /* SCI Control Register 2                  */
#define SCISR1(x)   (*((SCI_port)x + 0x04))   /* SCI Status Register 1                   */
#define SCISR2(x)   (*((SCI_port)x + 0x05))   /* SCI Status Register 2                   */
#define SCIDRH(x)   (*((SCI_port)x + 0x06))   /* SCI Data Register High                  */
#define SCIDRL(x)   (*((SCI_port)x + 0x07))   /* SCI Data Register Low                   */

Luego, cuando la escritura de su conductor, usted puede hacer así:

void sci_init (SCI_port port, ...)
{
  SCICR1(port) = THIS | THAT;
  SCICR2(port) = SOMETHING_ELSE;
  ...
}

Esto es muy útil cuando se tienen muchos periféricos idénticos en el MCU, con los mismos registros, pero sólo se desea un código de control.

2voto

Respawned Fluff Puntos 9403

En primer lugar, el BRAZO recomienda el uso de __packed para obtener el mínimo de embalaje. En segundo lugar, si usted realmente necesita de grandes lagunas en su estructura (y estos no pueden ser de dos estructuras por alguna razón) que sólo puede poner algo como un char[30] reserved1 de la matriz en el medio y así sucesivamente para los otros grandes lagunas. Asegúrese de poner el tamaño adecuado para estos. Usted puede verificar con una afirman que el siguiente campo del desplazamiento es realmente donde usted piensa; offsetof() le dará el desplazamiento de un campo.

Esto lo escribí un poco de prisa, si usted necesita más detalles, pregunte por debajo y voy a ampliar (aunque no para un número de horas).

Por cierto, se parece a TI ya ha escrito el archivo de encabezado en cuestión. Parecen como el uso de #define para todo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X