From: Dennis M. <djm...@gm...> - 2008-10-28 19:46:54
|
I have a little test program I've been playing with to test different variable sizes and locations. I came across a weird situation and I'm hoping someone can help me explain it. Chip=Cypress Ez-Usb (fx2lp) (8051/2) Here is the guts of my test: xdata BYTE buf[100]; xdata WORD count=0; bit light=0; void main() { while (1) { ++count; if (count % 1000 == 0) { bit=!bit; if (bit) { <snipped> } // custom board light on/off .. really simple memory reads } } } compiled with sdcc 2.8.0: sdcc -mmcs51 --xram-loc 0x4000 .... args The situation is this: For some sizes of buf, the program works. For other sizes, it doesn't work at all. Here is the RAM line from a non-working .mem file after compilation (xdata BYTE buf[100]): EXTERNAL RAM 0x4000 0x4065 102 65536 The funny thing is, I can increase it to large sizes, and it will work (xdata BYTE buf[0x3000]): EXTERNAL RAM 0x4000 0x7001 12290 65536 Anyone have any idea why the program doesn't run when buf size is 100. I'm not even using the buf variable.. I was just playing with different ways of allocating data and where they are located and came across this problem. -Dennis |
From: Dennis M. <djm...@gm...> - 2008-10-28 21:14:36
|
Dennis Muhlestein wrote: > I have a little test program I've been playing with to test different > variable sizes and locations. I came across a weird situation and I'm > hoping someone can help me explain it. I've traced this problem down to a smaller issue. It seems the declarations and initialization of the xdata are what is breaking my firmware. The following is broken: > xdata BYTE buf[100]; > xdata WORD count=0; If I instead initialize count to 0 inside main(), the firmware runs correctly: xdata BYTE buf[100]; xdata WORD count; void main() { count=0; ... It seems that having the external initialized data (XISEG in the assembly) causes my problem. The funny thing is, it only breaks when count falls on a an address like: 0x64 (100) 0x164 0x264 etc. I've tried 0x162 0x166, 0x262, 0x266 etc. and those addresses are working properly. I can reproduce the problem exactly by simply starting the xram location at the broken address and removing buf entirely: // comment out buff xdata BYTE[100]; xdata WORD count=0; Then compile: sdcc -mmcs51 --xram-loc 0x4064 ... So the issues is this: If my xdata variable is initialized and happens to lie on certain memory locations, the firmware doesn't run. I'm a little stumped as to why this is the case. In the mean time, I suppose I can get around it by initializing my variables locally instead of globally. Any thoughts as to why this is an issue? Perhaps there is a bug. -Dennis |
From: Toufiké HENNI-C. <hen...@fr...> - 2008-10-28 23:21:49
|
Hello, Today I downloaded the latest version of SDCC and installed in Windows XP. When I try to compile my C source file, (sdcc --compile-only essai.c), I get the error: "Preproc file not found : Invalid argument" Someone can help me ? Best Regards Toufiké HENNI-CHEBRA / / |
From: <pg...@la...> - 2008-10-28 23:24:33
|
dennis wrote: > It seems the declarations and initialization of the xdata are what is > breaking my firmware. The following is broken: > > xdata BYTE buf[100]; > > xdata WORD count=0; > If I instead initialize count to 0 inside main(), the firmware runs > correctly: > > xdata BYTE buf[100]; > xdata WORD count; > void main() { > count=0; > ... > > > It seems that having the external initialized data (XISEG in the > assembly) causes my problem. The funny thing is, it only breaks when > count falls on a an address like: > 0x64 (100) > 0x164 > 0x264 etc. > > I've tried 0x162 0x166, 0x262, 0x266 etc. and those addresses are > working properly. I can reproduce the problem exactly by simply > starting the xram location at the broken address and removing buf entirely: > > // comment out buff xdata BYTE[100]; > xdata WORD count=0; > > Then compile: sdcc -mmcs51 --xram-loc 0x4064 ... > > > So the issues is this: > > If my xdata variable is initialized and happens to lie on certain memory > locations, the firmware doesn't run. I'm a little stumped as to why > this is the case. In the mean time, I suppose I can get around it by > initializing my variables locally instead of globally. > > Any thoughts as to why this is an issue? Perhaps there is a bug. how are your initialized globals actually being initialized? are you sure they _are_ being initialized? if your linker or runtime startup code aren't set up correctly, then it's quite easy for static initializations to not happen, leaving the contents of those locations undefined. it's also possible that uninitialized data (which, according to C language rules, should be 0 on startup) may work correctly: i.e., if you never set a value in "count" at all, your code might work. again, it depends on the C startup code. paul =--------------------- paul fox, pg...@la... |
From: Dennis M. <djm...@gm...> - 2008-10-29 01:16:50
|
>> > > > how are your initialized globals actually being initialized? are > you sure they _are_ being initialized? if your linker or runtime > startup code aren't set up correctly, then it's quite easy for > static initializations to not happen, leaving the contents of > those locations undefined. > > it's also possible that uninitialized data (which, according to C > language rules, should be 0 on startup) may work correctly: i.e., > if you never set a value in "count" at all, your code might work. > again, it depends on the C startup code. Well, I'm not doing anything other than the default xinit startup code that is generated by sdcc. with a global: xdata BYTE buf[0x64]; xdata WORD count=0; I get this assembly (snipped): <snip> ;-------------------------------------------------------- ; external initialized ram data ;-------------------------------------------------------- .area XISEG (XDATA) G$count$0$0==. _count:: .ds 2 .area HOME (CODE) <snip> Fmem$__xinit_count$0$0 == . __xinit__count: .byte #0x00,#0x00 .area CABS (ABS,CODE) When I change the buffer in front of the count variable (or use xram- loc) the output assembly is exactly the same in regards to count. The only difference between the two assembly outputs is the size of the buffer: Diff: G$buf$0$0==. _buf:: - .ds 100 + .ds 102 The only difference between the two firmwares is that when the count variable is located at 0x64 (or the other locations I pointed out and probably many more), the firmware doesn't run. I'm not sure why the location of the variable matters in the slightest but that seems to me to be the case. -Dennis |
From: Toufiké HENNI-C. <hen...@fr...> - 2008-10-29 20:41:12
|
Hello, Today I downloaded the latest version of SDCC and installed it under Windows XP. When I try to compile my C source file, (sdcc --compile-only essai.c), I get the error: "Preproc file not found : Invalid argument" Can anyone help me ? Best Regards Toufiké HENNI-CHEBRA |
From: Dennis M. <djm...@gm...> - 2008-10-31 15:39:23
|
Dennis Muhlestein wrote: > Dennis Muhlestein wrote: >> I have a little test program I've been playing with to test different >> variable sizes and locations. I came across a weird situation and >> I'm hoping someone can help me explain it. > I've traced this problem down to a smaller issue. > > It seems the declarations and initialization of the xdata are what is > breaking my firmware. The following is broken: >> xdata BYTE buf[100]; >> xdata WORD count=0; > I think this problem has to do with the _XPAGE sfr. Defining _XPAGE for sfr at 0x92 seems to fix the global initialization problem. I'm not entirely sure the problem is gone, but it at least fixes my simple test case. For my program to work, I still have to use --xram-loc of somewhere around 896 to 1024 bytes (0x0400 works) Can anyone shed some light as to why the default xram location doesn't work? (cypress fx2lp) -Dennis |
From: Maarten B. <sou...@ds...> - 2008-11-02 09:22:10
|
Dennis, Initially you had --xram-loc=0x4000, but the FX2 has only 16kB RAM so there is nothing at 0x4000 unless you have external RAM connected. Without any --xram-loc SDCC puts xdata at 0x0000 but unless you have external ROM and EA=1 this memory is shared with code memory. So any write to xdata 0x0000 and up will overwrite the reset- and interrupt vectors and the rest of your program! During initialization SDCC needs something like P2 on the original 8051 to output the high byte of the address. For the FX2 this is MPAGE (0x92) and you need to tell SDCC about it through defining _XPAGE. An alternative is to reassemble crtxinit.asm for dual data pointer use as the FX2 supports that as well. So if you only have internal memory, you best use -- code-size=0x3000 to limit the generated code size and -- xram-loc=0x3000 and --xram-size=0x1000 to make sure xdata does not overlap with code memory. Maarten > Dennis Muhlestein wrote: > > Dennis Muhlestein wrote: > >> I have a little test program I've been playing with to test different > >> variable sizes and locations. I came across a weird situation and > >> I'm hoping someone can help me explain it. > > I've traced this problem down to a smaller issue. > > > > It seems the declarations and initialization of the xdata are what is > > breaking my firmware. The following is broken: > >> xdata BYTE buf[100]; > >> xdata WORD count=0; > > > I think this problem has to do with the _XPAGE sfr. > > Defining _XPAGE for sfr at 0x92 seems to fix the global initialization > problem. > > I'm not entirely sure the problem is gone, but it at least fixes my > simple test case. > > For my program to work, I still have to use --xram-loc of somewhere > around 896 to 1024 bytes (0x0400 works) > > Can anyone shed some light as to why the default xram location doesn't work? > (cypress fx2lp) > > -Dennis > > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Sdcc-user mailing list > Sdc...@li... > https://lists.sourceforge.net/lists/listinfo/sdcc-user > |
From: Dennis M. <djm...@gm...> - 2008-11-03 21:49:28
|
Maarten Brock wrote: > Dennis, > > Initially you had --xram-loc=0x4000, but the FX2 has > only 16kB RAM so there is nothing at 0x4000 unless you > have external RAM connected. Without any --xram-loc SDCC > puts xdata at 0x0000 but unless you have external ROM > and EA=1 this memory is shared with code memory. So any > write to xdata 0x0000 and up will overwrite the reset- > and interrupt vectors and the rest of your program! The Development board does indeed have external ram shared with the code space at 0x0000 to 0x4000. It has 64k total external ram (0x0000 to 0xffff). That is why starting at a higher number like 0x4000 works. The external memory can be turned off though depending on a couple jumper switches so that only up to 0x4000 is available for a program. > > During initialization SDCC needs something like P2 on > the original 8051 to output the high byte of the > address. For the FX2 this is MPAGE (0x92) and you need > to tell SDCC about it through defining _XPAGE. An > alternative is to reassemble crtxinit.asm for dual data > pointer use as the FX2 supports that as well. If using _XPAGE works, I don't see a lot of reason to redo crtxinit.asm. I do wonder if changing the way xdata is used by the compiler in general is worth looking at. i.e., why use _XPAGE if you can always use dptr? > > So if you only have internal memory, you best use -- > code-size=0x3000 to limit the generated code size and -- > xram-loc=0x3000 and --xram-size=0x1000 to make sure > xdata does not overlap with code memory. Thanks for the additional info, this is helping to clarify what was going on and what can be done to help ensure a more stable build environment (like not having added variables crash the program.) -Dennis |