SkillAgentSearch skills...

Picolibc

picolibc - a C library designed for embedded 32- and 64- bit systems.

Install / Use

/learn @picolibc/Picolibc
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

Picolibc

Copyright © 2018-2023 Keith Packard

Picolibc is library offering standard C library APIs that targets small embedded systems with limited RAM. Picolibc was formed by blending code from Newlib and AVR Libc.

Build status:

  • Linux
  • Zephyr
  • Coreboot

License

Picolibc source comes from a variety of places and has a huge variety of copyright holders and license texts. While much of the code comes from Newlib, none of the GPL-related bits used to build the library are left in the repository, so all of the source code uses BSD-like licenses, a mixture of 2- and 3- clause BSD itself and a variety of other (mostly older) licenses with similar terms.

There are two files used for testing printf, test/printf-tests.c and test/testcases.c which are licensed under the GPL version 2 or later. There is also a shell script, GeneratePicolibcCrossFile.sh which is licensed under the AGPL version 3 or later which is provided as a helper for people building the library, but not used by picolibc otherwise.

The file COPYING.picolibc contains all of the current copyright and license information in the Debian standard machine-readable format. It was generated using the make-copyrights and find-copyright scripts.

Supported Architectures

Picolibc has integrated testing support for many architectures which is used to validate the code for all patch integration:

  • ARC (32- and 64- bit)
  • ARM (32- and 64- bit)
  • i386 (Native and Linux hosted, for testing)
  • LatticeMico32
  • LoongArch
  • Motorola 68000 (m68k)
  • MIPS
  • MSP430
  • Nios II
  • OpenRisc
  • Power9
  • Renesas RX
  • RISC-V (both 32- and 64- bit)
  • SparcV8 (32 bit)
  • SuperH
  • x86_64 (Native and Linux hosted, for testing)
  • Xtensa ESP32

There is also build infrastructure and continuous build validation, but no integrated testing available for additional architectures:

  • Microblaze (32-bit, big and little endian)
  • Sparc64
  • Xtensa (ESP8266, LX106)

Supporting new architectures requires:

  1. Add libc/machine/architecture for architecture-specific libc bits. This should at least include setjmp/longjmp support as these cannot be performed in architecture independent code and are needed by libstdc++. If available, it should also include thread local storage setup code as libc/machine/architecture/tls.c; the build system looks for that file by name when determining if TLS is available.

  2. Checking for atomic support for stdio. Picolibc requires atomics for ungetc to work correctly in a reentrant environment. By default, it stores them in 16-bit values, but some architectures only have 32-bit atomics. To avoid ABI issues, the size selected isn't detected automatically, instead it must be configured in libc/include/stdio.h.

  3. If necessary, add libm/machine/architecture for any architecture-specific math bits

  4. picocrt/machine/architecture source code and build bits for startup code needed for the architecture. Useful in all cases, but this is necessary to run tests under emulation if your platform can do that.

  5. cross-gcc-triple.txt to configure the meson cross-compilation mechanism to use the right tools

  6. do-architecture-configure to make testing the cross-compilation setup easier.

  7. run-architecture script to run tests under QEMU. Look at the ARM and RISC-V examples to get a sense of what this needs to do and how it gets invoked from the cross-gcc-triple.txt configuration file.

Relation to newlib

Picolibc includes a lot of code originally from newlib. However, it has been reformatted and restructured to make it easier to read and maintain going forward.

