Standart vs Runtime C library

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, please what is the difference between the two libraries?

Many times, I found some libraries for AVR or even x86 OS than claims to be runtime or standart library, but it seems to me that they are basically the same.

If I think not just about AVRs and other MCUs, but lets say C language for say Windows OS, even standart library has to have Os specific code, for screen printing for example. But many articles state that only Runtime library in vendor specific.

I am sorry to messed things up with Windows programing, but I am really getting lost in these terms, and you guys always helped me a lot. Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not think that you will find this distinction between "standard" and " runtime" with most 8 and 16 bit micros. Here, everything is runtime.

Yes, you have the library that provides "standard" c functions but that is characteric of c, generally. You >>might<< call peter fleury's library or elm-chan FAT library as runtime, but that term seems rarely used. They are just "libraries".

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In GCC parlance the C RunTime (CRT) is the piece of code bound onto the start/end of all C programs (even though no actual "library" calls may be made). If you build an empty program (though I'm allowing myself the luxury of one .data and one .bss variable to illustrate that part of the CRT):

unsigned long ul = 0xDEADBEEF;
char buffer[10];

int main(void) { 
	while(1);
}

then the generated program (for tiny13) is:

===========================================================================
Disassembly of section .text:

00000000 <__vectors>:
   0:	09 c0       	rjmp	.+18     	; 0x14 <__ctors_end>
   2:	21 c0       	rjmp	.+66     	; 0x46 <__bad_interrupt>
   4:	20 c0       	rjmp	.+64     	; 0x46 <__bad_interrupt>
   6:	1f c0       	rjmp	.+62     	; 0x46 <__bad_interrupt>
   8:	1e c0       	rjmp	.+60     	; 0x46 <__bad_interrupt>
   a:	1d c0       	rjmp	.+58     	; 0x46 <__bad_interrupt>
   c:	1c c0       	rjmp	.+56     	; 0x46 <__bad_interrupt>
   e:	1b c0       	rjmp	.+54     	; 0x46 <__bad_interrupt>
  10:	1a c0       	rjmp	.+52     	; 0x46 <__bad_interrupt>
  12:	19 c0       	rjmp	.+50     	; 0x46 <__bad_interrupt>

00000014 <__ctors_end>:
  14:	11 24       	eor	r1, r1
  16:	1f be       	out	0x3f, r1	; 63
  18:	cf e9       	ldi	r28, 0x9F	; 159
  1a:	cd bf       	out	0x3d, r28	; 61

0000001c <__do_copy_data>:
  1c:	10 e0       	ldi	r17, 0x00	; 0
  1e:	a0 e6       	ldi	r26, 0x60	; 96
  20:	b0 e0       	ldi	r27, 0x00	; 0
  22:	ee e4       	ldi	r30, 0x4E	; 78
  24:	f0 e0       	ldi	r31, 0x00	; 0
  26:	02 c0       	rjmp	.+4      	; 0x2c <.do_copy_data_start>

00000028 <.do_copy_data_loop>:
  28:	05 90       	lpm	r0, Z+
  2a:	0d 92       	st	X+, r0

0000002c <.do_copy_data_start>:
  2c:	a4 36       	cpi	r26, 0x64	; 100
  2e:	b1 07       	cpc	r27, r17
  30:	d9 f7       	brne	.-10     	; 0x28 <.do_copy_data_loop>

00000032 <__do_clear_bss>:
  32:	10 e0       	ldi	r17, 0x00	; 0
  34:	a4 e6       	ldi	r26, 0x64	; 100
  36:	b0 e0       	ldi	r27, 0x00	; 0
  38:	01 c0       	rjmp	.+2      	; 0x3c <.do_clear_bss_start>

0000003a <.do_clear_bss_loop>:
  3a:	1d 92       	st	X+, r1

0000003c <.do_clear_bss_start>:
  3c:	ae 36       	cpi	r26, 0x6E	; 110
  3e:	b1 07       	cpc	r27, r17
  40:	e1 f7       	brne	.-8      	; 0x3a <.do_clear_bss_loop>
  42:	02 d0       	rcall	.+4      	; 0x48 
44: 02 c0 rjmp .+4 ; 0x4a <_exit> 00000046 <__bad_interrupt>: 46: dc cf rjmp .-72 ; 0x0 <__vectors> 00000048
: unsigned long ul = 0xDEADBEEF; char buffer[10]; int main(void) { 48: ff cf rjmp .-2 ; 0x48
0000004a <_exit>: 4a: f8 94 cli 0000004c <__stop_program>: 4c: ff cf rjmp .-2 ; 0x4c <__stop_program>

All of the code you see there, apart from the actual main():

00000048 
: int main(void) { 48: ff cf rjmp .-2 ; 0x48

is the C RunTime (CRT). It provides a (R)JMP at 0 followed by a vector table. Then the code that the reset jump arrives at clears R1 then SREG and sets the stack pointer. Following that is a loop to copy the initial value of any .data variables (0xDEADBEEF used to initialise 'ul') from code flash to the start of SRAM. This is followed by the loop that wipes any .bss variables (the 10 bytes of buffer[]) to 0x00. Finally there is a "(R)CALL main" which is what actually enters the program you wrote. If I had not written while(1) then main() would have returned and then hit the (R)JMP _exit and which point it disables interrupts (CLI) and then executes a tight loop at _stop_program.

That is the C RunTime library. There's a different version built for every model of AVR:

C:\WinAVR-20100110\avr\lib>dir crt*.o /s
 Volume in drive C is ACER
 Volume Serial Number is C6B0-75D7

 Directory of C:\WinAVR-20100110\avr\lib

06/01/2010  19:10             1,380 crt86401.o
06/01/2010  19:10             1,424 crtc8534.o
06/01/2010  19:10             1,072 crts1200.o
06/01/2010  19:10             1,572 crts2313.o
06/01/2010  19:10             1,244 crts2323.o
06/01/2010  19:10             1,696 crts2333.o
06/01/2010  19:10             1,244 crts2343.o
06/01/2010  19:10             1,672 crts4414.o
06/01/2010  19:10             1,696 crts4433.o
06/01/2010  19:10             1,840 crts4434.o
06/01/2010  19:10             1,672 crts8515.o
06/01/2010  19:10             1,840 crts8535.o
06/01/2010  19:10             1,108 crttn11.o
06/01/2010  19:10             1,152 crttn12.o
06/01/2010  19:10             1,528 crttn13.o
06/01/2010  19:10             1,272 crttn15.o
06/01/2010  19:10             1,244 crttn22.o
06/01/2010  19:10             1,908 crttn2313.o
06/01/2010  19:10             1,824 crttn24.o
06/01/2010  19:10             1,740 crttn25.o
06/01/2010  19:10             1,612 crttn26.o
06/01/2010  19:10             1,908 crttn261.o
06/01/2010  19:10             1,152 crttn28.o
06/01/2010  19:10             1,840 crttn44.o
06/01/2010  19:10             1,756 crttn45.o
06/01/2010  19:10             1,924 crttn461.o
06/01/2010  19:10             1,840 crttn84.o
06/01/2010  19:10             1,756 crttn85.o
06/01/2010  19:10             1,924 crttn861.o
              29 File(s)         45,840 bytes

 Directory of C:\WinAVR-20100110\avr\lib\avr25

06/01/2010  19:10             1,380 crt86401.o
06/01/2010  19:10             2,260 crta6289.o
06/01/2010  19:10             1,528 crttn13.o
06/01/2010  19:10             1,528 crttn13a.o
06/01/2010  19:11             1,908 crttn2313.o
06/01/2010  19:11             1,992 crttn2313a.o
06/01/2010  19:11             1,824 crttn24.o
06/01/2010  19:11             1,824 crttn24a.o
06/01/2010  19:11             1,740 crttn25.o
06/01/2010  19:11             1,908 crttn261.o
06/01/2010  19:11             1,908 crttn261a.o
06/01/2010  19:11             2,008 crttn4313.o
06/01/2010  19:11             1,796 crttn43u.o
06/01/2010  19:11             1,840 crttn44.o
06/01/2010  19:11             1,840 crttn44a.o
06/01/2010  19:11             1,756 crttn45.o
06/01/2010  19:11             1,924 crttn461.o
06/01/2010  19:11             1,924 crttn461a.o
06/01/2010  19:11             1,964 crttn48.o
06/01/2010  19:11             1,840 crttn84.o
06/01/2010  19:11             1,756 crttn85.o
06/01/2010  19:11             1,924 crttn861.o
06/01/2010  19:11             1,924 crttn861a.o
06/01/2010  19:11             1,964 crttn87.o
06/01/2010  19:11             1,964 crttn88.o
              25 File(s)         46,224 bytes

 Directory of C:\WinAVR-20100110\avr\lib\avr3

06/01/2010  19:11             1,704 crt43320.o
06/01/2010  19:11             1,704 crt43355.o
06/01/2010  19:11             1,792 crt76711.o
06/01/2010  19:11             2,568 crtm103.o
06/01/2010  19:11             2,408 crtusb162.o
06/01/2010  19:11             2,408 crtusb82.o
               6 File(s)         12,584 bytes

 Directory of C:\WinAVR-20100110\avr\lib\avr31

06/01/2010  19:12             1,704 crt43320.o
06/01/2010  19:12             2,568 crtm103.o
               2 File(s)          4,272 bytes

 Directory of C:\WinAVR-20100110\avr\lib\avr35

06/01/2010  19:12             2,804 crtm16u2.o
06/01/2010  19:12             2,804 crtm32u2.o
06/01/2010  19:12             2,804 crtm8u2.o
06/01/2010  19:12             2,012 crttn167.o
06/01/2010  19:12             2,408 crtusb162.o
06/01/2010  19:12             2,408 crtusb82.o
               6 File(s)         15,240 bytes

 Directory of C:\WinAVR-20100110\avr\lib\avr4

06/01/2010  19:13             2,468 crt90pwm1.o

For the program I built it was crtt13.o that was used as a result of my -mmcu=attiny13 on the avr-gcc command line. All of those files are built from a single source file:

http://svn.savannah.nongnu.org/v...

Any other code that is linked with a program you build is from the standard library (actually libraries). For example even if you just use some floating point operation:

#include 

int main(void) { 
	while(1) {
		PORTB = 0.7 * PINC;
	}
}

then you can see that this has bound to a whole bunch of _fp_* routines from libm.a which is one of the standard libraries:

D:\test>avr-nm test.elf | grep " T "
00000044 T __bad_interrupt
00000034 T __ctors_end
00000034 T __ctors_start
00000034 T __dtors_end
00000034 T __dtors_start
00000064 T __fixunssfsi
000000c0 T __floatsisf
000000bc T __floatunsisf
0000024e T __fp_inf
0000025a T __fp_nan
00000260 T __fp_pscA
0000026e T __fp_pscB
0000027c T __fp_round
00000136 T __fp_split3
00000146 T __fp_splitA
0000017c T __fp_szero
0000017a T __fp_zero
00000188 T __mulsf3
000001a4 T __mulsf3_pse
000001a0 T __mulsf3x
00000034 T __trampolines_end
00000034 T __trampolines_start
00000000 T __vectors
00800100 T _edata
000002a2 T _etext
0000029e T _exit
00000046 T main

The math routines (the good ones!) are held in libm.a while the majority of "standard" library routines are in libc.a:

C:\WinAVR-20100110\avr\lib>avr-nm libc.a | grep " T"
00000000 T abs
00000000 T __assert
00000000 T bsearch
00000000 T calloc
00000000 T dtoa_prf
00000000 T dtostre
00000000 T dtostrf
00000000 T labs
00000180 T free
00000000 T malloc
00000086 T qsort
000000aa T rand
000000a6 T rand_r
000000b2 T srand
000000b2 T random
000000ae T random_r
000000ba T srandom
00000000 T realloc
00000000 T strtod
00000000 T strtol
00000000 T strtoul
00000000 T abort
00000000 T atof
00000000 T atoi
00000000 T atol
00000000 T div
00000000 T exit
00000000 T __ftoa_engine
00000000 T ldiv
00000042 T longjmp
00000000 T setjmp
00000000 T isascii
00000000 T toascii
00000000 T isalnum
00000000 T __ctype_isfalse
00000004 T __ctype_istrue
00000004 T isalpha
00000006 T islower
00000000 T isupper
00000000 T isdigit
00000000 T isxdigit
00000000 T iscntrl
00000000 T isgraph
00000004 T isprint
00000000 T isspace
00000000 T isblank
00000000 T ispunct
00000000 T tolower
00000000 T toupper
00000000 T strtok_P
00000000 T memchr_P
00000000 T memcmp_P
00000000 T memccpy_P
00000000 T memcpy_P
00000000 T memrchr_P
00000000 T strcasecmp_P
00000000 T strcat_P
00000000 T strchr_P
00000000 T strchrnul_P
00000000 T strcmp_P
00000000 T strcpy_P
00000000 T strcspn_P
00000000 T strlcat_P
00000000 T strlcpy_P
00000000 T strlen_P
00000000 T strncasecmp_P
00000000 T strncat_P
00000000 T strncmp_P
00000000 T strncpy_P
00000000 T strnlen_P
00000000 T strpbrk_P
00000000 T strrchr_P
00000000 T strsep_P
00000000 T strspn_P
00000000 T strstr_P
00000000 T strtok_rP
00000000 T strdup
00000000 T strtok
00000000 T ffs
00000000 T ffsl
00000000 T ffsll
00000000 T memccpy
00000000 T memchr
00000000 T memcmp
00000000 T memcpy
00000000 T memmem
00000000 T memmem_P
00000000 T memmove
00000000 T memrchr
00000000 T memset
00000000 T strcasecmp
00000000 T strcasestr
00000000 T strcasestr_P
00000000 T strcat
00000000 T strchr
00000000 T strchrnul
00000000 T strcmp
00000000 T strcpy
00000000 T strcspn
00000000 T strlcat
00000000 T strlcpy
00000000 T strlen
00000000 T strlwr
00000000 T strncasecmp
00000000 T strncat
00000000 T strncmp
00000000 T strncpy
00000000 T strnlen
00000000 T strpbrk
00000000 T strrchr
00000000 T strrev
00000000 T strsep
00000000 T strspn
00000000 T strstr
00000000 T strtok_r
00000000 T strupr
00000000 T itoa
00000000 T ltoa
00000000 T __mulsi_const_10
00000000 T __mulhi_const_10
00000000 T ultoa
00000000 T utoa
00000000 T clearerr
00000000 T fclose
00000000 T fdevopen
00000000 T feof
00000000 T ferror
00000000 T fgetc
00000000 T fgets
00000000 T fprintf
00000000 T fprintf_P
00000000 T fputc
00000000 T fputs
00000000 T fputs_P
00000000 T fread
00000000 T fscanf
00000000 T fscanf_P
00000000 T fwrite
00000000 T getchar
00000000 T gets
00000000 T printf
00000000 T printf_P
00000000 T putchar
00000000 T puts
00000000 T puts_P
00000000 T scanf
00000000 T scanf_P
00000000 T snprintf
00000000 T snprintf_P
00000000 T sprintf
00000000 T sprintf_P
00000000 T sscanf

There's actually a different libc.a for each of the architecture families:

C:\WinAVR-20100110\avr\lib>dir libc.a /s /b
C:\WinAVR-20100110\avr\lib\libc.a
C:\WinAVR-20100110\avr\lib\avr25\libc.a
C:\WinAVR-20100110\avr\lib\avr3\libc.a
C:\WinAVR-20100110\avr\lib\avr31\libc.a
C:\WinAVR-20100110\avr\lib\avr35\libc.a
C:\WinAVR-20100110\avr\lib\avr4\libc.a
C:\WinAVR-20100110\avr\lib\avr5\libc.a
C:\WinAVR-20100110\avr\lib\avr51\libc.a
C:\WinAVR-20100110\avr\lib\avr6\libc.a
C:\WinAVR-20100110\avr\lib\avrxmega2\libc.a
C:\WinAVR-20100110\avr\lib\avrxmega3\libc.a
C:\WinAVR-20100110\avr\lib\avrxmega4\libc.a
C:\WinAVR-20100110\avr\lib\avrxmega5\libc.a
C:\WinAVR-20100110\avr\lib\avrxmega6\libc.a
C:\WinAVR-20100110\avr\lib\avrxmega7\libc.a

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow thanks a lot. Does it mean that the wikipedia definition is not clear? I mean, they say its used during runtime of program, but in fact no static library can be ever used on the runtime, am I right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It means that avrlibc contains both the runtime support (as defined by the Wikipedia article, i.e. code supporting the language as sush like startup, floating point support etc) and (parts of) the C standard library (things like IO, strings, memory allocation etc).

Quote:

but in fact no static library can be ever used on the runtime, am I right?

If it is not used at run-time, then when would it be used?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cliff, can you work up a FAQ entry for the avr-libc user manual based on your excellent post above?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems to me that there are two aspects on what is the "run time library":

- What functionality it encompasses
- What physical file(s) it is in

On the former aspect: I always thought of "run time library" as "what is needed by the language as such". On this Cliff and I agree. For the floating point stuff we seem to disagree. I thought that the stuff for supporting eg

float f = PORTB / 3.14;

would be in the "run time library" (while e.g. sin() would not).

It follows that (as I see it) some of the "run time library" is actually located in the file libm.a .

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan,

An interesting philosophical question. I guess you are saying that something is "library" if it's a routine that is explicitly called and CRT if the call is implicit then?

Or to put it another way - it's a CRT symbol if the name begins with '__', otherwise it is a library symbol?

I think I could probably agree with that and will incorporate that understanding when I put some words together for Eric. I'd be interested to hear what others think about this.

Cliff

EDIT:

Quote:
It follows that (as I see it) some of the "run time library" is actually located in the file libm.a

Sorry, missed this bit. I'm afraid this I don't agree with. We may well be seeing that some of the CRT is in libm.a but you can't turn that round and say that the entire CRT is in libm.a, I mean why is a file crtm16.o so called (especially the C-R-T at the start!) if it's not at least SOME of the CRT?

EDIT2: regarding the "__" thing. Try the command in the directory:

C:\WinAVR-20100110\avr\lib\avr5>avr-nm libc.a | grep " T " | grep "__"

that rather blows the "anything starting __" theory out of the water. In particular the myriad __eerd* and __eewr* routines which are actually explicitly called by eeprom_read/write() functions. Definitely not CRT functions to my mind.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since code runs at run time,
literalism fails at giving us a sensible definition of a C runtime.
The phrase "standard C library" isn't even hard:
it is whatever provides the functions
the standard requires of the tool chain.
The rest of the tool chain-provided code comes in two and a half flavors:
The tool chain-provided code that runs before main or could,
the tool chain-provided code that runs after main or could,
and the rest of the tool chain provided code.
When using the phrase "C runtime",
those who wish to communicate well should not rely on
the audience knowing whether the last item is included.

In case I wasn't clear: "C runtime" excludes "standard C library".

Oops again: I neglected extension code:
Tool chain provided code, e.g. printf_P,
which, like a standard C library,
is there for users to invoke explicitly,
but is not required by the standard.
I'd also exclude extension code from C runtime.

Moderation in all things. -- ancient proverb

Last Edited: Tue. Nov 9, 2010 - 04:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Quote:
It follows that (as I see it) some of the "run time library" is actually located in the file libm.a

Sorry, missed this bit. I'm afraid this I don't agree with. We may well be seeing that some of the CRT is in libm.a


Now I totally lost you.. We're saying exactly the same thing, AFAICS. SOME of the RTC is in libm.a. (And SOME of it is of course in libc.a. And not all of libm.a is CRT. And not all of libm.a is CRT, either. Parts of both of those is "The C Standard Library" (which I often think of as "libc", but that may not be the correct term/name)).

-----

I took a short swim in the pond that is Wikipedia, and there are discrepancies between different articles:

http://en.wikipedia.org/wiki/Libc says

Quote:
The run-time support provides not only the C standard library functions, but possibly other material needed to create an environment for the C program, such as initialization prior to the invocation of the main function, or subroutines to provide arithmetic operations missing from the CPU that are needed by code generated by the C

while http://en.wikipedia.org/wiki/Run... says
Quote:

For example, the programming language C requires only a very minimal runtime library, but defines a large standard library (called C standard library) that each implementation has to deliver.

If I'd stick with division of the two terms I'd probably say "You need the run-time library for all programs you write". E.g. this needs the run-time library:

// Success.c:
int main(void)
{
   return 0;
}

Then I was about to say "You need the standard library if you're calling any of it's functions", but I'm not sure that saying that covers all uses of the standard library and discriminates all non-uses of it.

-----

As so often when one digs deep enough everything start to be complicated, complex, in conflict or just devilish... I'll stick with "CRT is to support the language per se", "The C Standard Library" is a set of standardized functions etc.

With this, things like the startup and "teardown" code is in the CRT. Things like support routines to help compute a floating point expression, or to divide two 32-bit integer values on an AVR, is in the CRT.

Things like trigonometric functions, printf() and friends, all the str...() functions etc are in the C Standard Library.

We might try saying that the avrlibc runtime is everything in avrlibc except the stuff that is the C Standard Library, but then the util stuff messes things up (they're not RTC and they are not C Standard Library). Or, if you wish

avrlibc = run_time_support + C_Standard_Library + AVR_utility_stuff

I expect someone to shoot this last thing down RSN...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]