Los datos que usted describe (24-bit uso de memoria de programa para almacenar datos) no puede ser definido y se inicializa en C, y no se puede leer directamente a través de la C; la única manera de acceder a ella es mediante la encapsulación en un C-rescatable de la asamblea o de la función de un valor intrínseco.
En realidad, hay dos preguntas aquí:
cómo jugar muy bien con el compilador, ensamblador y enlazador, de modo que al definir el 24 bits de datos en un archivo de ensamblaje como reubicable de datos con un nombre simbólico D1
, en lugar de sin nombre datos en una dirección fija, el compilador puede ver esta variable para determinar su dirección
cómo acceder a los datos
La 2ª pregunta (¿cómo acceder a los datos) es respondida por 33EP partes en DS70613C y debe ser respondida por 33FJ partes en DS70204C (pero los ejemplos en la 33FJ manual sólo el uso de los 16 bits más bajos). He aquí un ejemplo de fragmento de código de la 33EP manual de referencia que funciona para 33EP partes + debe de 33FJ (no tengo un 33FJ dispositivo fácilmente disponibles):
(nota: el código utiliza int
, mientras que sería mejor utilizar a uint16_t
y #include <stdint.h>
)
int prog_data[10] __attribute__((space(prog))) =
{0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999};
unsigned int lowWord[10], highWord[10];
unsigned int tableOffset, loopCount;
int main(void){
TBLPAG = __builtin_tblpage (prog_data);
tableOffset = __builtin_tbloffset (prog_data);
/* Read all 10 constants into the lowWord and highWord arrays */
for (loopCount = 0; loopCount < 10; loopCount ++)
{
lowWord[loopCount] = __builtin_tblrdl (tableOffset);
highWord[loopCount] = __builtin_tblrdh (tableOffset);
tableOffset +=2;
}
while(1)
;
}
Tenga en cuenta que las funciones integradas __builtin_tblrdl()
y __builtin_tblrdh()
se utiliza para leer el alta y baja de palabras de 16 bits de datos desde un programa de la localización de memoria, y __builtin_tblpage() and __builtin_tbloffset()
puede ser utilizado para extraer la página y el desplazamiento de la dirección. En este ejemplo en particular, el highWord matriz siempre es 0, y el lowWord matriz coincide con el prog_data define e inicializa en C.
Por favor no punteros se utilizan aquí! Aunque es posible el uso normal de las variables que están marcados con la etiqueta const
, de modo que se encuentran por el enlazador en el programa de sólo lectura del espacio, y por lo que se puede leer la memoria usando el estándar de C puntero técnicas, con el compilador automáticamente la gestión de la paginación de registros para usted, usted sólo puede almacenar datos de 16 bits. Usted necesita para acceder a la TBLRDL y TBLRDH funciones integradas para obtener todos los 24 bits de datos.
En cuanto a la manera de jugar muy bien con el compilador/enlazador/etc, tienes que engañar al compilador y decirle que es sólo de ver de datos de 16 bits. Aquí un ejemplo en el que trabajó para llegar a la variable D1 declarado en otro lugar:
#define D1_SIZE 18
extern uint16_t __attribute__((space(prog))) D1[D1_SIZE];
#define READ_DATA(dst, v, len) readData(dst, __builtin_tblpage(v), __builtin_tbloffset(v), len)
void readData(uint32_t *pdst, uint16_t page, uint16_t offset, uint16_t len)
{
TBLPAG = page;
while (len-- > 0)
{
uint16_t lo = __builtin_tblrdl (offset);
uint16_t hi = __builtin_tblrdh (offset);
*pdst++ = (((uint32_t)(hi)) << 16) | ((uint32_t)(lo));
offset += 2;
}
}
...
uint32_t d1copy[D1_SIZE];
READ_DATA(d1copy, D1, D1_SIZE);
Esto hace la lectura correcta de 24-bit de valores y los almacena en la parte inferior de 24 bits de un uint32_t. Los extern D1 variable declarada en C es una variable ficticia que es sólo utilizado para llegar a la dirección de inicio al tomar ventaja de la forma en que el compilador/montador/enlazador de trabajar juntos. Las funciones integradas manejar el resto de la obra.
Lo que no sé es cómo obtener automáticamente el tamaño de los datos, ya que se define + inicializado en la asamblea.