cancel
Showing results for 
Search instead for 
Did you mean: 

newlib not calling _write_r

michael8
Associate II
Posted on April 15, 2009 at 16:40

newlib not calling _write_r

3 REPLIES 3
michael8
Associate II
Posted on May 17, 2011 at 09:58

I'm trying to use fprintf to direct i/o to my UARTs, SD card, LCD, etc suing the FILE ptr to indicate which device to access. I've provided my own syscalls (_write_r, _open_r, etc).

The problem is that fprintf calls the stadard _fwrite_r instead of my _write_r. Simple printf() calls _putc_r. Neither _fwrite_r or _putc_r are in syscalls.c, and I haven't overridden them. My code crashes because both expect a valid __REENT structure, which I haven't provided.

How do I either:

a) get fprintf to call _write_r instead of _fwrite_r or,

b) provide _fwrite_r a minimal __REENT structure, so it stops throwing data abort exceptions?

c) find a printf-like function that calls _write_r instead of _fwrite_r?

I don't want or need reentrancy, but can't find a way around needing a valid __REENT structure. My only other option seems to be seriously hacking newlib, to replace all the fxxxx i/o functions (fopen, fread, fwrite, etc) with my own. That doesn't sound like the right thing to do.

Ideas?

Thanks!

sjo
Associate II
Posted on May 17, 2011 at 09:58

normally you would override the following:

int _write_r(void *reent, int fd, char *ptr, size_t len)

{

return len;

}

you will also need a valid sbrk, eg.

register char *stack_ptr asm (''sp'');

caddr_t _sbrk_r(void *reent, size_t incr)

{

extern char end asm (''end''); // Defined by the linker

static char *heap_end;

char *prev_heap_end;

if( heap_end == NULL )

heap_end = &end;

prev_heap_end = heap_end;

if(( heap_end + incr ) > stack_ptr )

{

/* Some of the libstdc++-v3 tests rely upon detecting

out of memory errors, so do not abort here. */

//write( 1, ''sbrk: Heap and stack collision\n'', 32 );

//abort();

exit(1);

//errno = ENOMEM;

return (caddr_t) -1;

}

heap_end += incr;

return (caddr_t) prev_heap_end;

}

what version of newlib are you using?

Cheers

sjo

michael8
Associate II
Posted on May 17, 2011 at 09:58

Thanks, sjo.

Since I posted I've become pretty well educated on a number of things, including newlib internals, syscall.c functions, and ASM start-up code.

My real problem turned out to be that I had disabled the start-up code that initialized static variables from ROM (while debugging an interrupt issue). Newlib structures like _impure_ptr and impure_data weren't getting initialized, so newlib was failing internally due to bad pointer data. Restoring the copy code fixed the newlib calls.

I've since implemented Bill Gatliff's scheme for providing device-specific i/o functions through a function table -

http://neptune.billgatliff.com/newlib.html

. It's great for devices like UARTs, that support a single stream. I'm finding it a little awkward when trying to support devices that themselves support multiple files (like SD cards).

Much thanks for the feedback!

Regards,

m1ke0