Hello, To make a long story short I have switched from the Yagarto package with arm-elf (old, but good, Olimex GCCFD) to a fairly recent version using arm-none-eabi (updating the IDE based on the Yagarto homepage this time --- many thanks to Michael Fischer for putting it all together!). When I compile my project I get the following error message (quite a few object files removed from the link line for clarity): arm-none-eabi-ld -v -Lc:\Programs\Yagarto\lib\gcc\arm-none-eabi\4.6.2 -Lc:\Programs\Yagarto\arm-none-eabi\lib -L. -Map main.map -T2138_demo.cmd -o main.out crt.o main.o adcAD7686.o timer.o UARTStdIO.o --start-group -lm -lg -lgcc -lc --end-group GNU ld (GNU Binutils) 2.21 c:\Programs\Yagarto\arm-none-eabi\lib\libg.a(lib_a-sbrkr.o): In function `_sbrk_r': C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/.. /../../../../newlib-1.19.0/newlib/libc/reent/sbrkr.c:60: undefined reference to `_sbrk' make: *** [main.out] Error 1 **** Build Finished **** It seems like there is a reference to the function _sbrk. Apparently some function is calling this that I'm unaware of. Looking on the net, it seems like _sbrk is a very hardware dependent function, but I can't find any library (newlib?) for my LPC2138 and I'm not experienced enough to write it myself. I tried making a simple stub and making a super simple libnewlib.a only including this stub. Turns out the linking works out, but the controller hangs... The same line based on arm-elf works and can run the code so my guess is that I - for some reason - need the newlib and the _sbrk function. Or rather, using arm-none-eabi I use some function that makes a call to _sbrk. Any suggestions for the following would be highly appreciated: 1. Is there any way to find out what function actually is calling _sbrk? When stepping through the controller code, it hangs when returning from a function call so it's not obvious there. 2. Where can I find information about the difference between elf and none-eabi (what is it? - OK, consider me newbie)? 3. Can anyone suggest a working newlib (with _sbrk) for the LPC2138? The Yagarto that I have states newlib 1.19, but when I look through the package, I only find a newlib.h file? Many thanks in advance! Regards, Staffan
Hello, Many thanks. I find a _sbrk_r, but no _sbrk? The stub I created earlier looks like this (was actually based on a _sbrk_r from Aeolus Development): void * _sbrk( struct _reent *_s_r, ptrdiff_t nbytes) { char *base; /* errno should be set to ENOMEM on error */ if (!heap_ptr){ /* Initialize if first time through. */ heap_ptr = end; } base = heap_ptr; /* Point to end of heap. */ heap_ptr += nbytes; /* Increase heap. */ return base; /* Return pointer to start of new heap area. */ } It didn't work out so well. The syscalls.c file, does it go into newlib? Is there any place to look for a makefile where libnewlib is generated. I'm not very familiar with these things so any hints are highly appreciated. Also, if there are any suggestions as to how one can figure out what functions a given lib-file provides (and even better, from what files it's been compiled!), that would be great! In my (very small) experience, one includes header files with certain names, but is then expected to link with libraries having different names --- is one supposed to have divine inspiration somewhere or is there a method to find out what libraries that are to be used? Regards, Staffan
Staffan B. wrote: > Hello, > > Many thanks. I find a _sbrk_r, but no _sbrk? _sbrk_r should be defined in the libc (newlib). It calls _sbrk which needs to be defined by the user. In the newlib's documentation ( http://sourceware.org/newlib/libc.html ) this example is given:
1 | caddr_t sbrk(int incr) { |
2 | extern char _end; /* Defined by the linker */ |
3 | static char *heap_end; |
4 | char *prev_heap_end; |
5 | |
6 | if (heap_end == 0) { |
7 | heap_end = &_end; |
8 | }
|
9 | prev_heap_end = heap_end; |
10 | if (heap_end + incr > stack_ptr) { |
11 | write (1, "Heap and stack collision\n", 25); |
12 | abort (); |
13 | }
|
14 | |
15 | heap_end += incr; |
16 | return (caddr_t) prev_heap_end; |
17 | }
|
>The stub I created earlier > looks like this (was actually based on a _sbrk_r from Aeolus > Development): > > void * _sbrk( > struct _reent *_s_r, > ptrdiff_t nbytes) > ... This is the interface for an reentrant function with the name of the stub-function. > It didn't work out so well. Hmm, so it did work somehow? More information needed here. > The syscalls.c file, does it go into newlib? It usually just "go" into your project. Compile the file and link the generated object-code with the other object code. Just as i.e. main.c or uart.c or ... > Is there any place to look > for a makefile where libnewlib is generated. I'm not very familiar with > these things so any hints are highly appreciated. Also, if there are any > suggestions as to how one can figure out what functions a given lib-file > provides (and even better, from what files it's been compiled!), that > would be great! You may read the GNU binutils documentation, esp. on the tools nm and objdump. > In my (very small) experience, one includes header files > with certain names, but is then expected to link with libraries having > different names --- is one supposed to have divine inspiration somewhere > or is there a method to find out what libraries that are to be used? I don't think this is related to the problem. Here a function (_sbrk_r) of the libc (newlib) expects a support function (_sbrk). There is no need for an extra library, just define the system-calls as functions with the interfaces given in the newlib-documentation. Hope this helps, Martin
Hello, Thanks for all the links! I have tried a couple of ways of including the _sbrk.c. Should have realized that the copy of _sbrk_r wouldn't work as a stub for _sbrk... The compiling part naturally worked, but when I later downloaded the code and tried to get it running, it just hung. Debugging didn't give much of insight since I just ended up in an UNDEF after leaving a function call (that itself seemed to have worked well). I have also tried the code snippet you suggested, but it misses the definition of stack_ptr and I couldn't find a clear match. My latest attempt has been to use the syscalls.c from the file LPC2138_Test_IIC.zip. I have attached it as a file here. It seems to perhaps be providing what I'm looking for, but it has some oddities that my compiler can't handle. Example: ===== int isatty (int fd) { return 1; fd = fd; } ===== Several of these "var = var" exist in the code and it seems to be preventing compilation. Any clues why this is done and what to do to get by? Regards, Staffan
"it seems to be preventing" should result in a clear arror message from the compiler. If not, there is no problem. As "var = var" is prefectly valid C-Code, there should be no error. I guess, that this line has been put there to prevent an "unused argument" warning, but as is is placed after the return, there could be an "unreachabel code" warning instead. Anyhow, read the error messages, this will help you to splve any problems. Oliver
Hello, You're right. I compile using Eclipse (Indigo) and in the "Problems" tab, I get error messages like: Description Resource Path Location Type Assignment to itself 'm = m' syscalls.c /test1/LPC2138_Test_IIC line 457 Code Analysis Problem This is apparently not an error, but why does Eclipse consider it to be so? Anyways, with this known, I managed to get the file compiled (other stupid mistakes made the linker missing the file - the object file ended up in the wrong directory). The code can now be linked (syscalls.o at the absolute end of the set of files --- started out at the beginning before crt.o, not a good idea) without errors and I can download the code to the eval board. However, I still get the same error as before. Being a little bit more observant, I notice that the error occurring is a Prefetch Abort (instruction fetch memory fault, interrupt vector mem location 0xc in LPC2138). When running the debugger, I consistently get the same result and I've tried on two different eval boards so I guess there is something strange in the code. What I also notice is that the debugger 'looses track'. The calling hierarchy is shown (starting with main() on top, showing the different functions that are part in the 'calling tree' to get the the current code. After a while, when returning from a function call, the top level (starting with main()) 'disappears' and fairly quickly (not so many levels), the top level is changed from known location to somewhere way off in memory (0x1880e7f8 - there is no code whatsoever there) and when returning to this 'calling function', I get a PAbt interrupt - perhaps not so strange. When being in the function just below this strange location, I continuously get warnings like the following for each line of code that is executed: Warn : memory read caused data abort (address: 0x1880e7f8, size: 0x4, count: 0x1) I have tried to set a breakpoint in the sbrk function, but it seems for some reason that breakpoints are disabled so there is no easy way to figure out who has been calling. I'm rather clueless as to what to do except that I guess it still in some way is related to the syscalls/sbrk. Any clues would be highly appreciated! Regards, Staffan
Eclipse has an integrated Code Analysis Funktion, which creates more confusion than real benefit. You can disable this in the preferences. Oliver
The check for stack-heap-collision can be removed from the newlib example. Sorry, should have removed it after copy/paste to avoid confusion. Check the value for the start-of-heap in the map-file. The symbol used in the newlib-example is _end. So check your linker-script if _end is defined there and check the value in the map-file. Maybe another label is used (end has been shown in a previous post, may also be called __end or _end__ or __heap_start_) Just make sure the used label is hold the correct value for start-of-heap. Maybe the name has been used elsewhere in the code. Esp. if "provide" is used in the linker-script the linker will not complain about a missing symbol but will also not set the correct value. Show your linker-script and the map-file if you need more support. Also check that there are several kBytes of RAM "free" for the heap. Malloc may request heap-space in portions of 4 kBytes depending on the configuration of the newlib (4KiB is default IRC). It's difficult to help without further information. Maybe the heap just overwrites data/bss and/or one of the stacks, maybe it's an alignment problem, maybe not enough free RAM. Side-notes: - With a correct linker-script the order of object-file-names given to the linker should not matter. It's only important that the exception-table is assigned ot the correct location. A good approach is an extra section for the table (using .section and ASM) and to force this section to the address where the core looks for it by using the section-name of in the linker script (with KEEP when using unused-code-removal). - I have often used expressions like var=var; to avoid unused variable warnings from the compiler. But it seems that the method now causes the Eclipse and/or newer gcc (can't remember which) to give an self-assign-warning. Replacing var=var; by (void)var; should solve this.
Hello, Clearly, I get more information than I almost can handle --- many many thanks for taking your time with this! Not sure I actually do the what you suggest, but anyways: I took a look at my linker script (attached as 2138_demo.cmd) and it seems to only be providing _end. Actually, when reviewing it, it seems like there has been issues with sbrk also in arm-elf (I've added a note at least, long ago...). Looking in main.map (not attached since it is 187kB), it looks like this: ... .bss 0x40004d0c 0x0 c:\Programs\Yagarto\lib\gcc\arm-none-eabi\4.6.2\libgcc.a(_arm_fixsfsi.o) .bss 0x40004d0c 0x0 c:\Programs\Yagarto\lib\gcc\arm-none-eabi\4.6.2\libgcc.a(_arm_fixunssfsi .o) COMMON 0x40004d0c 0x100 c:\Programs\Yagarto\arm-none-eabi\lib\libg.a(lib_a-gdtoa-gethex.o) 0x40004d0c __hexdig COMMON 0x40004e0c 0x4 c:\Programs\Yagarto\arm-none-eabi\lib\libg.a(lib_a-reent.o) 0x40004e0c errno 0x40004e10 . = ALIGN (0x4) 0x40004e10 _bss_end = . 0x40004e10 _end = . 0x40004e10 PROVIDE (end, .) LOAD crt.o LOAD main.o LOAD adcAD7686.o ... Hmm, RAM could definitely be an issue I think. I have 32k available, but probably consume quite a bit of that (one reason for choosing the LPC2138 was the amount of flash and RAM). According to the spec, ram will be in the address space 0x4000 0000 - 0x4000 7fff. According to the part from main.map above, _end occurrs at 0x4000 4e10 --- does it mean there is space from 4e10 to 7fff free? In that case, there should be sufficient amount? Just changed the var=var to (void) var and now there are no complaints there, thanks! Strange that eclipse should complain... Changing the preferences could perhaps be better since the code in itself is correct (thanks Oliver) - now I know why it's there though. ---OOPS, just noticed one thing. At the very end of linker script 2138_demo.cmd, there is the line PROVIDE ( end = . ); Should this be PROVIDE ( _end = .); (with underscore)? You mention that PROVIDE may turn off some checking? You pretty much lost me with the comments at the end on the linker script. If there is a sample file I can look at, that would be great (my script apparently was sensitive to what order the makefile listed the object files...) Again, many thanks for all comments and help! Regards, Staffan
Hello, Just tried changing the last line of 2138_demo.cmd to PROVIDE ( _end = . ); (with underscore), but it didn't change anything. Same kind of error still. Regards, Staffan
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.