newlib port problem (stdio and malloc)
Nick THOMPSON
nickthompson@agere.com
Wed Jun 9 11:00:00 GMT 2004
Zhang Hua,
I have just done this for ARM also. The method I used was to leave
syscalls.c alone and create a new file in my application code that
replaces all the non-static functions in syscalls.c. So I started with
stubs for all of:
int _system (const char *s);
int _rename (const char *, const char *);
int isatty (int);
clock_t _times (struct tms *);
int _gettimeofday (struct timeval *, struct timezone *);
void _raise (void);
int _unlink (void);
int _link (void);
int _stat (const char *, struct stat *);
int _fstat (int, struct stat *);
caddr_t _sbrk (int);
int _getpid (int);
int _kill (int, int);
void _exit (int);
int _close (int);
int _open (const char *, int, ...);
int _write (int, char *, int);
int _lseek (int, int, int);
int _read (int, char *, int);
int _close_r (struct _reent *r, int file);
_ssize_t _write_r (struct _reent *r, int file, const void *ptr,
size_t len);
_off_t _lseek_r (struct _reent *r, int file, _off_t off, int dir);
_ssize_t _read_r (struct _reent *r, int file, void *ptr, size_t
len);
int _fstat_r (struct _reent *r, int file, struct stat *fd);
e.g., one I don't use:
int isatty (int fd)
{
return 0;
}
Then for write I have:
#define FH_OFFSET 20
#define FH_CONSOLE 1
remap_handle (int fh)
{
if (fh == STDIN_FILENO)
return FH_CONSOLE;
if (fh == STDOUT_FILENO)
return FH_CONSOLE;
if (fh == STDERR_FILENO)
return FH_CONSOLE;
return fh - FH_OFFSET;
}
int _write (int file, char *ptr, int len)
{
// not called by newlib - but I use it
_sys_write(remap_handle(file), ptr, len);
return len;
}
_ssize_t _write_r (struct _reent *r, int file, const void *ptr, size_t
len)
{
_sys_write(remap_handle(file), ptr, len);
return len;
}
extern int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned
len)
{
if ((fh >= 0) && (fh <= 2)) { // possible range of FH_CONSOLE
while(len--) {
_OUTCHR(fh, *buf++); // Write one char to UART
}
return(0); // remaining chars is ALWAYS zero
} else {
return(-1); // I don't support other devices yet
}
}
When building newlib I had:
CFLAGS_FOR_TARGET = -O2 $(CFLAGS) -DMALLOC_PROVIDED \
-DREENTRANT_SYSCALLS_PROVIDED
In the Makefile, so puts, printf, etc all end up calling my _write_r.
Since I have also defined _sbrk, I could define for myself exactly what
memory it manages. In fact in my app, I have my own OS malloc routines
(as you can see from my CFLAGS_FOR_TARGET), so I haven't bothered with
_sbrk.
Since I have defined new versions of all non-statics in syscalls.c, the
newlib file is left out of the final link. This allows me to build a
stock newlib, with no changes (except for the tweak in Makefile).
Hope that helps.
Nick.
On Wed, 2004-06-09 at 02:44, MBT:Zhang Hua wrote:
> Hello everyone:
>
> I have 2 questions when port the newlib to the ARM platform:
>
> 1. I need use stdio to display debug information. The debug information is output by the UART.
> Now I modify the function "int _swiwrite ( int file, char * ptr, int len)" in "\newlib-1.10.0\newlib\libc\sys\arm\syscalls.c".
> This function is modified something like this:
> for (i=0; i<len; i++)
> {
> while(1)
> {
> if (UART can send data)
> {
> break;
> }
> }
> send one byte
> }
>
> Is it OK?
> When I use stdio function, I find it's not a good way to modify like this.
> Any suggestion?
>
> 2. I need use malloc/free to manage memory. When I check the function "caddr_t _sbrk (int incr)" in "\newlib-1.10.0\newlib\libc\sys\arm\syscalls.c", I find _sbrk() tries to manage the memory between [end, sp).
> Although it's ok to manage like this, I want to know why _sbrk() on the ARM system doesn't try to manage a fixed range of memory? For example, manage the memory between [end, end + MEMORY_SIZE).
>
> Thanks in advance
>
> Zhang Hua
More information about the Newlib
mailing list