TODOPIC
Misceláneas - Interés General => Off Topic => Mensaje iniciado por: elnandu en 27 de Marzo de 2017, 17:10:23
-
Buenos días, estuve informandome en los diferentes manuales sobre estos atributos pero no llegue a entenderlos bien, y si alguien los ha usado ruego por favor que me lo explicaran.
1) unsigned char uart1TxBuferA[8] __attribute__((space(xmemory)));
2) double Px_copy __attribute__((section("midata")));
**********************************************************************
Esto es lo que encontre en la web:
2)
section ("section-name")
By default, the compiler places the objects it generates in sections such as .data and .bss. The section attribute allows you to override this behavior by specifying that a variable (or function) lives in a particular section.
struct a { int i[32]; };
struct a buf __attribute__((section("userdata"))) = {{0}}
***********************************************************************
1) entendí que lo ubica en el espacio de memoria "x" del dspic33ep
Saludos.
-
1- Exactamente como decis, los dsPIC tienen la particularidad de poder acceder a la RAM en 2 puntos al mismo tiempo, esto hace a su capacidad de DSP.
La espacio de memoria X es simplemente un pedazo de RAM, si supongamos usas un array de valores y queres aprovechar lo del DSP , pondria el array en el espacio X y las constantes en el espacio Y (sin irme mas del tema, en el espacio Y se puede observar la FLASH y tratarla casi como RAM solo en lectura)
2- Los compiladores GCC (en el cual esta basado XC16) tienen distintas secciones, entre ellas estan .data y .bss, en .data se ponen las variables inicializadas ( con valor), y en .bss aquellas que no son inicializadas. Desde el punto de vista de hardware en realidad es toda una RAM, pero para el linker los separa diciendo .data ocupa desde 0x0000 a 0x0100 por que hay datos que ocupan ese espacio, y .bss suponete que tenes un array nomas de 0x7F posiciones, entonces la seccion .bss sera de 0x0100 a 0x0180.
Todas tus variables van a estar dentro de esos 2 "grupos" a excepcion que vos decidas crear tu propio grupo o seccion y es los que estarias haciendo con este attribute.
Otra seccion y solo por gusto es .text que es la seccion del programa.
El compilador maneja las secciones a su gusto, ejemplo puede crear una seccion que le llame .vector y saber que debe ubicarlo al comienzo, puede crear algo que se llama .init y es la rutina de inicializacion de C ( la que carga los valores en las variables y algunas cosas mas)
En si esto es mas tirando ya para ASM.
-----------------------
Para mas info acerca de las memorias del dsPIC deberias leerte el capitulo de Data Memory y Program Memory de la familia dsPIC/PIC24
Para mas info acerca de los espacios de memoria, podes buscar por internet, o incluso podes empezar a mirar los archivos extras que crea al compilar/linkear, tal ves necesites tildar una opcion dentro de las propiedades del proyecto, pero tendrias una salida seguro.
-
KILLERJC muchas gracias por tomarte el tiempo de explicarme, ahora lo capto mejor, empezaré a leer el capitulo 3 como mencionas para empaparme del tema.
Saludos
-
Trato de aportar un granito de arena a la descripción de KillerJC.
El compilador maneja nombres de sectores "estandar" .text, .data, .bss donde se guarda el código compilado y los valores de las constantes empleadas en nuestro programa.
El compilador cuando toma un archivo .c genera un archivo objeto .o, y hace (según se le instruya con el archivo make, opciones, línea de comandos...) lo mismo para todos los .c generando para cada uno un .o
Luego entra a jugar el enlazador o linker, porque hasta este punto el compilador genera código/variables que tienen direcciones físicas de memoria no resueltas.
Por ejemplo si en mi archivo .c tengo:
#include <blablabla.h>
extern int unaVariableEnAlgunLugar;
//resto del programa.
El compilador dice "ajá... el programador me dice que en algún otro archivo .c está definida esa variable, por lo tanto no la agrego al conteo de memoria que hago para éste archivo c que estoy compilando ahora, me lo anoto como símbolo sin resolver".
Es decir, le deja la tarea al enlazador agregando una entrada en una tabla de símbolos sin resolver.
El enlazador junta todos los archivos .o que generó el compilador, todavía no tiene direcciones de memoria resueltas ni para las funciones ni para las variables o constantes, excepto que se haya especificado con un atributo especial.
Y además toma el archivo linker o linker script, que puede ser un .cmd o .ld ...o algo así :P
Y que tiene el archivo de linker script?:
1) las direcciones físicas (en hexadecimal 0xNNNNNN) de los vectores de interrupción (reset, periféricos: puertos, conversor AD, etc), también puede estar definido en los .h y no en linker script
2) los registros del micro (puertos, dirección de puertos, registros del uart/i2c/spi... de todos los registros de propósito especial SFR aunque a veces pueden estar en los .h y no en el linker script),
3) los segmentos de memoria (a partir de que dirección comienza la RAM y que longitud tiene, es decir, que rango de memoria; ídem para memoria flash, eeprom si la hubiera),
Nota: segmento de memoria != sector de memoria, el sector memoria .data va en el segmento de memoria RAM por ejemplo
4) la pila que es lo que usa C para llamar y retornar de las funciones, pasar parámetros
5) el heap si algún valiente se mete con memoria dinámica (malloc)
Y alguna cosa más que o bien no conozco, o se me pasó por alto (sector de inicialización como dijo KillerJC).
Eso es lo que hace el enlazador, resuelve todas las referencias a memoria que es nada más y nada menos decir que la variable "miVariable" tiene la dirección 0x1ab por ejemplo.
Se hace notar cuando tira un error "unresolved reference to...." que significa que no encontró una variable o función que yo le dije que iba a estar en otro archivo usando extern (o a través de un include).
En el linker script si uno quisiera se podría agregar un sector de memoria definido a mano para un propósito especial, por ejemplo una zona de datos de calibración que no quiero que cambie al actualizar el programa del micro, o un sector de memoria para un bootloader (de hecho si un micro usa un bootloader seguro su linker script para nuestro programa excluirá el sector de memoria que usa el bootloader, o por lo menos debería).
Bueno, eso es todo, no quería dejar en la oscuridad al enlazador/linker.
-
Y alguna cosa más que o bien no conozco, o se me pasó por alto (sector de inicialización como dijo KillerJC).
http://www.todopic.com.ar/foros/index.php?topic=45240.msg376311#msg376311
Escribi por el foro acerca de eso, mas abajo en una de las respuestas hablo de mas sectores, a pesar que hay muchas cosas mezcladas por que el post era sobre ASM usando el compilador XC16.
En resumen, C posee un "codigo de inicializacion", lo que hace este codigo es inicializar las variables, en algunos casos como ARM procede a configurar el micro en otro modo (algunos setean incluso los osciladores en un valor prefijado), casi siempre para esa seccion de codigo se utiliza el seccion .cinit, y para los datos que deberian contiener esas variables inicializadas y que deben estar en la FLASH, suele ser .dinit, obviamente esto puede cambiar de fabricante en fabricante. Secciones de variables constantes como .const . En si muchas mas, por eso mismo lo deje abierto " a criterio del fabricante "
En resumen con esto, casi no se aplicaria a no ser casos MUY puntuales como lo del dsPIC, que deberias ubicar las variables en algun lado concreto. Aun asi para el uso de las instrucciones de DSP tenes que recurrir a usar ASM. Por lo que vi en los ejemplos de Microchip.
Y si le intereza a elnandu, aca hay ejemplos "practicos" de como funciona el linker (en un PIC18):
http://www.todopic.com.ar/foros/index.php?topic=45254.msg376641#msg376641
Nuevamente todo en ASM.