Thought Leadership

C libraries

For a software developer, the idea of a library is quite simple: It is a file containing a [typically large] number of functions/procedures/subroutines in a special format. At link time, the linker looks in the library [or there may well be more than one, in which case it checks each in turn] to resolve any references to functions not satisfied by the supplied object modules. This means that the programmer just needs to reference commonly used functions and their code is pulled in automatically.

Of course, it is not quite that simple. Also, as with most aspects of embedded programming, libraries present more challenges and options to developers …

When developing software for the desktop, most programmers give little consideration to standard libraries, concentrating only on any special libraries that might be employed for their application. Such libraries are commonly dynamically linked, so they are quite different from anything used in most embedded systems.

The fact that every embedded system is different is often cited [by me anyway] as a reason for much of the complexity with developing embedded software. The use of libraries reflects this. Apart from getting a library that is right for the target device family and the chosen compiler, there may be a wide selection of other variations: chip family member specifics, register relative addressing, PC relative [position independent] code, endianity, size/speed optimization, the list goes on …

A standard C library contains two types of functions:

  1. Functions called by the generated code where the compiler has determined that so doing is preferable to creating inline instructions.
  2. Functions explicitly called by the code [like printf()].

Commonly a single library is used to contain both these types of function. However, that is not always the case. For GNU compilers, one library [libgcc] contains the compiler support functions. There are a number of options to choose from for the explicitly called functions:

  • GLIBC is very full-featured and designed to be used with Linux, including not only the ISO C functions, but POSIX support and GNU extensions.
  • uClibc is also designed to be used with Linux [or uClinux] and contains a subset of GLIBC, so it has a smaller footprint.
  • Newlib is smaller still and is primarily aimed at embedded applications with no OS.

An interesting question is: what is the benefit of a smaller library, given that only called functions are extracted from it so final binary image size will not vary? I can think of about three answers:

  1. A smaller library results in faster link time.
  2. Less choice of functions might make a programmer more careful in their selection, thus resulting in more optimal [smaller] code.
  3. A small library may also have smaller [less capable] versions of functions, which will result in a smaller application memory footprint.

Any other ideas or suggestions would be welcome by comment or email.

Colin Walls

I have over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, I am a member of the marketing team of the Mentor Graphics Embedded Systems Division, and am based in the UK. Away from work, I have a wide range of interests including photography and trying to point my two daughters in the right direction in life. Learn more about Colin, including his go-to karaoke song and the best parts of being British: http://go.mentor.com/3_acv

More from this author

Comments

0 thoughts about “C libraries
  • I like to see libraries split up on the basis of cohesion and what I would loosely call suitability. I don’t really care whether the actual library code modules come in one file or several but I do like distinct and cohesive header files.

    Most of the C standard library, for example, is unsuitable for most of the embedded and real-time work I do but at least the suitable can be broadly separated from the unsuitable because of the numerous distinct header files. For example, I’ve often used stdio.h for tracing things with printf() during development, but it would ring alarm bells for production code (MISRA backs me on that) unless there were explicit preprocessor directives designed to compile out both the inclusion of stdio.h and its uses, in the production build. On the other hand, I might need math.h and I would be quite happy to use this because the functions are re-entrant (except possibly for setting errno, which can be ignored) and safe also in other ways.

    If a header file’s functions are cohesive, it is usually easy to categorise the whole file as “suitable” or not “suitable”. The reverse is also true. The file stdlib.h is an insult to the concept of cohesion. Within it are a few useful and safe functions – notably some integer arithmetic functions which probably ought to be in math.h – but to get these I have to take on board many highly unsafe functions as well. As long as the header file is there, someone will take that as carte blanche to use whatever is in it!

  • In some small embedded systems we are avoiding dynamic memory allocation. Unfortunately some stdlib functions use malloc/calloc etc (for example printf), even if they can avoid it or if it is only needed by small subset of features.

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at https://blogs.stage.sw.siemens.com/embedded-software/2011/09/19/c-libraries/