Hello,
I use the 9S12XEQ384 derivative. My compiling options are: -CPUHCS12XE -D__NO_FLOAT__ -D__MAP_FLASH__ -D__FAR_DATA -Mb -MapFlash -Onf -OnB=b -PSegObj
I first set an array of 8 bytes of data in func1.
Then I call func2 with a pointer to this array of 8 bytes as argument.
Inside func2, all data read from this array are 0s,I don't understand this.
I.e. the following program:
void func1_every1ms(void)
{
U8 buffer[8] = {0, 0, 0, 0, 0, 0x0A, 0x0F, 0x05};
log_printf("Inside func1, before call:\n");
log_U32((U32)buffer);
log_U32(*(U32 *)&buffer[0]);
log_U32(*(U32 *)&buffer[4]);
func2_handler(buffer);
log_printf("Inside func1, after call:\n");
log_U32(*(U32 *)&buffer[0]);
log_U32(*(U32 *)&buffer[4]);
}
void func2_handler(U8 *buffer)
{
if (buffer != NULL))
{
log_printf("Inside func2:\n");
log_U32((U32)buffer));
log_U32(*(U32 *)&buffer[0]);
log_U32(*(U32 *)&buffer[4]);
}
gives the following result:
Inside func1, before call
01B9C00
00000000
00000AF5
Inside func2:
01B9C00
00000000
00000000
Inside func1, after call
00000000
00000AF5
Does anyone have an idea why it is not possible to read back the 8 byte array of data inside func2, and why instead I read all zeros?
已解决! 转到解答。
But you can reproduce problem in new project with IP sensitive things removed. If you can't reproduce the problem in small new project, then looking for differences should reveal what's wrong. Unfortunately it is very common to be lazy like a hell to not start new small experimental projects. People prefer spending hours looking at thousand of lines without any progress.
But you can reproduce problem in new project with IP sensitive things removed. If you can't reproduce the problem in small new project, then looking for differences should reveal what's wrong. Unfortunately it is very common to be lazy like a hell to not start new small experimental projects. People prefer spending hours looking at thousand of lines without any progress.
Thanks for your recommandation to build a small projet.
My fault: there was a "switch" with 3 "cases" in func2_handler(); and I forgot the "break" instructions.
This caused the buffer not to be consistent.
Thanks again for having helped me.
Either your PRM file is misedited or it is a result of allocating enormously big objects on the stack. Your buffer[] is allocated on stack. You should check, maybe some very big array is allocated on stack.
void func1_every1ms(void)
{
U8 buffer[8] = {0, 0, 0, 0, 0, 0x0A, 0x0F, 0x05};
Ok, there was a typo:
void func1_every1ms(void)
{
U8 buffer[8] = {0, 0, 0, 0, 0, 0, 0x0A, 0xF5};
The stack size is 0xBB8.
Here is the prm file:
/* This is a linker parameter file for the MC9S12XEQ384 */
/*
This parameter file is setup in a generic way to allow exploring most common features of both cores:
- S12X core
- XGATE code and constants in FLASH and/or RAM
- XGATE data and stack in RAM
It might be required to adapt some of the definitions to best match your application.
*/
NAMES
/* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your additional files */
END
SEGMENTS /* here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. All addresses are 'logical' */
/* Register space */
/* IO_SEG = PAGED 0x0000 TO 0x07FF; intentionally not defined */
/* non-paged EEPROM */
EEPROM = READ_ONLY DATA_NEAR IBCC_NEAR 0x0C00 TO 0x0FFF;
/* non-paged RAM */
RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF ALIGN 2[1:1]; /* word align for XGATE accesses */
/* non-banked FLASH */
ROM_4000 = READ_ONLY DATA_NEAR IBCC_NEAR 0x4000 TO 0x7FFB; /* instead of default 0x7FFF (see EGV PR 386) */
ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xCFFF;
ROM_D000 = READ_ONLY 0xD000 TO 0xFEFB; /* instead of default 0xFEFF */
/* VECTORS = READ_ONLY 0xFF00 TO 0xFFFF; intentionally not defined: used for VECTOR commands below */
//OSVECTORS = READ_ONLY 0xFF10 TO 0xFFFF; /* OSEK interrupt vectors (use your vector.o) */
/* paged EEPROM 0x0800 TO 0x0BFF; addressed through EPAGE */
EEPROM_00 = READ_ONLY DATA_FAR IBCC_FAR 0x000800 TO 0x000BFF;
EEPROM_01 = READ_ONLY DATA_FAR IBCC_FAR 0x010800 TO 0x010BFF;
EEPROM_02 = READ_ONLY DATA_FAR IBCC_FAR 0x020800 TO 0x020BFF;
EEPROM_03 = READ_ONLY DATA_FAR IBCC_FAR 0x030800 TO 0x030BFF;
EEPROM_04 = READ_ONLY DATA_FAR IBCC_FAR 0x040800 TO 0x040BFF;
EEPROM_05 = READ_ONLY DATA_FAR IBCC_FAR 0x050800 TO 0x050BFF;
EEPROM_06 = READ_ONLY DATA_FAR IBCC_FAR 0x060800 TO 0x060BFF;
EEPROM_07 = READ_ONLY DATA_FAR IBCC_FAR 0x070800 TO 0x070BFF;
EEPROM_08 = READ_ONLY DATA_FAR IBCC_FAR 0x080800 TO 0x080BFF;
EEPROM_09 = READ_ONLY DATA_FAR IBCC_FAR 0x090800 TO 0x090BFF;
EEPROM_0A = READ_ONLY DATA_FAR IBCC_FAR 0x0A0800 TO 0x0A0BFF;
EEPROM_0B = READ_ONLY DATA_FAR IBCC_FAR 0x0B0800 TO 0x0B0BFF;
EEPROM_0C = READ_ONLY DATA_FAR IBCC_FAR 0x0C0800 TO 0x0C0BFF;
EEPROM_0D = READ_ONLY DATA_FAR IBCC_FAR 0x0D0800 TO 0x0D0BFF;
EEPROM_0E = READ_ONLY DATA_FAR IBCC_FAR 0x0E0800 TO 0x0E0BFF;
EEPROM_0F = READ_ONLY DATA_FAR IBCC_FAR 0x0F0800 TO 0x0F0BFF;
EEPROM_10 = READ_ONLY DATA_FAR IBCC_FAR 0x100800 TO 0x100BFF;
EEPROM_11 = READ_ONLY DATA_FAR IBCC_FAR 0x110800 TO 0x110BFF;
EEPROM_12 = READ_ONLY DATA_FAR IBCC_FAR 0x120800 TO 0x120BFF;
EEPROM_13 = READ_ONLY DATA_FAR IBCC_FAR 0x130800 TO 0x130BFF;
EEPROM_14 = READ_ONLY DATA_FAR IBCC_FAR 0x140800 TO 0x140BFF;
EEPROM_15 = READ_ONLY DATA_FAR IBCC_FAR 0x150800 TO 0x150BFF;
EEPROM_16 = READ_ONLY DATA_FAR IBCC_FAR 0x160800 TO 0x160BFF;
EEPROM_17 = READ_ONLY DATA_FAR IBCC_FAR 0x170800 TO 0x170BFF;
EEPROM_18 = READ_ONLY DATA_FAR IBCC_FAR 0x180800 TO 0x180BFF;
EEPROM_19 = READ_ONLY DATA_FAR IBCC_FAR 0x190800 TO 0x190BFF;
EEPROM_1A = READ_ONLY DATA_FAR IBCC_FAR 0x1A0800 TO 0x1A0BFF;
EEPROM_1B = READ_ONLY DATA_FAR IBCC_FAR 0x1B0800 TO 0x1B0BFF;
EEPROM_1C = READ_ONLY DATA_FAR IBCC_FAR 0x1C0800 TO 0x1C0BFF;
EEPROM_1D = READ_ONLY DATA_FAR IBCC_FAR 0x1D0800 TO 0x1D0BFF;
EEPROM_1E = READ_ONLY DATA_FAR IBCC_FAR 0x1E0800 TO 0x1E0BFF;
EEPROM_1F = READ_ONLY DATA_FAR IBCC_FAR 0x1F0800 TO 0x1F0BFF;
EEPROM_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC0800 TO 0xFC0BFF;
EEPROM_FD = READ_ONLY DATA_FAR IBCC_FAR 0xFD0800 TO 0xFD0BFF;
EEPROM_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE0800 TO 0xFE0BFF;
/* EEPROM_FF = READ_ONLY 0xFF0800 TO 0xFF0BFF; intentionally not defined: equivalent to EEPROM */
/* paged RAM: 0x1000 TO 0x1FFF; addressed through RPAGE */
RAM_XGATE_STK_L_ = NO_INIT DATA_FAR 0xFA1000 TO 0xFA107D;
RAM_XGATE_STK_L = NO_INIT DATA_FAR 0xFA107E TO 0xFA107F;
RAM_XGATE_STK_H_ = NO_INIT DATA_FAR 0xFA1080 TO 0xFA10FD;
RAM_XGATE_STK_H = NO_INIT DATA_FAR 0xFA10FE TO 0xFA10FF;
RAM_FA = READ_WRITE DATA_FAR 0xFA1100 TO 0xFA1FFF ALIGN 2[1:1]; /* is also mapped to XGATE: 0xA100..0xAFFF */
RAM_FB = READ_WRITE DATA_FAR 0xFB1000 TO 0xFB1FFF ALIGN 2[1:1]; /* is also mapped to XGATE: 0xB000..0xBFFF */
RAM_FC = READ_WRITE DATA_FAR 0xFC1000 TO 0xFC1FFF ALIGN 2[1:1]; /* is also mapped to XGATE: 0xC000..0xCFFF */
RAM_FD = READ_WRITE DATA_FAR 0xFD1000 TO 0xFD1FFF ALIGN 2[1:1]; /* is also mapped to XGATE: 0xD000..0xDFFF */
/* RAM_FE = READ_WRITE 0xFE1000 TO 0xFE1FFF; intentionally not defined: equivalent to RAM: 0x2000..0x2FFF */
/* RAM_FF = READ_WRITE 0xFF1000 TO 0xFF1FFF; intentionally not defined: equivalent to RAM: 0x3000..0x3FFF */
/* paged FLASH: 0x8000 TO 0xBFFF; addressed through PPAGE */
PAGE_E0_0 = READ_ONLY DATA_FAR IBCC_FAR 0xE08000 TO 0xE087FF; /* cannot be mapped to XGATE; XGATE sees registers here */
PAGE_E0 = READ_ONLY DATA_FAR IBCC_FAR 0xE08800 TO 0xE0BFFF ALIGN 2[1:1]; /* is also mapped to XGATE: 0x0800..0x3FFF */
PAGE_E1 = READ_ONLY DATA_FAR IBCC_FAR 0xE18000 TO 0xE1BFFF ALIGN 2[1:1]; /* is also mapped to XGATE: 0x4000..0x7FFF */
// cannot be mapped to XGATE; this module should NOT be used for HC12 code when also used for XGATE code since
//the HC12 will have priority over the XGATE accessing the FLASH modules resulting very poor performance of
//the XGATE: Check allocation of this ranges in PLACEMENT below!
PAGE_E2 = READ_ONLY DATA_FAR IBCC_FAR 0xE28000 TO 0xE2BFFF;
PAGE_E3 = READ_ONLY DATA_FAR IBCC_FAR 0xE38000 TO 0xE3BFFF;
PAGE_E4 = READ_ONLY DATA_FAR IBCC_FAR 0xE48000 TO 0xE4BFFF;
PAGE_E5 = READ_ONLY DATA_FAR IBCC_FAR 0xE58000 TO 0xE5BFFF;
PAGE_E6 = READ_ONLY DATA_FAR IBCC_FAR 0xE68000 TO 0xE6BFFF;
PAGE_E7 = READ_ONLY DATA_FAR IBCC_FAR 0xE78000 TO 0xE7BFFF;
PAGE_F0 = READ_ONLY DATA_FAR IBCC_FAR 0xF08000 TO 0xF0BFFF;
PAGE_F1 = READ_ONLY DATA_FAR IBCC_FAR 0xF18000 TO 0xF1BFFF;
PAGE_F2 = READ_ONLY DATA_FAR IBCC_FAR 0xF28000 TO 0xF2BFFF;
PAGE_F3 = READ_ONLY DATA_FAR IBCC_FAR 0xF38000 TO 0xF3BFFF;
PAGE_F4 = READ_ONLY DATA_FAR IBCC_FAR 0xF48000 TO 0xF4BFFF;
PAGE_F5 = READ_ONLY DATA_FAR IBCC_FAR 0xF58000 TO 0xF5BFFF;
PAGE_F6 = READ_ONLY DATA_FAR IBCC_FAR 0xF68000 TO 0xF6BFFF;
PAGE_F7 = READ_ONLY DATA_FAR IBCC_FAR 0xF78000 TO 0xF7BFFF;
PAGE_F8 = READ_ONLY DATA_FAR IBCC_FAR 0xF88000 TO 0xF8BFFF;
PAGE_F9 = READ_ONLY DATA_FAR IBCC_FAR 0xF98000 TO 0xF9BFFF;
PAGE_FA = READ_ONLY DATA_FAR IBCC_FAR 0xFA8000 TO 0xFABFFF;
PAGE_FB = READ_ONLY DATA_FAR IBCC_FAR 0xFB8000 TO 0xFBBFFF;
PAGE_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC8000 TO 0xFCBFFF;
/* PAGE_FD = READ_ONLY 0xFD8000 TO 0xFDBFFF; intentionally not defined: equivalent to ROM_4000 */
PAGE_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE8000 TO 0xFEBFFF;
/* PAGE_FF = READ_ONLY 0xFF8000 TO 0xFFBFFF; intentionally not defined: equivalent to ROM_C000 */
END
PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */
_PRESTART, /* Used in HIWARE format: jump to _Startup at the code start */
STARTUP, /* startup data structures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */
//.ostext, /* eventually OSEK code */
NON_BANKED, /* runtime routines which must not be banked */
COPY /* copy down information: how to initialize variables */
/* in case you want to use ROM_4000 here as well, make sure
that all files (incl. library files) are compiled with the
option: -OnB=b */
INTO ROM_D000;
DEFAULT_ROM INTO PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8,
PAGE_F7, PAGE_F6, PAGE_F5, PAGE_F4, PAGE_F3, PAGE_F2, PAGE_F1, PAGE_F0,
PAGE_E7, PAGE_E6, PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2,
/* PAGE_E1 intentionally not listed: assigned to XGATE */
/* PAGE_E0 intentionally not listed: assigned to XGATE */
PAGE_E0_0;
//XGATE_STRING_FLASH, /* XGATE strings that should always go into flash */
//XGATE_CONST_FLASH, /* XGATE constants what should always go into flash */
//XGATE_CODE_FLASH /* XGATE code that should always run out of flash */
// INTO PAGE_E0, PAGE_E1; /* FLASH accessible by XGATE */
//.stackstart, /* eventually used for OSEK kernel awareness: Main-Stack Start */
// SSTACK, /* allocate stack first to avoid overwriting variables on overflow */
//.stackend, /* eventually used for OSEK kernel awareness: Main-Stack End */
DEFAULT_RAM /* all variables, the default RAM location */
INTO RAM;
SHARED_DATA /* variables that are shared between CPU12 and XGATE */
INTO RAM;
XGATE_VECTORS, /* XGATE vector table has to be copied into RAM by HCS12X */
XGATE_STRING, /* XGATE string literals have to be copied into RAM by HCS12X */
XGATE_CONST, /* XGATE constants have to be copied into RAM by HCS12X */
XGATE_CODE, /* XGATE functions have to be copied into RAM by HCS12X */
XGATE_STRING_RAM, /* XGATE strings that should always go into RAM */
XGATE_CONST_RAM, /* XGATE constants what should always go into RAM */
XGATE_CODE_RAM, /* XGATE code that should always run out of RAM */
XGATE_DATA /* data that are accessed by XGATE only */
INTO RAM_FA, RAM_FB, RAM_FC /*, RAM_FD */;
SSTACK
INTO RAM_FD;
PAGED_RAM /* there is no need for paged data accesses on this derivative */
INTO RAM;
XGATE_STK_L INTO RAM_XGATE_STK_L;
XGATE_STK_H INTO RAM_XGATE_STK_H;
//.vectors INTO OSVECTORS; /* OSEK vector table */
END
ENTRIES /* keep the following unreferenced variables */
/* OSEK: always allocate the vector table and all dependent objects */
//_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStart
END
STACKSIZE 0xBB8 /* size of the stack (will be allocated in DEFAULT_RAM) */
/* use these definitions in plane of the vector table ('vectors') above */
VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */
//VECTOR 0 Entry /* reset vector: this is the default entry point for an Assembly application. */
//INIT Entry /* for assembly applications: that this is as well the initialization entry point */
Thanks for your answer.
Yes. I assume there is no drawback to put the stack in pagined RAM, but I am a beginner on the S12X.
Maybe I am wrong, but in that case, shouldn't I read FD1B9C instead of 1B9C for the value of the pointer?
> Yes. I assume there is no drawback to put the stack in pagined RAM
Well one drawback is that a normal pointer cannot reliably point to a local variable anymore.
I would not locate the stack in paged RAM.
> shouldn't I read FD1B9C instead of 1B9C for the value of the pointer
Not sure why you are expecting that, a 16 bit pointer cannot contain a 24 bit address.
Not 100% sure, but I think locals are always expected to be non paged.
Daniel