This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: newlib port problem (stdio and malloc)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]