Re: [arm-gnu] With arm-none-eabi atoi and strtol don't work[SOLVED]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [arm-gnu] With arm-none-eabi atoi and strtol don't work[SOLVED]



Gene Smith wrote, On 07/03/2009 04:15 PM:
For some reason when I build a project for arm7tdmi everything seems to
build and work except calls to atoi or strtol don't decode the string to
an integer but always return 0. For example if the string is "128" the
return value is 0 for atoi or strtol.

Atoi or strtol works fine for an arm cortex M3 projects.

I compiled the newlib code for strtol inline with my program and I can
see with the debugger that isdigit() always returns false. If I fake
isdigit to return 1 for the characters in the string "128" it works and
strtoul returns 128 as it should.

It appears that the value of the pointer __ctype_ptr__ at 0x20000008 in
ram is zero. So when isdigit() macro in ctypes.c attempts to access the
lookup table for the ascii value index to determine the "ctype", e.g.,
_N, it never detects a "digit" character type.

I realize this is a bit sketchy and more information is probably needed,
but any suggestions on where to look or what I could be doing wrong
would be appreciated.

The code is based on the str71x_demo1 project found here:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_str.html

Thanks,
-gene

I found the problem. The link script for the above demo project that I blindly used contains this:

MEMORY
{
	XCODE (rx) : ORIGIN = 0x60000000, LENGTH = 0x00400000
	CODE (rx)  : ORIGIN = 0x40000000, LENGTH = 0x00040000
	XDATA (rw) : ORIGIN = 0x62000000, LENGTH = 0x00400000
	DATA (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00010000
}

But the str712 demo board has no external (X) memory. The SECTIONS below does not explicitly define the ARM.exidx section. I suppose that when the linker comes across this section and tries to locate it that it uses the first line in the MEMORY defintion and puts it at 0x60000000 which is non-existent ROM. Then what really messes thing up is that the .data section, which comes after ARM.exidx, is loaded (LMA) also at 0x60000000 at non-existent external memory. The startup code then copies the data at 0x60000000 to .data in internal RAM which zero's the initialized data, including the look-up tables used by strtol.

Here's how the sections look when bad:

Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000086b8  40000000  40000000  00008000  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .rodata       00000be0  400086b8  400086b8  000106b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .ARM.exidx    00000008  60000000  60000000  00018000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .data         00000850  20000000  60000008  00020000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  4 .bss          00009d1c  20000850  60000858  00020850  2**2
:

My load address for .data is specified like this:
	:
	PROVIDE (etext = .);
	.data : AT (_etext)
	:
so it is just following where the previous text section was (incorrectly put at 0x60000000).

An easy fix for this, with minimal change to the demo linker script, is to just change the order of the MEMORY statements:

MEMORY
{
	CODE (rx)  : ORIGIN = 0x40000000, LENGTH = 0x00040000
	DATA (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00010000
	XCODE (rx) : ORIGIN = 0x60000000, LENGTH = 0x00400000
	XDATA (rw) : ORIGIN = 0x62000000, LENGTH = 0x00400000
}

This keeps the .ARM.exidx in the CODE (interal ROM) section and does not corrupt the initialization of the .data section:

Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000086b8  40000000  40000000  00008000  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .rodata       00000be0  400086b8  400086b8  000106b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .ARM.exidx    00000008  40009298  40009298  00011298  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .data         00000850  20000000  400092a0  00018000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  4 .bss          00009d1c  20000850  40009af0  00018850  2**2
:

I am not sure what .ARM.exidx (and possibly .ARM.extab) do but I think it (or they) should have explicit section defined in the link script. However, I still don't have them there. But, with this change to MEMORY order definition, the atoi and strtol type functions now work. (I am surprised that more did not break since *all* the initialized data was being zeroed.)