Code Banking con SDCC
-
05-07-2019 - |
Domanda
Devo usare il code banking in un microcontrollore 8051 per adattarsi a tutto il codice. SDCC afferma che lo supporta, ma sto riscontrando problemi nella fase di collegamento.
Ho un progetto di test con 3 file: main.c, func1.c e bank.asm. La funzione principale dovrebbe chiamare func1 () e quindi sedersi in un ciclo while. Ma func1 () si trova in una banca di codici diversa.
// main.c
int func1(void) banked;
void main()
{
int i = func1();
while(i)
{
}
}
// func1.c
#pragma codeseg BANK1
int func1(void) {
return 99; }
//bank.asm
.area HOME (CODE)
.area GSINIT0 (CODE)
.area GSINIT1 (CODE)
.area GSINIT2 (CODE)
.area GSINIT3 (CODE)
.area GSINIT4 (CODE)
.area GSINIT5 (CODE)
.area GSINIT (CODE)
.area GSFINAL (CODE)
.area CSEG (CODE)
.area HOME (CODE)
__sdcc_banked_call::
ret ;make the call
__sdcc_banked_ret::
ret ;return to caller
Ho un file batch di compilazione per compilare tutto e collegarlo insieme.
sdcc -c func1.c
sdcc -c main.c
asx8051 -ol bank.asm
sdcc "-Wl -b BANK1=0x018000" main.rel func1.rel bank.rel
Ottengo questo errore del linker:
?ASlink-Error-Insufficient ROM/EPROM/FLASH memory.
Come posso ottenere questo link?
Soluzione
Dal manuale SDCC:
I segmenti possono essere posizionati ovunque nel 4 megabyte di spazio indirizzo utilizzando il solito - * - opzioni loc. Si noti che se qualche segmento si trova sopra 64 KB, il -r flag deve essere passato al linker a generare il segmento corretto rilocazioni e output Intel HEX il formato deve essere utilizzato. La bandiera -r può essere passato al linker usando il opzione -Wl-r sulla riga comandi SDCC. Tuttavia, attualmente il linker non può gestire segmenti di codice > 64k.
Quindi, aggiungi -Wl-r alla riga del linker.
Altri suggerimenti
Non ho familiarità con SDCC, ma da altre architetture di memoria bancaria, abbiamo dovuto fornire le chiamate di funzione di banca reindirizzate.
Devi inserire il codice corretto per impostare i registri di banca o cosa imposta il banco di memoria in:
__sdcc_banked_call::
ret ;make the call
__sdcc_banked_ret::
ret ;return to caller
routine?
Anche se questo non è probabilmente il problema del linker.
Devi definire un codice seg per: BANK1?
Sembra che stia configurando i segmenti di codice:
//bank.asm
.area HOME (CODE)
.area GSINIT0 (CODE)
.area GSINIT1 (CODE)
.area GSINIT2 (CODE)
.area GSINIT3 (CODE)
.area GSINIT4 (CODE)
.area GSINIT5 (CODE)
.area GSINIT (CODE)
.area GSFINAL (CODE)
.area CSEG (CODE)
.area HOME (CODE)
ma non è stato definito BANK1. Esiste un file linker e assegna tutto lo spazio di memoria / flash a questi segmenti di codice?