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)


Hi Nick,

    I got it. Thank you very much!
    Maybe I need to study "Porting and Using Newlib in Embedded Systems" first.

Zhang Hua

----- Original Message ----- 
From: "Nick THOMPSON" <nickthompson@agere.com>
To: "MBT:Zhang Hua" <zhanghua@megabyte.com.cn>
Cc: <newlib@sources.redhat.com>
Sent: Thursday, June 10, 2004 12:10 AM
Subject: Re: newlib port problem (stdio and malloc)


> Zhang Hua,
> 
> No, don't remove syscalls.c, you will need it to complete the newlib
> build. But If you define new functions in your application, with the
> same names and parameters as all the non-static functions (forget about
> the static swi functions) in syscalls.c, then the linker will not
> include any of the functions from syscalls.c - effectively ignoring it
> completely.
> 
> This allows you to redefine those functions without changing the newlib
> build at all.
> 
> So:
> 
> 1) Build newlib with syscalls.c included as normal.
> 
> 2) You can override the syscalls.c functions with new ones in your
> application. This works as long as you redefine all the non-static
> function in a newlib C file. The linker then doesn't have to look in
> libc.a to find the functions as they are already defined by your
> application. If you leave one or more non-static functions in a C file
> not redefined, the linker will track them down and include _all_ the
> functions in the C file, some of which will then clash with your
> definitions. Therefore use stubs for those functions you don't care
> about but have to define.
> 
> Nick.
> 
> 
> On Wed, 2004-06-09 at 11:59, MBT:Zhang Hua wrote:
> > Hello Nick,
> > 
> >     I think I don't understand you completely.
> > 
> >    1.  Do you mean when we use -DREENTRANT_SYSCALLS_PROVIDED option, we can remove "\newlib\libc\sys\arm\syscalls.c" and then compile the newlib? 
> >     # I just try to remove it, and there is error when compile.
> >    
> >     2. If we can do step 1, then when we link the newlib, the non-static functions in "syscalls.c" are replaced by the functions in our applications?
> >     # That is, can I even use the resource in my own application to implement the non-static functions?
> > 
> > Thank you very much
> > 
> > Zhang Hua
> >     
> > ----- Original Message ----- 
> > From: "Nick THOMPSON" <nickthompson@agere.com>
> > To: "MBT:Zhang Hua" <zhanghua@megabyte.com.cn>
> > Cc: <newlib@sources.redhat.com>
> > Sent: Wednesday, June 09, 2004 5:02 PM
> > Subject: 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]