Ich verwende den PIC18F13K22 und den C18-Compiler von Microchip in MPLABX. Der PIC wurde immer wieder zurückgesetzt, als er in die Interrupt-Serviceroutine (ISR) springen wollte. Ich konnte das Problem bis zur Deklaration eines Arrays zurückverfolgen:
UINT16 rom periods[] = {64000,59412,55438,51962, ...} // 1024 Values
Wenn ich die Größe des Arrays auf wenige Elemente verkleinere, wird der PIC ausgeführt, ohne kontinuierlich zurückgesetzt zu werden.
Jetzt frage ich mich, warum das große Array einen Reset verursacht. Und noch interessanter für mich: Kann ich irgendwie einen Datensatz deklarieren, der diese 1024 Werte enthält?
Die angeforderten Abschnittsinformationen:
Section Type Address Location Size(Bytes)
--------- --------- --------- --------- ---------
_entry_scn code 0x000000 program 0x000006
.cinit romdata 0x000006 program 0x000002
.romdata_Main.o romdata 0x000008 program 0x000800
.code_Main.o code 0x000808 program 0x000124
_cinit_scn code 0x00092c program 0x00009e
.code_Debug.o code 0x0009ca program 0x000080
.code_Signal.o code 0x000a4a program 0x000040
PROG code 0x000a8a program 0x00003c
.code_t0open.o code 0x000ac6 program 0x000038
.code_ADC.o code 0x000afe program 0x000032
.stringtable romdata 0x000b30 program 0x000026
.code code 0x000b56 program 0x000020
_startup_scn code 0x000b76 program 0x00001c
.code___init.o code 0x000b92 program 0x000002
.romdata_t0open.o romdata 0x000b94 program 0x000000
.idata___init.o_i romdata 0x000b94 program 0x000000
.idata_t0open.o_i romdata 0x000b94 program 0x000000
.romdata_Debug.o romdata 0x000b94 program 0x000000
.idata_Debug.o_i romdata 0x000b94 program 0x000000
.romdata___init.o romdata 0x000b94 program 0x000000
.romdata_Signal.o romdata 0x000b94 program 0x000000
.idata_Signal.o_i romdata 0x000b94 program 0x000000
.idata_Main.o_i romdata 0x000b94 program 0x000000
.romdata_ADC.o romdata 0x000b94 program 0x000000
.idata_ADC.o_i romdata 0x000b94 program 0x000000
.code_c018i.o code 0x000b94 program 0x000000
.romdata_c018i.o romdata 0x000b94 program 0x000000
.idata_c018i.o_i romdata 0x000b94 program 0x000000
.config_300001_Main.o romdata 0x300001 program 0x000001
.config_300002_Main.o romdata 0x300002 program 0x000001
.config_300003_Main.o romdata 0x300003 program 0x000001
.config_300005_Main.o romdata 0x300005 program 0x000001
.config_300006_Main.o romdata 0x300006 program 0x000001
MATH_DATA udata 0x000000 data 0x000014
.tmpdata udata 0x000014 data 0x000000
.stack udata 0x000060 data 0x000050
.udata_c018i.o udata 0x0000b0 data 0x00000a
.udata_Signal.o udata 0x0000ba data 0x000002
.idata_c018i.o idata 0x0000bc data 0x000000
.udata_ADC.o udata 0x0000bc data 0x000000
.idata_ADC.o idata 0x0000bc data 0x000000
.udata_Main.o udata 0x0000bc data 0x000000
.idata_Main.o idata 0x0000bc data 0x000000
.idata_Signal.o idata 0x0000bc data 0x000000
.udata_Debug.o udata 0x0000bc data 0x000000
.idata_Debug.o idata 0x0000bc data 0x000000
.udata_t0open.o udata 0x0000bc data 0x000000
.idata_t0open.o idata 0x0000bc data 0x000000
.udata___init.o udata 0x0000bc data 0x000000
.idata___init.o idata 0x0000bc data 0x000000
SFR_UNBANKED0 udata 0x000f68 data 0x000098
Aufgrund von Olins Antwort konnte ich das Problem beseitigen.
Wie Olin geschrieben hat, platziert der Linker das Array unter der Adresse 0x08. Dies ist die Interrupt-Vektoradresse.
Eine "Problemumgehung" besteht nun darin, Code explizit an der Adresse 0x08 zu platzieren, die zum ISR springt. (Inspiriert von der C18-Bedienungsanleitung Seite 29):
oder noch einfacher:
quelle