How to use newlib?

thanks for your kind help.

There is also a _write function defined in the libc.a(syscalls.o). So if i write my own _write function there is an error.

Please correct me if i’m wrong. Does defining personal _write and _read funtions mean that i have to recompile the whole newlib. Or is there any other possibility?

Thanks a lot,

rain

no.

But if you add libraries using

lib\libc.a lib\libm.a libgcc.a

that can be the problem,

The prefered way is

-lc -lm -lgcc

Sometimes a path must be specified with -L $(PATH TO LIBRARIES) -lname

The linker wil subsitute -lname with libname.a or libname.so

and it also knows that this is a library so only load the functions used from other parts of the code.

The exact behaviour of linkers is deep magic.

If you define your own verison of library files with the same names and calling parametrs , then they are uesd insted of the library versions. So the library must not be rebuilt.

But your versions must be built with the same, or at least compatible compiler, flags as the library since they will simoetimes be called by other functions in the library.

Simply : your vesrion replaces the library version and thy must work together.

How can we now it i works. Test, try, debug and send in different data. :slight_smile:

Debugging and testing is when we really learn about both the underlying system, our code and the problem we try to solve.

regards,

Magnus

Dear mlu,

Thanks for your hints.

now i tried the following:

int _write(int file, char *ptr, int len){
    int todo;
      	AT91PS_DBGU pDBGU = AT91C_BASE_DBGU;
 
    for (todo = 0; todo < len; todo++) {
     	while(!(pDBGU->DBGU_CSR & AT91C_US_TXRDY)) ; 
   		pDBGU->DBGU_THR= *ptr++;
    }
    return len;
}

And this is the output - similar to the error message i got before:

make -k all 
...compiling debug.c
arm-elf-gcc -I./ -c -fno-common -O0 -g debug.c
...linking
arm-elf-ld -v -Map main.map -Tdemo_at91sam7_blink_flash.cmd -o main.out crt.o	main.o lcd.o lowlevelInit.o debug.o -L C:\Programme\ARM_TOOLCHAIN\yagarto\arm-elf\lib  -lc -lm -lgcc
GNU ld version 2.17
C:\Programme\ARM_TOOLCHAIN\yagarto\arm-elf\lib\libc.a(syscalls.o): In function `_write':
../../../../../../newlib-1.14.0/newlib/libc/sys/arm/syscalls.c:333: multiple definition of `_write'
debug.o:I:\SOFTWARE\5.Semester\ARM_Projects\demo_at91sam7_blink_flash/debug.c:34: first defined here
arm-elf-ld: Warning: size of symbol `_write' changed from 148 in debug.o to 112 in C:\Programme\ARM_TOOLCHAIN\yagarto\arm-elf\lib\libc.a(syscalls.o)
make: *** [main.out] Error 1
make: Target `all' not remade because of errors.

Do i have to add any other compiler / or linker flags so that my version of _write is used instead of newlib one’s?

Once again,

Thanks a lot

rain

Hello rain,

this should be your solution, I have test it here with an lpc2294 board.

How to solve the problem with newlib from YAGARTO?

Therefore you must know that the libc.a for YAGARTO is created

with the syscalls function. Syscalls provide some functionality for

malloc printf and more.

To overwrite we need a libc.a without the syscalls functionality.

The reason why you get the error with the _write is that this

function is in syscalls.

Now we remove syscalls from the libc.a I have installed YAGARTO at

d:\Compiler, therefore I will find libc.a at the following location:

d:\Compiler\yagarto\arm-elf\lib\libc.a

Go inside the d:\Compiler\yagarto\arm-elf\lib directory

and make a copy of the libc.a for example: libc_with_syscalls.a.

Use now the following command to remove the syscalls from libc.a:

arm-elf-ar -d libc.a syscalls.o

Now you have a libc.a library without the syscalls functionality.

The disavantage is here, you must write this functionality by yourself.

If you compile your program now, you will get a lot of warnings.

Try to use this syscalls.c file and add it to your project.

=============================================================

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>

extern int DebugWrite (const void *buffer, int len);

#define STDIN_FILENO 0 /* standard input file descriptor */

#define STDOUT_FILENO 1 /* standard output file descriptor */

#define STDERR_FILENO 2 /* standard error file descriptor */

void _exit (int n)

{

while(1)

{

n = n;

}

}

int _stat(char *file, struct stat *st) {

return (0);

}

int _fstat (int fd, struct stat * st)

{

if (fd == STDOUT_FILENO)

{

memset(st, 0, sizeof (* st));

st->st_mode = S_IFCHR;

st->st_blksize = 1024;

return 0;

}

else

{

DebugWrite(“Error: _fstat\r\n”, 15);

return(-1);

}

}

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. */

exit(1);

return (caddr_t) -1;

}

heap_end += incr;

return (caddr_t) prev_heap_end;

}

int isatty (int fd)

{

return(1);

}

int _lseek (int fd, int ptr,int dir)

{

return (-1);

}

int _open(const char *name, int mode)

{

return(-1);

}

int _close(int fd)

{

return(0);

}

int _write(int fd, const void *data, unsigned int count)

{

if (fd == STDOUT_FILENO)

{

count = DebugWrite(data, count);

}

else

{

DebugWrite(“Error: _write\r\n”, 15);

count = -1;

}

return(count);

}

int _read(int fd, void *buffer, unsigned int count)

{

return(-1);

}

=====================================================================

Inside the _write function I use DebugWrite, therefore

your application must now provide a DebugWrite function like this:

int DebugWrite (const void *buffer, int len);

Here you get the buffer of the string to write and the len.

You must return the len you have wrote.

int DebugWrite (const void *buffer, int len)

{

int c = len;

char cp = (char)buffer;

while(c–)

{

output(cp++); / You must write this function */

}

return len;

}

Best regards,

Michael

Try adding -lnosys after -lc

/Magnus

Dear Michael,

wow - thanks a lot not i got it working.

I want to thank all of those who contributed to this topic.

Greetings from vienna,

rain

Hello!

This thread was a great help for me understanding the role of the newlib and the syscalls.c file. Thank you very much for sharing knowledge.

Nevertheless, I still got a problem: The end of a string is always printed twice. See e.g.:

Hello Hello!

o!

1111111111111

111

Hello Hello!

o!

dec=123123 hex=1e0f3

hex=1e0f3

Hello, can you see me?

you see me?

e?

This text I produced with my at91sam7x-ek board following this thread and this piece of code:

printf("Hello Hello!\r\n");
printf("1111111111111\r\n");
printf("Hello Hello!\r\n");
printf("dec=%d hex=%x\r\n", num, um);

I tracked down the error and found out, that after each call to DebugWrite, the fflush function is called and it makes another call to DebugWrite outputting some old data from the buffer.

Thanks for help and comments.

Armin

Okay, I was able to solve my problem:

I didn’t return the number of printed characters correctly; I missed line

return len;

in function DebugWrite.

I don’t know why the compiler didn’t complain…