Here's a list of some differences between picolibc and newlib:

  1. Designed for and tested on 32- and 64- bit embedded systems. Newlib (and newlib-nano) are used on both embedded systems and Cygwin, with the bulk of the development focused on improving the Cygwin support. Because the Cygwin version needs to be very careful about ABI stability, many parts of the newlib code base are very difficult to change. Picolibc has no such constraints, so much work has been done to improve the ABI and API for use in embedded systems.

  2. Stdio. Picolibc's stdio implementation borrows some code from AVR-Libc along with substantial new code. The goal is to remain compatible with relevant C and POSIX standards while using a very narrow API to the underlying system (it only requires getc and putc) along with doing no internal allocation and using a minimal amount of RAM.

  3. Thread-local-storage support. Instead of creating a large data structure containing all possible thread-specific data, Picolibc uses the underlying TLS support from the compiler which only allocates the amount of per-thread storage needed to support the API called by the application. Typically, this means you use only 4 bytes for errno.

  4. Integrated test suite. Along with dozens of new tests, picolibc includes tests from newlib and musl. These tests are run as a part of the patch review process and new code or bugfixes are expected to include tests that verify functionality and keep bugs from recurring.

  5. Bare-metal startup code and linker scripts for many architectures. These may not support precisely what your application requires, but these provide a good basis for writing your own startup code and linker scripts. These are used to create bare-metal versions of the test suite which can then be run using QEMU.

  6. Meson-based build system. This is largely used to avoid conflicts with the newlib autotools build system files, but a side effect is that the library builds very quickly.

  7. Narrow and well-defined POSIX OS requirements. Portions of Picolibc which require underlying OS support are documented so that you will know which functions are necessary based on the API in use. In particular, picolibc requires no POSIX functions to support stdin/stdout/stderr, and instead requires only functions to get and put single characters to the target device.

  8. Built-in semihosting support for many architectures. This allows you to take advantage of existing gdb, openocd and qemu semihosting support for things like debugging output even before you have a serial port working.

  9. Clear BSD licensing. All non-BSD compatible library source code has been removed so that the status of the resulting library is not in question.

Documentation

Introductory documentation. Read these first:

  • Building Picolibc. Explains how to compile picolibc yourself.
  • Using Picolibc. Shows how to compile and link applications once you have picolibc built and installed.
  • Linking with Picolibc.ld. Provides more details about the linking process.
  • Hello World. Build and run a stand-alone C application by following step-by-step instructions

Detailed documentation. Use these to learn more details about how to use Picolibc:

Releases

Picolibc release 1.8.11

  • Use __math_inexact to generate FE_INEXACT in several math functions. Thanks to Gergely Futo.

  • Support riscv '-mlarge' model in asm code.

  • Initialize riscv vector unit in startup code when present.

  • Improve arm32 A-profile operation in Thumb state. Thanks to Victor Campos.

  • Remove duplicate isinf and isnan declarations that were visible even when building with C++. Thanks to Mostafa Salman.

  • Improve accuracy of cacoshf for real inputs. Thanks to Ahmed Shehab.

  • Avoid use of float types in vfprintf to avoid unnecessary fpu register use.

  • Add missing pid_t and getdate_err declarations to time.h.

  • Implement getdate and getdate_r as required by POSIX.

  • Fix numerous minor bugs in strptime.

  • Test exception handling on m68k

  • Add Hexagon architecture support. Thanks to Kushal Pal.

  • Clean up RISC-V asm code integration. Thanks to Venkata Ramanaiah Nalamothu.

  • Add more math tests, including exhaustive binary 32 testing.

  • Improve cbrtf precision to within 1ulp.

  • Fix lgammaf for values between -0x1p-70 and -0x1p-64.

  • Add some missing stdint.h bits that are new in C23.

  • Improve accuracy of erfcf for values between 1.25 and 28. Improve performance for values between 0x1p-56 and 0x1p-26.

  • Fix memchr on targets with 16-bit int and 32-bit long (MSP430).

  • Mask needle with 0xff on rx version of memchr.

  • Add missing POSIX functionality in fnmatch to support character classes, equivalence classes and collating sequences. Limit fnmatch recursion for '*' operators to 16 levels.

  • Rename cross compile property 'libgcc' to 'librt' since we can now specify either libgcc or compiler-rt as run-time library. However, 'libgcc' is still supported for backward compatibility.

  • Fix bug in 32-bit riscv stpcpy which returned the wrong value. Imp

Related Skills

View on GitHub
GitHub Stars1.5k
CategoryDesign
Updated3h ago
Forks251

Languages

C

Security Score

80/100

Audited on Mar 20, 2026

No findings