El compilador XC8 con el @ "enmascara" utilizar (*((volatile unsigned long *) 0xE0028000)) ?
Lo otro que no se es sobre GCC...¿Es un compilador?
Mi ultima consulta es acerca del linker. Tengo entendido que el linker "une" los bloques que el compilador crea cuando se utilizan funciones para que después se generen el archivo .hex.
El compilador XC8 si no utiliza un linker, ¿Como une esos bloques ? (o estoy complemente errado y el linker no funciona así?).
// Fuses
Fuses(); // Aqui debiera ir la direccion de los fuses
// Direcciones de los registros a usar
#define ADCON1 (*((volatile unsigned int *) 0x9f)) // direccion de memoria ADCON1 pic16f716
#define TRISA (*((volatile unsigned int *) 0x85)) // direccion de memoria TRISA pic16f716
#define PORTA (*((volatile unsigned int *) 0x05)) // direccion de memoria PORTA pic16f716
void main(){
int* PUERTO = PORTA;
int* DIRECCION = TRISA;
int* ADC_CONFIG = ADCON1;
// AHORA SETEO REGISTROS
*PUERTO = 0X00; // Limpio puerto
*DIRECCION = 0X00; // Todos pines como salida
*ADC_CONFIG = 0XFF; //Todos digitales
//ENCIENDO UN LED
while(1){
*PUERTO |= 0x01; //Enciendo PIN0 puerto A
}
}
- preprocesador: llamo a mi archivo LED.c y utilizando -E + nombre del archivo (que sera LED) obtengo el archivo LED.cpp (esto no es de mucha utilidad, según yo xD)
- compilador: con el LED.c y utilizando -S + nombre de archivo (que sera LED) obtengo un archivo en ensamblador que con nombre LED.s
- ensamblador: llamo a mi archivo LED.s creado y utilizando -o + nombre del archvio a obtener (que tambien ser llamara led) creara mi archivo objeto llamado LED.o. (según la web se puede saltar todo eso, usando LED.c -o y me genera el LED.o...¿que beneficio tiene saltar la creación del .s?)
Ahora viene el trabajo del LINKER!!
gcc -c -o hola.o hola.c El link 2 y 3 que me enviaste entendí que debo "configurar" las direcciones de memoria donde el linker pondrá el código objeto, que en mi caso sera el LED.o. Según eso debiera dar los rangos de memoria de FLASH, que son:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20001000; /* end of RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 16K
}
/* Sections */
SECTIONS
{
/* The startup code into ROM memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >ROM
/* The program code and other data into ROM memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >ROM
/* Constant data into ROM memory*/
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >ROM
.ARM.extab : {
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >ROM
.ARM : {
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >ROM
.preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >ROM
.init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >ROM
.fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >ROM
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into RAM memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> ROM
/* Uninitialized data section into RAM memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }Entonces por lo que entiendo, el linker como sabe los rangos de memoria tomara las direcciones de los registros y las "unirá" al respectivo banko (esto para la RAM) y para la memoria de programa tomara lo que esta dentro del main y lo "unirá" desde el 0x0000 de la memoria en adelante y así al final se tendrá el .hex (esta correcto esto???).El linker esta consciente del tamaño de las seccion y del microcontrolador, por lo cual intenta ubicarlas por el mismo en donde sea.
Con el linker creado debiera enlazarlo con mi código objeto, pero el comando que debo utilizar no se bien como utilizarlo aun (la web habla de enlazado dinámico y estático).En los microcontroladores no usamos enlazado dinamico creo que nunca, al menos nunca lo realice.
KILLERJC me gustaría que pudieras ayudarme con lo que he escrito, verificando los pasos que he puesto si están bien o mal o le falta, etc.
PD: en el código de ejemplo los FUSES no se como se direccionan, ya que su dirección esta en la memoria de programa. Tengo entendido que los punteros "apuntan" a la RAM y no se si se puede hacer algo asi:
#define CONFIG (*((volatile unsigned long *) 0x2000))
Disculpa si es muy largo el texto pero quise ser lo mas explicito y claro posible. Me sera de mucha utilidad que me pudieras corregir y ayudar a construir un .hex
Asi que el programa va a salir con instrucciones ASM para un microprocesador Pentium por ejemplo y no un PIC, como las computadoras tienen el OS, apenas intentes ejecutar ese programa en tu PC vas a tener un error de memoria.
Este archivo ya te lo provee Microchip ( .lkr ), pero para SU propio linker.
Otra cosa distinta es que Microchip en ASM utiliza 2 ejecutables distintos. El primero es el compilador, y el segundo un linker. Mientras que para XC8 utiliza todo el mismo, igual que para GCCAl parecer es cierto (no es que dude de ti KILLERJC, solo comprobar xD), ya que no encontré un linker para los 16f, entonces XC8 de "alguna" forma compila y enlaza sin un linker.
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/JUANJO/MPLABXProjects/PWM_16f716.X'
make -f nbproject/Makefile-default.mk dist/default/production/PWM_16f716.X.production.hex
make[2]: Entering directory 'C:/Users/JUANJO/MPLABXProjects/PWM_16f716.X'
"C:\Program Files\Microchip\xc8\v1.43\bin\xc8.exe" --pass1 --chip=16F716 -Q -G --double=24 --float=24 --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" -obuild/default/production/main.p1 main.c
"C:\Program Files\Microchip\xc8\v1.43\bin\xc8.exe" --chip=16F716 -G -mdist/default/production/PWM_16f716.X.production.map --double=24 --float=24 --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" --memorysummary dist/default/production/memoryfile.xml -odist/default/production/PWM_16f716.X.production.elf build/default/production/main.p1
Microchip MPLAB XC8 C Compiler (Free Mode) V1.43
Build date: Jul 24 2017
Part Support Version: 1.43
Copyright (C) 2017 Microchip Technology Inc.
License type: Node Configuration
:: warning: (1273) Omniscient Code Generation not available in Free mode
Memory Summary:
Program space used 44h ( 68) of 800h words ( 3.3%)
Data space used 8h ( 8 ) of 80h bytes ( 6.2%)
EEPROM space None available
Data stack space used 0h ( 0) of 50h bytes ( 0.0%)
Configuration bits used 1h ( 1) of 1h word (100.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)
"C:\Program Files\Microchip\xc8\v1.43\bin\xc8.exe" --chip=16F716 -G -mdist/default/production/PWM_16f716.X.production.map
Microchip MPLAB XC8 Compiler V1.36 ()
Linker command line:
--edf=/opt/microchip/xc8/v1.36/dat/en_msgs.txt -cs \
-h+dist/default/production/XC8C.X.production.sym \
--cmf=dist/default/production/XC8C.X.production.cmf -z -Q16F84A \
-o/tmp/xcX5ug00z -Mdist/default/production/XC8C.X.production.map -E1 \
-ver=XC8 -ASTACK=0Ch-04dh -pstack=STACK -ACODE=00h-03FFh \
-ASTRCODE=00h-03FFh -ASTRING=00h-0FFhx4 -ACONST=00h-0FFhx4 \
-AENTRY=00h-0FFhx4 -ABANK0=0Ch-04Dh -ARAM=0Ch-04Dh -AABS1=0Ch-04Fh \
-ACOMMON=04Eh-04Fh -ASFR0=00h-0Bh -ASFR1=080h-0CDh \
-preset_vec=00h,intentry,init,end_init -ppowerup=CODE -pcinit=CODE \
-pfunctab=CODE -ACONFIG=02007h-02007h -pconfig=CONFIG -DCONFIG=2 \
-AIDLOC=02000h-02003h -pidloc=IDLOC -DIDLOC=2 -AEEDATA=00h-03Fh/02100h \
-peeprom_data=EEDATA -DEEDATA=2 -DCODE=2 -DSTRCODE=2 -DSTRING=2 -DCONST=2 \
-DENTRY=2 -k /tmp/xcXJ9c1UP.obj \
dist/default/production/XC8C.X.production.obj
Ingrese a la carpeta donde se instalo XC8 (que en mi caso es C:\Program Files\Microchip\xc8\v1.43) dentro de ella busque los linkers que debieran estar creados ya que los provee Microchip.
Utilizando la barra de búsqueda (ingrese que buscara .lkr) encontré que los linkers están en la carpeta data, pero en su interior hay solo archivos .lkr para pics 18fxxxx.