From: Vangelis R. <vr...@ot...> - 2004-10-27 13:21:33
|
I send this to the sdcc-devel list since replying in the bug tracker is making things more complex than required! On Tue, 26 Oct 2004, SourceForge.net wrote: > Category: pic16 target > Group: None > Status: Open > Resolution: None > Priority: 5 > Submitted By: ccsporters (tecodev) > Assigned to: Vangelis Rokas (vrokas) > Summary: too large .udata sections > > Comment By: Craig Franklin (craigfranklin) > Date: 2004-10-27 00:47 > > Modifying the linker script will allow the project to link. > However, SDCC will still need to ensure that the bank > switching is handled properly. > > That is the main reason the script is split into banks. The > split ensures that no data section crosses a bank boundary. > That usually causes headaches for PIC compilers. With the > splits the compiler can make assumptions that reduce the > number of switches required. > > I highly recommend appending the name of each object to the > end of the data section (.udata_main). It probably would > allow this example to compile without modifying the script. Now I see what both Craig and Rapahel mean. Initially I thought that the problem was there was not enough udata ram to hold a single element, but the bug entry asked for udata ram when multiple elements where defined. I thought that gplink was clever enough to place symbols placed under the generic udata section in various sections of data ram. But this is not the case. Its not difficult at all to split symbols in their own .udata section. In fact it might be desirable. But this raises another issue Craig, which is not solved by the above approach. (which of course isn't discussed in the bug report, but it was the issue *I thought* that was raised initially) Even if we split udata symbols, an array of 280 bytes still wouldn't fit in a single section, so we have to modify the linker script. PIC16 port currently doesn't care about symbol relocation because a BANKSEL directive is always emited before a udata variable is used. This of course might decrease performance, but there is no way (at this point) to know how and if a symbol is placed between banks. Here is the result of the example Raphael sent: udata _main_array1_1_1 res 128 _main_array2_1_1 res 117 S_s95__main code _main: ; .line 7; s95.c array1[1] = 1; MOVLW 0x01 BANKSEL (_main_array1_1_1 + 1) MOVWF (_main_array1_1_1 + 1), B ; .line 8; s95.c array2[1] = 1; MOVLW 0x01 BANKSEL (_main_array2_1_1 + 1) MOVWF (_main_array2_1_1 + 1), B ; .line 10; s95.c return 0; MOVLW 0x00 MOVWF PRODL MOVLW 0x00 RETURN end As you can BSR is updated twice (in this example the second banksel is redudant, but how the compiler would know that both symbols are placed in same section?) Even if we use the standard banks and split the 280 bytes array to 256 and 24 bytes, is there any guarantee that gplink will place the two sections in consequtive sections (so that a pointer access with FSR0 to be able to traverse the whole array) ?? It would be a great advantage if there was any kind of compiler <---> linker intercommunication that would give the compiler a layout of the variable allocation chart. Then the compiler would skip some banksel directives. But this approach doesn't work for projects with many object files. Another solution (the professional solution in my opinion) would be to modify the linker to remove redudant banksels from the objects. But this should be a heavy job to do. I could help, but I need some guidance on gputils/gplink internals and some spare time as a gift! > Initial Comment: > We faced the problem that SDCC merges .udata to big > sections even if they do not fit into one bank. Example > code: > > **** > #pragma stack 0x300 > > int main () > { > unsigned char array1[128]; > unsigned char array2[117]; // 116 works > array1[1] = 1; > array2[1] = 1; > > return 0; > } > **** > > gplink refuses with > error: no target memory available for section ".udata" > > As the gplink developers told us they do not see this > as a bug because additional banksels would be required > while walking in an array. So we will have to accept > that no single data structure can be bigger than 244 bytes. > > But SDCC should split .udata sections to chunks that > gplink accepts when each variable and array is smaller > than a bank but larger in total. > > SDCC version is: pic16 2.4.5 #862 (Oct 5 2004) > Command line was: sdcc -mpic16 -p18f6720 I don't consider the above as a bug in the compiler, it is more like an interpretation issue. ANW, I'll modify the compiler to emit each symbol in its own udata section. The question that remains is why there is a limit of 244 bytes, when there 256 bytes available for each section?! regards, Vangelis |