RTEMS User Manual (7.e8e6f12).#
This document is available under the Creative Commons Attribution-ShareAlike 4.0 International Public License.
The authors have used their best efforts in preparing this material. These efforts include the development, research, and testing of the theories and programs to determine their effectiveness. No warranty of any kind, expressed or implied, with regard to the software or the material contained in this document is provided. No liability arising out of the application or use of any product described in this document is assumed. The authors reserve the right to revise this material and to make changes from time to time in the content hereof without obligation to notify anyone of such revision or changes.
The RTEMS Project is hosted at https://www.rtems.org. Any inquiries concerning RTEMS, its related support components, or its documentation should be directed to the RTEMS Project community.
RTEMS Online Resources
Documentation https://docs.rtems.org
Mailing Lists https://lists.rtems.org
Bug Reporting https://gitlab.rtems.org
Git Repositories https://gitlab.rtems.org
Developers https://gitlab.rtems.org
1. Introduction#
1.1. Overview#
You are someone looking for a real-time operating system. This document
presents the basic features of RTEMS, so that you can decide if it is worth to look at,
gives you a quick start to install all the tools necessary to work with RTEMS, and
helps you to build an example application on top of RTEMS.
1.2. Features#
The Real-Time Executive for Multiprocessor Systems (RTEMS) is a multi-threaded, single address-space, real-time operating system with no kernel-space/user-space separation. It is capable to operate in an SMP configuration providing a state of the art feature set.
RTEMS is licensed under a modified GPL 2.0 or later license with an exception for static linking FOOTNOTE. It exposes no license requirements on application code. The third-party software used and distributed by RTEMS which may be linked to the application is licensed under permissive open source licenses. Everything necessary to build RTEMS applications is available as open source software. This makes you completely vendor independent.
RTEMS provides the following basic feature set:
-
Programming languages
C/C++/OpenMP (RTEMS Source Builder, RSB)
Ada (RSB,
--with-ada
)Erlang
Fortran (RSB,
--with-fortran
)Python and MicroPython
Parallel languages
Thread synchronization and communication
Locking protocols
Scalable timer and timeout support
Lock-free timestamps (FreeBSD timecounters)
Responsive interrupt management
C11/C++11 TLS FOOTNOTE
Link-time configurable schedulers
Fixed-priority
Job-level fixed-priority (EDF)
Constant Bandwidth Server (experimental)
Clustered scheduling (SMP feature)
Focus on link-time application-specific configuration
Linker-set based initialization (similar to global C++ constructors)
Operating system uses fine-grained locking (SMP feature)
Dynamic memory allocators
First-fit (default)
Universal Memory Allocator (UMA , libbsd)
File systems
Device drivers
Termios (serial interfaces)
I2C (Linux user-space API compatible)
SPI (Linux user-space API compatible)
Network stacks (legacy, libbsd, lwIP)
USB stack (libbsd)
SD/MMC card stack (libbsd)
Framebuffer (Linux user-space API compatible, Qt)
Application runs in kernel-space and can access hardware directly
libbsd
Port of FreeBSD user-space and kernel-space components to RTEMS
Easy access to FreeBSD software for RTEMS
Support to stay in synchronization with FreeBSD
1.3. Ecosystem#
The RTEMS Ecosystem is the collection of tools, packages, code, documentation and online content provided by the RTEMS Project. The ecosystem provides a way to develop, maintain, and use RTEMS. It’s parts interact with the user, the host environment, and each other to make RTEMS accessible, useable and predicable.
The ecosystem is for users, developers and maintainers and it is an ongoing effort that needs your help and support. The RTEMS project is always improving the way it delivers the kernel to you and your feedback is important so please join the mailing lists and contribute back comments, success stories, bugs and patches.
What the RTEMS project describes here to develop, maintain and use RTEMS does not dictate what you need to use in your project. You can and should select the work-flow that best suites the demands of your project and what you are delivering.
1.3.1. Rationale#
RTEMS is complex and the focus of the RTEMS Ecosystem is to simplify the complexity for users by providing a stable documented way to build, configure and run RTEMS. RTEMS is more than a kernel running real-time applications on target hardware, it is part of a project’s and therefore team’s workflow and every project and team is different.
RTEMS’s ecosystem does not mandate a way to work. It is a series of parts, components, and items that are used to create a suitable development environment to work with. The processes explained in this manual are the same things an RTEMS maintainer does to maintain the kernel or an experienced user does to build their production system. It is important to keep this in mind when working through this manual. We encourage users to explore what can be done and to discover ways to make it fit their needs. The ecosystem provided by the RTEMS Project will not install in a single click of a mouse because we want users to learn the parts they will come to depend on as their project’s development matures.
The RTEMS Ecosystem provides a standard interface that is the same on all supported host systems. Standardizing how a user interacts with RTEMS is important and making that experience portable is also important. As a result the ecosystem is documented at the command line level and we leave GUI and IDE integration for users and integrators.
Standardizing the parts and how to use them lets users create processes and procedures that are stable over releases. The RTEMS Ecosystem generates data that can be used to audit the build process so their configuration can be documented.
The ecosystem is based around the source code used in the various parts, components and items of the RTEMS development environment. A user can create an archive of the complete build process including all the source code for long term storage. This is important for projects with a long life cycle.
1.3.2. Open Source#
RTEMS is an open source operating system and an open source project and this extends to the ecosystem. We encourage users to integrate the processes to build tools, the kernel and any third-party libraries into their project’s configuration management processes.
All the parts that make up the ecosystem are open source. The ecosystem uses a package’s source code to create an executable on a host so when an example RTEMS executable is created and run for the first time the user will have built every tool as well as the executable from source. The RTEMS Project believes the freedom this gives a user is as important as the freedom of having access to the source code for a package.
1.3.3. Deployment#
The RTEMS Project provides the ecosystem as source code that users can download to create personalised development environments. The RTEMS Project does not provide packaging and deployment for a specific host environment, target architecture or BSP. The RTEMS Project encourages users and organizations to fill this role for the community. The RTEMS Source Builder provides some aid to build and deploy tool binaries.
1.4. Real-time Application Systems#
Real-time application systems are a special class of computer applications. They have a complex set of characteristics that distinguish them from other software problems. Generally, they must adhere to more rigorous requirements. The correctness of the system depends not only on the results of computations, but also on the time at which the results are produced. The most important and complex characteristic of real-time application systems is that they must receive and respond to a set of external stimuli within rigid and critical time constraints referred to as deadlines. Systems can be buried by an avalanche of interdependent, asynchronous or cyclical event streams.
Deadlines can be further characterized as either hard or soft based upon the value of the results when produced after the deadline has passed. A deadline is hard if the results have no value or if their use will result in a catastrophic event. In contrast, results which are produced after a soft deadline may have some value.
Another distinguishing requirement of real-time application systems is the ability to coordinate or manage a large number of concurrent activities. Since software is a synchronous entity, this presents special problems. One instruction follows another in a repeating synchronous cycle. Even though mechanisms have been developed to allow for the processing of external asynchronous events, the software design efforts required to process and manage these events and tasks are growing more complicated.
The design process is complicated further by spreading this activity over a set of processors instead of a single processor. The challenges associated with designing and building real-time application systems become very complex when multiple processors are involved. New requirements such as interprocessor communication channels and global resources that must be shared between competing processors are introduced. The ramifications of multiple processors complicate each and every characteristic of a real-time system.
- FOOTNOTE The goal is to use the
BSD 2-Clause license for new code or code those copyright holder agreed to a license change, see #3053 for the details.
FOOTNOTE See #2832.
- FOOTNOTE Thread-local storage requires some support by the tool chain and the
RTEMS architecture support, e.g. context-switch code. It is supported at least on ARM, AArch64, PowerPC, RISC-V, SPARC, MicroBlaze, Nios II, and m68k. Check the RTEMS CPU Architecture Supplement if it is supported.
2. Quick Start#
Follow the sections of this chapter step by step to get started developing applications on top of RTEMS. You will create a set of tools and an RTEMS kernel for your selected Board Support Package (BSP).
2.1. Preparation#
You need to perform some basic preparation to get started with RTEMS development. You need tools from your host’s operating system to build the RTEMS tool suite from source. The RTEMS tools you build are used to build the Board Support Package (BSP) libraries for your target hardware from source. The BSP libraries contain the RTEMS operating system. All RTEMS tools and runtime libraries are built from source on your host machine. The RTEMS Project does not maintain binary builds of the tools. This may appear to be the opposite to what you normally experience with host operating systems, and it is, however this approach works well. RTEMS is not a host operating system and it is not a distrbution. Providing binary packages for every possible host operating system is too big a task for the RTEMS Project and it is not a good use of core developer time. Their time is better spent making RTEMS better and faster. This is not a one-click installation process, but there are good reasons to build everything from source. The RTEMS Project base installation sets up the tools and the RTEMS kernel for the selected BSPs. The tools run on your host computer are used to compile, link, and format executables so they can run on your target hardware.
During this Quick Start guide you will:
Select a suitable place to install RTEMS.
Select if you download all the source code before you start building RTEMS or the source is downloaded on demand as it is needed. If you do not have a reliable internet connection we recommend you download all the source before starting a build.
Build a tool suite.
Build and test a BSP.
Optionally build additional packages.
Alternatively you can build a BSP as a package using the RSB. This is covered in Build an RSB Package
2.1.1. Host Computer#
The host computer is a computer you use to develop applications. It runs all your tools, editors, documentation viewers, etc. You need a native C, C++, and Python development environment. The following procedure assumes you have installed and configured your host operating system. It also assumes you have installed any dependent packages needed when building the tools and the kernel. Please make sure you can build native C/C++ applications on your host computer. You must be able to build native Python C modules as some RTEMS tools contain these modules. Usually, you have to install a Python development package for this. The Python scripts of the RTEMS Project expect on POSIX systems that a python
command is available FOOTNOTE. Please have a look at the Host Computer chapter for the gory details. In particular Microsoft Windows users should do this.
2.1.2. Selecting a BSP#
If you are new to RTEMS and you are looking to try RTEMS then the best suited Board Support Package (BSP) is the SPARC ERC32 (erc32
). The SPARC ERC32 BSP has a robust simulator that runs the example and test executables on your host computer. This Quick Start guide will build the erc32
BSP and run RTEMS tests executables in the simulator. The ERC32 BSP is a SPARC architecture BSP so the tool suite name is sparc-rtems5
.
If you are looking for a hardware target to run RTEMS on we recommend the BeagleBone Black (beagleboneblack
) BSP. The BeagleBone Black support includes the RTEMS BSD Library (libbsd
) and networking. The BeagleBone Black BSP is an ARM architecture BSP so the tool suite name is arm-rtems5
.
2.1.3. Selecting a Version of RTEMS#
In the examples of this manual we will often refer to a specific version of RTEMS, which will usually be the version that accompanied the publication of this documentation manual. That may not be the appropriate version for you to use, for example, it may be too old (or too new) depending on what you are trying to do. If you’re not sure what version to use, we generally recommend using the most recent release or the development head (main), and you may want to consult with the same version of the documentation. We hope that newer is better.
An RTEMS release involves the creation of a single downloadable file, normally a compressed tarball, that packages the source of all the repositories in a state consistent with the time the release is created. A release branch is a git branch pushed to the repositories named with the numeric identifier of the branch. A release branch release is a git tag on a release branch with the tags pushed to the repositories.
Numbering for RTEMS versions beginning with RTEMS 5 uses a format as follows. The main branch has the version N.0.0 with N being the next major release number. The first release of this series has the version number N.1.0. and there is exactly one commit with this version number in the corresponding repository. The first bugfix release (minor release) of this series will have the version number N.2.0. The release branch will have the version number N.M.1 with M being the last minor release of this series.
For example:
5.0.0 is the version number of the development branch for the 5 series.
5.1.0 is the first release of the 5 series.
5.1.1 is the version number of the 5 series release branch right after the 5.1.0 release until 5.2.0 is released.
5.2.0 is the first bugfix release of the 5 series
5.2.1 is the version number of the 5 series release branch right after the 5.2.0 release until 5.3.0 is released.
6.0.0 is the version number of the development branch for the 6 series.
RTEMS development tools use N as the version number and are expected to work with all releases and the release branch of the N series. So to build tools for compiling RTEMS version number 5.1.0 for SPARC use sparc-rtems5
. Despite the number not increasing, the tools may change within a release branch, for example the tools packaged with 5.1.1 still use the sparc-rtems5
moniker, but are likely not the same as the tools used in version 5.1.0. This tool mismatch can be a source of confusion. Be sure to use the toolchain that matches your release.
Footnotes
FOOTNOTE The Python scripts use a shebang of #!/usr/bin/env python
.
2.2. Choose an Installation Prefix#
You will see the term prefix referred to throughout this documentation and in a wide number of software packages you can download from the internet. It is also used in the GNU Coding Standard. A prefix is the path on your host computer a software package is installed under. Packages that have a prefix will place all parts under the prefix path. Packages for your host computer typically use a default prefix of /usr/local
on FreeBSD and Linux.
You have to select a prefix for your installation. You will build and install the RTEMS tool suite, an RTEMS kernel for a BSP, and you may build and install third party libraries. You can build all the parts as a stack with a single prefix or you can separate various parts by providing different prefixes to each part as it is built. Using separate prefixes is for experienced RTEMS users.
Do not select a prefix that is under the top of any of the source trees. The prefix collects the install output of the various build steps you take in this guide and need to be kept separate from the sources used.
The RTEMS tool suite consists of a cross tool chain (Binutils, GCC, GDB, Newlib, etc.) for your target architecture and RTEMS tools provided by the RTEMS Project. The RTEMS Tools are a toolkit that help create the RTEMS ecosystem and help support the building of embedded real-time applications and systems. The RTEMS tool chain changes less often than the RTEMS kernel. One method of working with development releases is to have a separate prefix
for the RTEMS tools and a different one for the RTEMS kernel. You can then update each without interacting with the other. You can also have a number of RTEMS versions available to test with.
You build and install the tool suite with the RTEMS Source Builder (RSB). By default, the RSB will start the prefix path with a host operating system specific path plus rtems
, and the RTEMS version, e.g. /opt/rtems/7
on Linux, and /usr/local/rtems/7
on FreeBSD and macOS. Placing the RTEMS version number in the path lets you manage and migrate RTEMS versions as they are released. It is best to have a prefix
for each different version of RTEMS you are using. If you are using RTEMS in production it is not a good idea to install a development version of over the top by using the same prefix
. A separate prefix
for each version avoids this.
It is strongly recommended to run the RSB as a normal user and not with root privileges (also known as super user or Administrator). You have to make sure that your normal user has sufficient privileges to create files and directories under the prefix. For example, you can create a directory /opt/rtems
and give it to a developer group with read, write, and execute permissions. Alternatively, you can choose a prefix in your home directory, e.g. $HOME/rtems/7
or with a project-specific component $HOME/project-x/rtems/7
. For more ideas, see the project sandboxing section. In this quick start chapter, we will choose $HOME/quick-start/rtems/7
for the RTEMS tool suite prefix.
Warning
The prefix must not contain space characters.
2.3. Obtain the Sources#
You have considered and chosen a suitable installation prefix in the previous section. We have chosen $HOME/quick-start/rtems/7
as the installation prefix. We will show how to use a released version of RTEMS and then as an alternative we will show you using the RSB Git repository. Consider using a Git clone if you wish to make contributions to the RTEMS Project.
You need the RTEMS Source Builder (RSB) to work with RTEMS and we prefer you use a released version. A released version of the RSB downloads all source code from the RTEMS servers. Each release archives all the referenced source providing long term stability as changes in upstream projects do not effect a release’s build.
You will need approximately 1.5G bytes of disk space to build the tools, RTEMS kernel, network stack and 3rd party packages for the ERC32 BSP.
2.3.1. Releases#
You can download the source archives for a released RTEMS version from RTEMS’ servers. Releases can be viewed at https://ftp.rtems.org/pub/rtems/releases with the releases listed as a series under a release’s major number. For RTEMS 5.1 the release series is 5 and the release path is https://ftp.rtems.org/pub/rtems/releases/5/5.1.
To work with the archives of a released RTEMS version, simply replace the version number 7 used throughout this chapter with the version number you selected, e.g. sparc-rtems4.11
, sparc-rtems6
, and so on.
Download and unpack using the curl
and tar
command with these commands:
mkdir -p $HOME/quick-start/src
cd $HOME/quick-start/src
curl https://ftp.rtems.org/pub/rtems/releases/7/7.0/sources/rtems-source-builder-7.0.tar.xz | tar xJf -
If curl
does not work consider using wget
or a browser.
The RSB is unpacked under the path rtems-source-builder-7.0
. Rename this to rsb
to get shorter paths during the tool suite build. To do this run these commands:
cd $HOME/quick-start/src
mv rtems-source-builder-7.0 rsb
If you wish to build the RTEMS kernel from source obtain the RTEMS kernel sources:
cd $HOME/quick-start/src
curl https://ftp.rtems.org/pub/rtems/releases/7/7.0/sources/rtems-7.0.tar.xz | tar xJf -
2.3.2. Git#
Alternatively, clone the Git repositories into $HOME/quick-start/src
.
A Git repository clone gives you some flexibility with the added complexity of needing to use a Git branch to build a released version. With Git you can switch between branches to try out different RTEMS versions and you have access to the RTEMS source history. The RTEMS Project welcomes contributions. The Git repositories enable you to easily create patches and track local changes.
You can clone the Git repository to get all versions of RTEMS including the development head. Release branches in Git are kept stable however they may differ from a release’s source archive.
mkdir -p $HOME/quick-start/src
cd $HOME/quick-start/src
git clone https://gitlab.rtems.org/rtems/tools/rtems-source-builder.git rsb
git clone https://gitlab.rtems.org/rtems/rtos/rtems.git
The rsb
repository clone contains the RTEMS Source Builder (RSB). We clone it into rsb
to get shorter paths during the tool suite build. The rtems
repository clone contains the RTEMS sources. These two repositories are enough to get started. There are more repositories available.
Warning
The development version is not for use in production and it can break from time to time.
2.3.3. Offline Download#
If you have limited Internet access you can download the source before you start building. If you are permanently connected to the Internet you do not need to do this and the sources will be automatically download on demand when needed.
Once the sources have been downloaded you could disconnect your host computer from the Internet. It is no longer required to work with RTEMS. To download the sources to build the ERC 32 BSP before building run the following commands:
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --source-only-download 7/rtems-sparc
This command should output something like this (omitted lines are denoted by ...
):
RTEMS Source Builder - Set Builder, 7 (5e449fb5c2cb)
Build Set: 7/rtems-sparc
Build Set: 7/rtems-autotools.bset
Build Set: 7/rtems-autotools-internal.bset
...
download: https://gitlab.rtems.org/rtems-tools/snapshot/rtems-tools-90342feb4dd63d188ce945adfb0a769...<see log> -> sources/rtems-tools-90342feb4dd63d188ce945adfb0a7694a42a65cd.tar.bz2
...
Build Sizes: usage: 0.000B total: 264.228MB (sources: 264.186MB, patches: 43.468KB, installed 0.000B)
Build Set: Time 0:06:34.357125
If you encounter errors, check your internet connection, firewall settings, virus scanners and the availability of the download servers.
2.4. Install the Tool Suite#
You have chosen an installation prefix, the BSP to build, the tool’s architecure and prepared the source for the RSB in the previous sections. We have chosen $HOME/quick-start/rtems/7
as the installation prefix, the erc32
BSP and the SPARC architecture name of sparc-rtems7
, and unpacked the RSB source in $HOME/quick-start/src
.
The tool suite for RTEMS and the RTEMS sources are tightly coupled. For example, do not use a RTEMS version 7 tool suite with RTEMS version 4.11 or 5 sources and vice versa.
If you are unsure how to specify the build set for the architecture you wish to build, just ask the tool:
$ ../source-builder/sb-set-builder --list-bsets
Build and install the tool suite:
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --prefix=$HOME/quick-start/rtems/7 7/rtems-sparc
This command should output something like this (omitted lines are denoted by …). The build host appears as part of the name of the package being built. The name you see may vary depending on the host you are using:
RTEMS Source Builder - Set Builder, 7 (5e449fb5c2cb)
Build Set: 7/rtems-sparc
...
config: tools/rtems-binutils-2.36.cfg
package: sparc-rtems7-binutils-fbb9a7e-x86_64-linux-gnu-1
building: sparc-rtems7-binutils-fbb9a7e-x86_64-linux-gnu-1
sizes: sparc-rtems7-binutils-fbb9a7e-x86_64-linux-gnu-1: 716.015MB (installed: 163.538MB)
cleaning: sparc-rtems7-binutils-fbb9a7e-x86_64-linux-gnu-1
reporting: tools/rtems-binutils-2.36.cfg -> sparc-rtems7-binutils-fbb9a7e-x86_64-linux-gnu-1.txt
reporting: tools/rtems-binutils-2.36.cfg -> sparc-rtems7-binutils-fbb9a7e-x86_64-linux-gnu-1.xml
config: tools/rtems-gcc-10-newlib-head.cfg
package: sparc-rtems7-gcc-6051af8-newlib-d10d0d9-x86_64-linux-gnu-1
building: sparc-rtems7-gcc-6051af8-newlib-d10d0d9-x86_64-linux-gnu-1
....
Build Sizes: usage: 9.607GB total: 2.244GB (sources: 264.186MB, patches: 43.468KB, installed 1.986GB)
installing: 7/rtems-sparc -> $HOME/quick-start/rtems/7
clean staging: 7/rtems-sparc
Staging Size: 5.292MB
Build Set: Time 1:01:48.019157
Once the build has successfully completed you can check if the cross C compiler works with the following command:
$HOME/quick-start/rtems/7/bin/sparc-rtems7-gcc --version
This command should output something like below. The version informtion helps you to identify the exact sources used to build the cross compiler of your RTEMS tool suite. In the output you see the version of RTEMS or the hash from the RSB repository if you are building using a Git repository clone. The Newlib hash is the version of Newlib in the RTEMS’s github sourceware-mirror-newlib-cygwin repository. The sources
and patches
directories created by the RSB contain all the source code used.
sparc-rtems7-gcc (GCC) 10.2.1 20210309 (RTEMS 7, RSB 5e449fb5c2cb6812a238f9f9764fd339cbbf05c2, Newlib d10d0d9)
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Add --verbose
to the GCC command for the verbose version details.
2.4.1. Creating a Tool Archive#
Since the RTEMS Project does not provide binary tool distributions, some users may need to create their own relocatable toolchains. This need can be due to Canadian Cross-Compilation (CxC or three-way), configuration control, or because a user wants to synchronize development environments across multiple workstations or to share tools among multiple developers. To support such needs, the RSB can create tar files of the built package set by adding --bset-tar-file
to the sb-set-builder
command line. These tar files can then be relocated or adapted as needed to suit the user’s needs.
2.4.2. Need for RTEMS-Specific Cross-Compiler#
New users are often confused as to why they cannot use their distribution’s cross-compiler for their target on RTEMS, e.g., the riscv64-linux-gnu or the arm-none-eabi-gcc. Below mentioned are some of the reasons for using the RTEMS cross-compiler.
- Correct configuration of Newlib
Newlib is a C standard library implementation intended for use on embedded systems. Most of the POSIX and libc support for RTEMS is derived from Newlib. The RTEMS cross-compiler configures Newlib correctly for RTEMS.
- Threading in GCC support libraries
Several threading packages in GCC such as Go threads (libgo), OpenMP (libgomp), and OpenACC need to be customized according to RTEMS. This is done by the RTEMS specific cross-compiler.
- Provide preprocessor define __rtems__
The
__rtems__
preprocessor define is used to provide conditional code compilation in source files that are shared with other projects e.g. in Newlib or imported code from FreeBSD.- Multilib variants to match the BSP
RTEMS configures GCC to create separate runtime libraries for each supported instruction set, floating point unit, vector unit, word size (e.g. 32-bit and 64-bit), endianness, ABI, processor errata workarounds, and so on in the architecture. These libraries are termed as Multilib variants. Multilib variants to match the BSP are set by selecting a specific set of machine options using the RTEMS cross-compiler.
2.4.3. Project Sandboxing#
Project specific sandboxes let you have a number of projects running in parallel with each project in its own sandbox. You simply have a prefix per project and under that prefix you create a simple yet repeatable structure.
As an example lets say I have a large disk mounted under /bd
for Big Disk. As root
create a directory called projects
and give the directory suitable permissions to be writable by you as a user.
Lets create a project sandbox for my Box Sorter project. First create a project directory called /bd/projects/box-sorter
. Under this create rtems
and under that create rtems-7.e8e6f12
. Under this path you can follow the released-version procedure to build a tool set using the prefix of /bd/projects/box-sorter/rtems/7.e8e6f12
. You are free to create your project specific directories under /bd/projects/box-sorter
. The top level directories would be:
/bd/projects
Project specific development trees.
/bd/projects/box-sorter
Box Sorter project sandbox.
/bd/projects/box-sorter/rtems/7.e8e6f12
Project prefix for RTEMS 7.e8e6f12 compiler, debuggers, tools and installed Board Support Package (BSP).
A variation is to use the --without-rtems
option with the RSB to not build the BSPs when building the tools and to build RTEMS specifically for each project. This lets you have a production tools installed at a top level on your disk and each project can have a specific and possibly customised version of RTEMS. The top level directories would be:
/bd/rtems
The top path to production tools.
/bd/rtems/7.e8e6f12
Production prefix for RTEMS 7.e8e6f12 compiler, debuggers and tools.
/bd/projects
Project specific development trees.
/bd/projects/box-sorter
Box Sorter project sandbox.
/bd/projects/box-sorter/rtems
Box Sorter project’s custom RTEMS kernel source and installed BSP.
A further varation if there is an RTEMS kernel you want to share between projects is it to move this to a top level and share. In this case you will end up with:
/bd/rtems
The top path to production tools and kernels.
/bd/rtems/7.e8e6f12
Production prefix for RTEMS 7.e8e6f12.
/bd/rtems/7.e8e6f12/tools
Production prefix for RTEMS 7.e8e6f12 compiler, debuggers and tools.
/bd/rtems/7.e8e6f12/bsps
Production prefix for RTEMS 7.e8e6f12 Board Support Packages (BSPs).
/bd/projects
Project specific development trees.
/bd/projects/box-sorter
Box Sorter project sandbox.
Finally you can have a single set of production tools and RTEMS BSPs on the disk under /bd/rtems
you can share between your projects. The top level directories would be:
/bd/rtems
The top path to production tools and kernels.
/bd/rtems/7.e8e6f12
Production prefix for RTEMS 7.e8e6f12 compiler, debuggers, tools and Board Support Packages (BSPs).
/bd/projects
Project specific development trees.
/bd/projects/box-sorter
Box Sorter project sandbox.
The project sandoxing approach allows you move a specific production part into the project’s sandbox to allow you to customise it. This is useful if you are testing new releases. The typical dependency is the order listed above. You can test new RTEMS kernels with production tools but new tools will require you build the kernel with them. Release notes with each release will let know what you need to update.
If the machine is a central project development machine simply replace projects
with users
and give each user a personal directory.
2.5. Build a Board Support Package (BSP)#
You installed the tool suite in your installation prefix, made ready the source for two RTEMS source packages and if you are using a Git clone bootstrapped the RTEMS sources in the previous sections. We installed the tool suite in $HOME/quick-start/rtems/7
and unpacked the source in $HOME/quick-start/src
.
You are now able to build Board Support Packages (BSPs) for all architectures you have an installed RTEMS tool suite. To build applications on top of RTEMS, you have to build and install a BSP for your target hardware. To select a proper BSP for your target hardware consult the BSPs chapter. We select the erc32
BSP. The erc32
BSP uses approximately 2.3G bytes of disk space when the testsuite is built and 44M bytes of space when installed.
We will first show how to build the BSP using the RSB and then we will show how to build the same BSP manually. You only need to use one of the listed methods to build the BSP.
In the output in this section the base directory $HOME/quick-start
was replaced by $BASE
.
2.5.1. RSB BSP Build#
The RSB build of RTEMS does not use the RTEMS source we made ready. It uses the RSB source you downloaded in a previous section. If you are using a release RSB source archive the BSP built is the released kernel image. If you are using a Git clone of the RSB the BSP will be version referenced in the RSB clone.
To build the BSP with all the tests run this command:
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --prefix=$HOME/quick-start/rtems/7 \
--target=sparc-rtems7 --with-rtems-bsp=sparc/erc32 --with-rtems-tests=yes 7/rtems-kernel
This command should output something like:
RTEMS Source Builder - Set Builder, @rtems-ver-majminver@
Build Set: 7/rtems-kernel
config: tools/rtems-kernel-7.cfg
package: sparc-rtems7-kernel-erc32-1
building: sparc-rtems7-kernel-erc32-1
sizes: sparc-rtems7-kernel-erc32-1: 2.279GB (installed: 44.612MB)
cleaning: sparc-rtems7-kernel-erc32-1
reporting: tools/rtems-kernel-7.cfg -> sparc-rtems7-kernel-erc32-1.txt
reporting: tools/rtems-kernel-7.cfg -> sparc-rtems7-kernel-erc32-1.xml
installing: sparc-rtems7-kernel-erc32-1 -> $BASE/
cleaning: sparc-rtems7-kernel-erc32-1
Build Set: Time 0:03:09.896961
The RSB BSP build can be customised with following RSB command line options:
--with-rtems-tests
:Build the test suite. If
yes
is provided all tests in the testsuite are build. Ifno
is provided no tests are built and ifsamples
is provided only the sample executables are built, e.g.--with-rtems-tests=yes
. The test executables are install under the BSP in thetests
directory and you can execute them with the tester and run command.--with-rtems-smp
:Build with SMP support. The BSP has to have SMP support or this option will fail with an error.
--with-rtems-legacy-network
:Build the legacy network software. We recommend you use the current network support in the RTEMS BSP Library (libbsd) unless you need to maintain a legacy product. Do not use the legacy networking software for new developments.
--with-rtems-bspopts
:Build the BSP with BSP specific options. This is an advanced option. Please refer to the BSP specific details in the Board Support Packages (BSPs) of this manual or the BSP source code in the RTEMS source directory. To supply a list of options quote then list with
"
, e.g.--with-rtems-bspopts="BSP_POWER_DOWN_AT_FATAL_HALT=1"
If you have built a BSP with the RSB, you can move on to Test a Board Support Package (BSP).
2.5.2. Manual BSP Build#
We manually build the BSP in four steps. The first step is to set your path. Prepend the RTEMS tool suite binary directory to your $PATH
throughout the remaining steps. Run the command:
export PATH=$HOME/quick-start/rtems/7/bin:"$PATH"
Check your installed tools can be found by running:
command -v sparc-rtems7-gcc && echo "found" || echo "not found"
The output should be:
found
If not found
is printed the tools are not correctly installed or the path has not been correctly set. Check the contents of the path $HOME/quick-start/rtems/7/bin
manually and if sparc-rtems7-gcc
is present the path is wrong. If the file cannot be found return to Install the Tool Suite and install the tools again.
The second step is to configure the BSP. There are various BSP build configuration options available. Some options are BSP-specific. Each section in the INI-style configuration file config.ini
instructs the build system to build a particular BSP variant (sparc/erc32
in our case). We enable the build of the tests with the BUILD_TESTS = True
option and use default values for everything else. For detailed information about the BSP build system, see BSP Build System.
cd $HOME/quick-start/src/rtems
echo "[sparc/erc32]" > config.ini
echo "BUILD_TESTS = True" >> config.ini
./waf configure --prefix=$HOME/quick-start/rtems/7
The first invocation of ./waf
needs a bit of time (e.g. 10 seconds) since an internal cache file is populated. This command should output something like this. In this output the base directory $HOME/quick-start
was replaced by $BASE
.
Setting top to : $BASE/quick-start/src/rtems
Setting out to : $BASE/quick-start/src/rtems/build
Configure board support package (BSP) : sparc/erc32
Checking for program 'sparc-rtems7-gcc' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'sparc-rtems7-g++' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-g++
Checking for program 'sparc-rtems7-ar' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-ar
Checking for program 'sparc-rtems7-ld' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-ld
Checking for program 'ar' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-ar
Checking for program 'g++, c++' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-g++
Checking for program 'ar' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-ar
Checking for program 'gas, gcc' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'ar' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-ar
Checking for program 'gcc, cc' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'ar' : $BASE/quick-start/rtems/7/bin/sparc-rtems7-ar
Checking for asm flags '-MMD' : yes
Checking for c flags '-MMD' : yes
Checking for cxx flags '-MMD' : yes
Checking for program 'rtems-bin2c' : $BASE/quick-start/rtems/7/bin/rtems-bin2c
Checking for program 'gzip' : /usr/bin/gzip
Checking for program 'rtems-ld' : $BASE/quick-start/rtems/7/bin/rtems-ld
Checking for program 'rtems-syms' : $BASE/quick-start/rtems/7/bin/rtems-syms
Checking for program 'xz' : $BASE/anaconda3/bin/xz
'configure' finished successfully (0.414s)
Building the BSP is the third step.
cd $HOME/quick-start/src/rtems
./waf
This command should output something like this (omitted lines are denoted by …).
Waf: Entering directory `$BASE/quick-start/src/rtems/build'
Waf: Leaving directory `$BASE/quick-start/src/rtems/build'
'build' finished successfully (0.085s)
Waf: Entering directory `$BASE/quick-start/src/rtems/build/sparc/erc32'
[ 1/4093] Compiling bsps/shared/dev/serial/mc68681_reg2.c
[ 2/4093] Compiling bsps/shared/dev/rtc/mc146818a_ioreg.c
[ 3/4093] Compiling bsps/shared/dev/flash/am29lv160.c
...
[4093/4093] Processing link: build/sparc/erc32/testsuites/libtests/dl01/dl01-tar.o build/sparc/erc32/testsuites/libtests/dl01/init.o build/sparc/erc32/testsuites/libtests/dl01/dl-load.o build/sparc/erc32/testsuites/libtests/dl01/dl01-sym.o -> build/sparc/erc32/testsuites/libtests/dl01.exe
Waf: Leaving directory `$BASE/quick-start/src/rtems/build/sparc/erc32'
'build_sparc/erc32' finished successfully (2m14.111s)
The last step is to install the BSP.
cd $HOME/quick-start/src/rtems
./waf install
This command should output something like this (omitted lines are denoted by …). In this output the base directory $HOME/quick-start
was replaced by $BASE
.
Waf: Entering directory `$BASE/quick-start/src/rtems/build'
Waf: Leaving directory `$BASE/quick-start/src/rtems/build'
'install' finished successfully (0.081s)
Waf: Entering directory `$BASE/quick-start/src/rtems/build/sparc/erc32'
+ install $BASE/quick-start/rtems/7/sparc-rtems7/erc32/lib/include/libchip/am29lv16.h (from bsps/include/libchip/am29lv1.h)
+ install $BASE/quick-start/rtems/7/sparc-rtems7/erc32/lib/include/libchip/mc146818a.h (from bsps/include/libchip/mc146818a.h)
+ install $BASE/quick-start/rtems/7/sparc-rtems7/erc32/lib/include/libchip/mc68681.h (from bsps/include/libchip/mc68681.h))
...
+ install $BASE/quick-start/rtems/7/sparc-rtems7/erc32/lib/include/rtems/score/watchdogticks.h (from cpukit/include/rtems/score/watchdogticks.h)
+ install $BASE/quick-start/rtems/7/sparc-rtems7/erc32/lib/include/rtems/score/wkspace.h (from cpukit/include/rtems/score/wkspace.h)
+ install $BASE/quick-start/rtems/7/sparc-rtems7/erc32/lib/include/rtems/score/wkspacedata.h (from cpukit/include/rtems/score/wkspacedata.h)
Waf: Leaving directory `$BASE/quick-start/src/rtems/build/sparc/erc32'
'install_sparc/erc32' finished successfully (1.834s))
2.6. Test a Board Support Package (BSP)#
You built a BSP with tests in the previous section. The manual build of the sparc/erc32
BSP placed build artifacts in $HOME/quick-start/src/rtems
while the RSB build placed build artifacts under $HOME/quick-start/rtems/7/sparc/erc32-rtems*/tests
which will need to be adjusted below.
You should run the RTEMS test suite on your target hardware. The RTEMS Project provides some support to do this, see the Testing chapter for the details.
On the sparc/erc32
BSP we selected for this quick start chapter, this is easy. Just run this command:
cd $HOME/quick-start/src/rtems
rtems-test --rtems-bsp=erc32-sis build/sparc/erc32
This command should output something like this (omitted lines are denoted by …). In this output the base directory $HOME/quick-start
was replaced by $BASE
.
RTEMS Testing - Tester, 7.0.not_released
Command Line: $BASE/rtems/7/bin/rtems-test --rtems-bsp=erc32-sis build/sparc/erc32
Host: Linux 5.8.0-44-generic #50~20.04.1-Ubuntu SMP Wed Feb 10 21:07:30 UTC 2021 x86_64
Python: 3.8.5 (default, Jan 27 2021, 15:41:15) [GCC 9.3.0]
Host: Linux-5.8.0-44-generic-x86_64-with-glibc2.29 (Linux 5.8.0-44-generic #50~20.04.1-Ubuntu SMP Wed Feb 10 21:07:30 UTC 2021 x86_64 x86_64)
[ 1/570] p:0 f:0 u:0 e:0 I:0 B:0 t:0 L:0 i:0 W:0 | sparc/erc32: dhrystone.exe
...
[570/570] p:554 f:2 u:6 e:1 I:0 B:3 t:0 L:0 i:0 W:0 | sparc/erc32: ts-validation-1.exe
Passed: 558
Failed: 2
User Input: 6
Expected Fail: 1
Indeterminate: 0
Benchmark: 3
Timeout: 0
Test too long: 0
Invalid: 0
Wrong Version: 0
Wrong Build: 0
Wrong Tools: 0
------------------
Total: 570
Failures:
dl06.exe
minimum.exe
User Input:
dl10.exe
monitor.exe
termios.exe
top.exe
capture.exe
fileio.exe
Expected Fail:
psxfenv01.exe
Benchmark:
dhrystone.exe
linpack.exe
whetstone.exe
Average test time: 0:00:00.371256
Testing time : 0:03:31.616055
2.7. Build Your Application#
You tested a BSP in the previous section. We built the erc32
BSP and it is installed under $HOME/quick-start/rtems/7
.
We will now create a simple Hello World application with a Git repository and using the Waf build system.
The application is be created in $HOME/quick-start/app/hello
.
In the output in this section the base directory $HOME/quick-start
was replaced by $BASE
.
The steps in this section assume you are in the directory $HOME/quick-start/app/hello
after the first step changes to it.
Setup the application work space. Create a new Git repository, download the Waf build system, and the RTEMS Waf.
Create the application directory and change into it:
mkdir -p $HOME/quick-start/app/hello
cd $HOME/quick-start/app/hello
Download the Waf build system and set it to executable:
curl https://waf.io/waf-2.0.19 > waf
chmod +x waf
Initialise a new Git repository:
git init
Add RTEMS Waf support as a Git sub-module and initialise it:
git submodule add https://gitlab.rtems.org/rtems/tools/rtems_waf.git rtems_waf
Create the application source files. Three files are created with an editor of your choice.
First create a C file that configures RTEMS. Using an editor create a file called init.c
and copy the following configuration settings:
/*
* Simple RTEMS configuration
*/
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
Create the Hello World application source file. Using an editor create hello.c
and copy the follow code:
/*
* Hello world example
*/
#include <rtems.h>
#include <stdlib.h>
#include <stdio.h>
rtems_task Init(
rtems_task_argument ignored
)
{
printf( "\nHello World\n" );
exit( 0 );
}
Finally create the Waf script. Using an editor create wscript
and copy the Waf script:
#
# Hello world Waf script
#
from __future__ import print_function
rtems_version = "7"
try:
import rtems_waf.rtems as rtems
except:
print('error: no rtems_waf git submodule')
import sys
sys.exit(1)
def init(ctx):
rtems.init(ctx, version = rtems_version, long_commands = True)
def bsp_configure(conf, arch_bsp):
# Add BSP specific configuration checks
pass
def options(opt):
rtems.options(opt)
def configure(conf):
rtems.configure(conf, bsp_configure = bsp_configure)
def build(bld):
rtems.build(bld)
bld(features = 'c cprogram',
target = 'hello.exe',
cflags = '-g -O2',
source = ['hello.c',
'init.c'])
Configure the application using Waf’s configure
command:
./waf configure --rtems=$HOME/quick-start/rtems/7 --rtems-bsp=sparc/erc32
The output will be something close to:
Setting top to : $BASE/app/hello
Setting out to : $BASE/app/hello/build
RTEMS Version : 7
Architectures : sparc-rtems7
Board Support Package (BSP) : sparc-rtems7-erc32
Show commands : no
Long commands : no
Checking for program 'sparc-rtems7-gcc' : $BASE/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'sparc-rtems7-g++' : $BASE/rtems/7/bin/sparc-rtems7-g++
Checking for program 'sparc-rtems7-gcc' : $BASE/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'sparc-rtems7-ld' : $BASE/rtems/7/bin/sparc-rtems7-ld
Checking for program 'sparc-rtems7-ar' : $BASE/rtems/7/bin/sparc-rtems7-ar
Checking for program 'sparc-rtems7-nm' : $BASE/rtems/7/bin/sparc-rtems7-nm
Checking for program 'sparc-rtems7-objdump' : $BASE/rtems/7/bin/sparc-rtems7-objdump
Checking for program 'sparc-rtems7-objcopy' : $BASE/rtems/7/bin/sparc-rtems7-objcopy
Checking for program 'sparc-rtems7-readelf' : $BASE/rtems/7/bin/sparc-rtems7-readelf
Checking for program 'sparc-rtems7-strip' : $BASE/rtems/7/bin/sparc-rtems7-strip
Checking for program 'sparc-rtems7-ranlib' : $BASE/rtems/7/bin/sparc-rtems7-ranlib
Checking for program 'rtems-ld' : $BASE/rtems/7/bin/rtems-ld
Checking for program 'rtems-tld' : $BASE/rtems/7/bin/rtems-tld
Checking for program 'rtems-syms' : $BASE/rtems/7/bin/rtems-syms
Checking for program 'rtems-bin2c' : $BASE/rtems/7/bin/rtems-bin2c
Checking for program 'tar' : /usr/bin/tar
Checking for program 'gcc, cc' : $BASE/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'ar' : $BASE/rtems/7/bin/sparc-rtems7-ar
Checking for program 'g++, c++' : $BASE/rtems/7/bin/sparc-rtems7-g++
Checking for program 'ar' : $BASE/rtems/7/bin/sparc-rtems7-ar
Checking for program 'gas, gcc' : $BASE/rtems/7/bin/sparc-rtems7-gcc
Checking for program 'ar' : $BASE/rtems/7/bin/sparc-rtems7-ar
Checking for c flags '-MMD' : yes
Checking for cxx flags '-MMD' : yes
Compiler version (sparc-rtems7-gcc) : 10.2.1 20210309 (RTEMS 7, RSB 5e449fb5c2cb6812a238f9f9764fd339cbbf05c2, Newlib d10d0d9)
Checking for a valid RTEMS BSP installation : yes
Checking for RTEMS_DEBUG : no
Checking for RTEMS_MULTIPROCESSING : no
Checking for RTEMS_NEWLIB : yes
Checking for RTEMS_POSIX_API : no
Checking for RTEMS_SMP : no
Checking for RTEMS_NETWORKING : no
'configure' finished successfully (1.142s)
Build the application:
./waf
The output will be something close to:
Waf: Entering directory `$BASE/app/hello/build/sparc-rtems7-erc32'
[1/3] Compiling init.c
[2/3] Compiling hello.c
[3/3] Linking build/sparc-rtems7-erc32/hello.exe
Waf: Leaving directory `$BASE/app/hello/build/sparc-rtems7-erc32'
'build-sparc-rtems7-erc32' finished successfully (0.183s)
Run the executable:
rtems-run --rtems-bsps=erc32-sis build/sparc-rtems7-erc32/hello.exe
The output will be something close to:
RTEMS Testing - Run, @rtems-ver-mjminrev@
Command Line: $BASE/quick-start/rtems/7/bin/rtems-run --rtems-bsps=erc32-sis build/sparc-rtems7-erc32/hello.exe
Host: Linux 5.8.0-44-generic #50~20.04.1-Ubuntu SMP Wed Feb 10 21:07:30 UTC 2021 x86_64
Python: 3.8.5 (default, Jan 27 2021, 15:41:15) [GCC 9.3.0]
Host: Linux-5.8.0-44-generic-x86_64-with-glibc2.29 (Linux 5.8.0-44-generic #50~20.04.1-Ubuntu SMP Wed Feb 10 21:07:30 UTC 2021 x86_64 x86_64)
SIS - SPARC/RISCV instruction simulator 2.26, copyright Jiri Gaisler 2020
Bug-reports to jiri@gaisler.se
ERC32 emulation enabled
Loaded build/sparc-rtems7-erc32/hello.exe, entry 0x02000000
Hello World
*** FATAL ***
fatal source: 5 (RTEMS_FATAL_SOURCE_EXIT)
fatal code: 0 (0x00000000)
RTEMS version: 7.0.0.586e06ec6222f1cd1f005aa8f4a34a8b33f5d862
RTEMS tools: 10.2.1 20210309 (RTEMS 7, RSB 5e449fb5c2cb6812a238f9f9764fd339cbbf05c2, Newlib d10d0d9)
executing thread ID: 0x08a010001
executing thread name: UI1
cpu 0 in error mode (tt = 0x101)
158479 0200d500: 91d02000 ta 0x0
Run time : 0:00:00.259136
Commit the application to the repository:
git add init.c hello.c wscript
git commit -m "My first RTEMS application."
2.8. Build an RSB Package#
This section describes how to build an RTEMS package using the RSB. Before we start to build a package with the RSB you need to complete these steps:
Return to here once you have completed these steps.
You have chosen an installation prefix, the BSP to build, the tool’s architecure and prepared the source for the RSB in the previous sections. We have chosen $HOME/quick-start/rtems/5
as the installation prefix, the erc32
BSP and the SPARC architecture name of sparc-rtems5
, and unpacked the RSB source in $HOME/quick-start/src
.
You are now able to build BSP Packages or 3rd party libraries of code if you have built a BSP.
2.8.1. RTEMS Packages#
RTEMS Packages are source packages the RSB build to run on RTEMS. An installed package is a set of header files and libraries. Your application include the packages header files to make calls to the package’s code and include the libraries in it’s linker options.
RTEMS packages can be part of the RTEMS Project or they can be external packages from 3rd parties. RTEMS Project packages include the BSPs and BSD Library package called libbsd
. External 3rd party packages include networking such has curl
or libcurl
to graphics libraries.
Packages can depend on other packages and need to be build in the corret order. For example the FreeBSD Library package depends on the BSP package and a 3rd party library such as curl
depends on the FreeBSD Library package. We call this layering a vertical software stack.
RTEMS applications are cross-compiled and this adds complexity when building libraries of code. RTEMS Packages build with the RSB manage this complexity for you.
Package are libraries so they will not be linked into your application until you make calls to the the code and add the library to your application’s linker command line.
2.8.2. BSP Stack Build#
A BSP stack build is a single command that uses the RSB to build a BSP software stack of:
Tool suite
BSP
Packages
The packages built depend on the BSP and the default will build all packages for a BSP.
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --prefix=$HOME/quick-start/rtems/5 \
--with-rtems-tests=yes bsps/erc32
This command should output something like this:
RTEMS Source Builder - Set Builder, 5.1.0
Build Set: bsps/erc32
Build Set: 5/rtems-sparc.bset
Build Set: 5/rtems-autotools.bset
Build Set: 5/rtems-autotools-internal.bset
config: tools/rtems-autoconf-2.69-1.cfg
package: autoconf-2.69-x86_64-freebsd12.1-1
building: autoconf-2.69-x86_64-freebsd12.1-1
sizes: autoconf-2.69-x86_64-freebsd12.1-1: 7.505MB (installed: 0.000B)
...
building: protobuf-2.6.1-sparc-rtems5-1
sizes: protobuf-2.6.1-sparc-rtems5-1: 228.079MB (installed: 84.408MB)
cleaning: protobuf-2.6.1-sparc-rtems5-1
reporting: net/protobuf-2.6.1-1.cfg -> protobuf-2.6.1-sparc-rtems5-1.txt
reporting: net/protobuf-2.6.1-1.cfg -> protobuf-2.6.1-sparc-rtems5-1.xml
staging: protobuf-2.6.1-sparc-rtems5-1 -> $HOME/quick-start/src/rsb/rtems/build/tmp/sb-500-staging
cleaning: protobuf-2.6.1-sparc-rtems5-1
Build Set: Time 0:00:23.564992
Build Set: Time 0:02:27.380299
installing: bsps/erc32 -> $HOME/quick-start/rtems/
clean staging: bsps/erc32
Staging Size: 1.372GB
Build Set: Time 0:24:17.83979
The RSB BSP build can be customised with following RSB command line options:
--with-rtems-tests
:Build the test suite. If
yes
is provided all tests in the testsuite are build. Ifno
is provided no tests are built and ifsamples
is provided only the sample executables are built, e.g.--with-rtems-tests=yes
.--with-rtems-smp
:Build with SMP support. The BSP has to have SMP support or this option will fail with an error.
--with-rtems-bspopts
:Build the BSP with BSP specific options. This is an advanced option. Please refer to the BSP specific details in the Board Support Packages (BSPs) of this manual or the BSP source code in the RTEMS source directory. To supply a list of options quote then list with
"
, e.g.--with-rtems-bspopts="BSP_POWER_DOWN_AT_FATAL_HALT=1"
Only a limited number of BSPs have RSB support to build as a software stack. To see which BSPs are supported run this command:
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --list-bsets | grep bsps
2.8.3. Package Build#
Packages are built using RSB build sets. A build set is a set of builds need to build a packages. The build steps can be dependencies a package has or it could be a stack of software to provide specific functionality, i.e. a build set can be a list of build sets. To view the avaliable build sets run this command:
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --list-bsets
RTEMS package naming is based on the naming FreeBSD uses in its ports collection.
This Quick Start Guide will build the BSD Library or 5/rtems-libbsd
.
An RTEMS package is hosted on RTEMS so the tool suite name needs to be supplied using the --host
option, e.g. --host=sparc-rtem5
. The BSP needs to be provided using the --with-rtems-bsp
option, e.g. --with-rtems-bsp=erc32
. The commands to build libbsd
for the erc32
BSP are:
cd $HOME/quick-start/src/rsb/rtems
../source-builder/sb-set-builder --prefix=$HOME/quick-start/rtems/5 \
--host=sparc-rtems5 --with-rtems-bsp=erc32 5/rtems-libbsd
This command should output something like this:
RTEMS Source Builder - Set Builder, 5.1.0
Build Set: 5/rtems-libbsd
config: tools/rtems-libbsd-5.cfg
package: rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1
building: rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1
sizes: rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1: 1.199GB (installed: 116.541MB)
cleaning: rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1
reporting: tools/rtems-libbsd-5.cfg -> rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1.txt
reporting: tools/rtems-libbsd-5.cfg -> rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1.xml
installing: rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1 -> $HOME/quick-start/rtems/5
cleaning: rtems-libbsd-v3cc039cdac77272a8e16b33ae5a53ccd89edf989-sparc-rtems5-1
Build Set: Time 0:00:51.898231
Note
Not all packages will build or run with all BSPs. Please ask on the Users Mailing List if you have any issues.
2.9. GSoC Getting Started#
The goal of this page is to help new contributors get RTEMS compiled and running so they can start with the real work. It is specifically meant for prospective applicants to Google Summer of Code, but should be helpful for anyone who wants to get in to development and contributing to RTEMS.
Please join the Discord and ask questions in the #gsoc
channel.
Help correct any deficiencies in the code or documentation you spot, including those on the website. The ultimate goal of GSoC is to help you become part of the open source community, and there is no better way to start than by fixing small errors in the getting started resources.
This section will help you to quickly setup a development environment without delving into the details. For more information you can go through the other subsections under Quick Start chapter, ask in Discord, or ask on the Users Mailing List and Developers Mailing List.
We recommend all new developers use the current development (unreleased) version, which is currently 7. The Quick Start Preparation should be consulted for guidance. Some examples shown may use released versions, which may not be recommended for your purposes. If you are unsure, feel free to inquire in the Discord or on the Developers Mailing List.
You will likely encounter the least difficulty by using a GNU/Linux environment, which could be in a virtual machine, for example that uses Virtualbox and should run on most modern desktop systems. You should also be able to work with a MacOS or Windows system, but might encounter more challenges. See the detailed guidance in Host Computer.
Setting up a development environment consists of the following steps.
Installing dependencies for your host operating system.
Choosing an installation prefix.
Downloading the source code.
Installing the tool suite.
Building the Board Support Package (BSP).
Testing the Board Support Package (BSP).
2.9.1. Installing Dependencies#
You need tools for your host’s operating system to build the RTEMS tool suite from source. Please have a look at the Host Computer chapter for the instructions to install the tools for your OS.
2.9.2. Choosing an installation prefix#
The term prefix
refers to the path on your computer where the software is to be installed. You can refer to the Prefix section for details on choosing an installation prefix. You should avoid using prefixes that require root permission, as building with root is not supported or recommended.
2.9.3. Downloading the Sources#
We will be using Git to clone the sources for RTEMS and RSB. This is the preferred way if you are planning to make contributions to the RTEMS project.
Please refer to the Git section for instructions on obtaining sources using Git.
2.9.4. Installing the Tool Suite#
The Tools suite is the collection of tools required to build the BSP. This includes the compiler, debugger, assembler and other tools. These tools are architecture-specific. We will be installing the SPARC tool suite since we are building a SPARC based BSP.
Please refer to the Install the Tool Suite section for instructions on building and installing the tool suite. Remember to use the current version associated with the RTEMS development head, see Selecting a Version of RTEMS. You do not need to create a toolchain archive, but you should read the rest of the Quick Start while your tools build.
2.9.5. Building the Board Support Package#
There are two ways of building a BSP. We could either ask RSB to build the BSP or manually build it. You will build it manually. Please refer the Manual BSP Build section for the instructions.
2.9.6. Testing the Board Support Package#
Testing is an essential part of RTEMS development process. The main reason for choosing the SPARC erc32 BSP is that it has very good simulator support. This will allow you to test your changes without the need for SPARC hardware.
Please refer to Test a Board Support Package (BSP) for instructions on testing the BSP.
2.9.7. Prove You Can Work On RTEMS#
This section is intended for contributors interested in Google Summer of Code.
You have to finish the following task to prove that you can work on RTEMS.
Modify the hello world example to include a new different print statement.
Something like “Hello from The Dark Side!”.
If you followed this guide, this hello world modification will likely need to be made in $HOME/quick-start/src/rtems/testsuites/samples/hello/init.c
. To test your changes, you have to build the BSP again, something like the following:
cd $HOME/quick-start/src/rtems
./waf
If you are happy with your changes you can commit the changes. Create a patch of your changes and attach it with your screenshot to send to us to prove that you did this. We want to know you can work with RTEMS. You can create a patch using this command from inside your modified rtems.git:
git format-patch HEAD^ -o ../
This should create a file in the parent directory (../
) with a filename like 0001-commit-message.patch
where the first (subject) line of your commit message gets embedded in the filename. You can just attach these files to a Discord message in the #gsoc
channel.
2.9.8. Creating and Sending Merge Requests#
Instead of passing around patches, we use merge requests (MRs) in GitLab to share code and conduct code reviews. Before sending an MR, make sure that the changes you have made conforms to RTEMS coding standards. You can refer to Contributing section for instruction on creating and sending merge requests.
Here are a few pointers to keep in mind while creating the patches.
Always work in a fork.
Make sure not to commit changes in the
main
branch. This is to avoid merge conflicts when you are pulling the latest changes from the remote branch.Avoid trailing whitespace errors.
Avoid making random whitespace changes unrelated to your changes.
The author name of the patch is your full legal name.
The author email of the patch is your valid email address.
Ensure that your changeset builds before sending the MR for review.
As an initial test of submitting an MR, please add yourself to the correct tracking page of Google Summer of Code for the current year.
3. Support and Contributing#
3.1. RTEMS Project Support#
3.1.1. Users Mailing List#
RTEMS offers a variety of support options and ways to contribute to the project. Users can ask their questions on the Users Mailing List. This is a low frequency mailing list intended for topics related to the use of RTEMS. If you are new to RTEMS, please join the list and ask whatever you want.
3.1.2. Documentation#
You find the latest set of manuals at the Documentation Site.
3.1.3. All Mailing Lists#
We have several mailing lists for RTEMS users and developers:
Announce Mailing List: Announcements for major and other project-related issues.
Bugs Mailing List: Emails generated by the Bugs Database.
Developers Mailing List: For developers of RTEMS itself.
Build Logs: Results from building and testing of RTEMS.
Users Mailing List: For users of RTEMS.
Version Control Mailing List: Commits to the RTEMS Project repositories.
3.1.4. Discord#
The RTEMS Discord server is available at https://www.rtems.org/discord
We have several channels available for discussion please be kind. The purpose of each channel is listed in thier discriptions.
For support with GitLab there is also the #gitlab-support
channel.
3.2. Report Bugs#
The RTEMS Project uses a ticket system to deal with bugs, organize enhancement requests, and manage small tasks and projects. You can submit a bug report to the RTEMS Project ticket system. Before you do this, please read the following information. Good bug reports are more likely to get addressed quickly. If you have patches not specifically related to bugs or existing tickets, please have a look at the Contributing guidelines.
3.2.1. Search for Existing Bugs#
You can search for existing bugs in the RTEMS Project ticket system. Please try to avoid duplicate bug reports and search for an existing bug before you report a new bug. If you are unsure, please ask on the Users Mailing List and we will help you sort it out.
3.2.2. Not RTEMS Bugs#
Some issues appear to be an RTEMS bug to you, but are actually the intended behaviour or in the scope of other projects.
Bugs in the assembler, the linker, or the C library (Newlib) are not RTEMS bugs. These are separate projects, with separate mailing lists and different bug reporting procedures. The RTEMS Project is happy to work with you and those projects to resolve the problem but we must work with those projects. Bugs in those products must be addressed in the corresponding project. Report assembler, linker, and GDB bugs to sourceware.org, compiler bugs to GCC, and Newlib bugs to the Newlib mailing list. If the bug was fixed, then you can update the Source Builder to pick up the fix.
Questions about the correctness or the expected behaviour of programming language constructs or calls to library routines that are not part of RTEMS belong somewhere else.
The POSIX standard does not specify the default set of thread attributes. Thus, when passing a NULL for attributes to pthread_create(), the application is not guaranteed any particular thread behaviour.
The defaults for all RTEMS Application Configuration parameters are intentionally small, see Configuring a System chapter of the RTEMS Classic API Guide. Thus, it is common for RTEMS tasking and file related calls to return errors indicating out of resources until the configuration parameters are properly tuned for the application. For example, there are only three file descriptors available by default: stdin, stdout, and stderr. Any attempt to open a socket or file will fail unless more file descriptors are configured.
When first developing a BSP, many users encounter an unexpected interrupt or exception immediately upon completion of RTEMS initialization. This occurs because interrupts are disabled during RTEMS initialization and are automatically initialized as part of switching to the first task. The interrupted user code will be in either _CPU_Context_switch() or _Thread_Handler(). This indicates that an interrupt source has not been properly initialized or masked.
Some users encounter a random reset during BSP initialization. This usually indicates that the board has a watchdog timer that is not being properly serviced during the BSP initialization.
Bugs in releases or snapshots of RTEMS not issued by the RTEMS Project. Report them to whoever provided you with the release.
3.2.3. Creating Good Bug Reports#
Please open a page to the RTEMS Project ticket system and follow the guidelines below to write a good bug report.
Click the “Select project to create issue” button for the relevant repository.
Click the New Issue button for the selected project repository.
Provide a useful single line Summary in the Title.
Fill out a description with target details, reproduction steps, build environment, exact versions, etc. Use MarkDown to structure the information you provide. It does help the readability of the information you provide.
Add a description of the expected behaviour. The expected behaviour may be obvious to you, but maybe not to someone else reading the bug report.
Add a description of the actual undesired behaviour.
Name the target hardware (processor architecture, chip family or model, and BSP) in the description. In addition, select the appropriate
arch::
label if the bug is hardware-specific.Add the toolchain version used (GCC, Binutils, Newlib) to the description. Custom toolchain builds are discouraged. To avoid problems caused by custom builds of the toolchain, please build your toolchain with the Source Builder. If you use a custom build of the toolchain, then try to reproduce the bug first using a toolchain built by the RSB.
Provide the configuration options used to build the RTEMS BSP in the description. This helps to reproduce the issue.
Make the bug reproducible by others. Write a self-contained piece of source code which can be compiled and reproduces the bug. Avoid adding assembly files (*.s) produced by the compiler, or any binary files, such as object files, executables, core files, or precompiled header files. If it is difficult or time consuming to reproduce the bug, then it may not get the attention it deserves from others. Developing and debugging real-time embedded systems can be difficult. Exercise caution in reporting an error that occurs only some of the times a certain program is executed, such that retrying a sufficient number of times results in a successful compilation; this is often a symptom of a hardware problem or application issue, not of a RTEMS bug (sorry). We do recognise that sometimes a timing bug will exist in RTEMS, but we want you to exercise due diligence before pointing fingers.
Only when your bug report requires multiple source files to be reproduced should you attach an archive. Otherwise, the uploaded individual source file or diff should contain the minimal source code needed to reproduce the bug. In any case, make sure the above are included in the body of your bug report as plain text, even if needlessly duplicated as part of an archive.
Please try to reproduce the bug on the current Git main branch. If it is not reproducible on main, you should figure out if the bug was already fixed. You can search the existing bugs once again, ask on the Users Mailing List, or do a Git bisect to find a commit which fixed the bug.
Include only information relevant to the bug.
Write separate bug reports for different bugs.
Select the Milestone to which this bug applies. It should be the nearest unreleased Milestone from the affected branch. Ask for help if you are not sure.
Select a set of appropriate Labels for the issue.
Select whether the issue is confidential. This is only expected in the potential context of security bugs.
Some fields should only be set by the maintainers, as it is not always clear what they should be set to. Feel free to make your own choices.
When you have checked that your report meets the criteria for a good bug report, please submit it.
If you fail to supply enough information for a bug report to be reproduced, someone will probably ask you to post additional information. In this case, please post the additional information and not just to the person who requested it, unless explicitly told so.
3.2.4. Nobody Fixes my Bug#
Sometimes, you may notice that after some time your bug report gets no attention and the bug is not magically fixed. This may have several reasons
the bug report is incomplete or confusing,
the target hardware is not available to others,
the bug is not reproducible on the Git main branch,
the bug is not reproducible at all,
the RTEMS version is quite old and no longer used by RTEMS maintainers, or
fixing the bug has a low priority for others.
Please note that you do not have a service contract with the RTEMS Project. The RTEMS Project is run by volunteers and persons who take care about how RTEMS performs in their application domain. If your bug does not affect the interest of someone else, then you should try to fix the bug on your own, see the Contributing guidelines. To change the priorities of others with respect to your bug, you may refer to the Commercial Support Services.
3.3. Contributing#
3.3.1. How to Contribute?#
You can contribute to the RTEMS Project in various ways, for example:
participation in mailing list discussions, helping other users
documentation updates, clarifications, consolidation, fixes
bug fixes, bug report consolidation
new BSPs
new device drivers
new CPU (processor architecture) ports
improvements in the existing code base (code size, code clarity, test coverage, performance optimizations)
new features
RTEMS Tools improvements
Most contributions will end up in patches of the RTEMS source code or documentation sources. The patch integration into the RTEMS repositories is done through a patch review process on Gitlab.
3.3.2. Preparing and Submitting Merge Requests#
The RTEMS Project uses Git for version control and uses Gitlab for managing changes. Contributions are made by creating a Merge Request (MR) on Gitlab. The Gitlab merge request documentation comprehensively explains the concepts of using merge requests. RTEMS will only accept changes via a Merge Request. Most merge requests should have one or more Issues associated with them, unless it is a simple, isolated change. Please do not use merge requests to introduce new code, concepts, styles or to change existing behaviours such as APIs or internal interfaces. Please create an issue before you start the work so the community is aware of the changes coming. The merge requests can then focus on the details of the implementation and approval does not need to be about approval of change at a functional level.
We use project forks as the base of our workflow and outside of that there is no workflow we mandate. What works for one task or work package may not work for another. Complex tasks may affect a number of our GitLab Projects with issues and merge requests in a number of projects. You may want to use an Epic to bring work together.
With our GitLab instance, you fork a repo into your personal workspace and use that to manage your changes. This means you need to keep your forked project up to date. See the Gitlab forking workflow documentation <https://docs.gitlab.com/ee/user/project/merge_requests/authorization_for_merge_requests.html#forking-workflow>
for details. If you are part of a team working on a change you can collaborate on merge requests <https://docs.gitlab.com/ee/user/project/merge_requests/allow_collaboration.html>
. GitLab enforces branch naming rules and provides branch naming patterns <https://docs.gitlab.com/ee/user/project/repository/branches/#prefix-branch-names-with-issue-numbers>
that simplifies code review and software change management. You can create merge requests from your fork <https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html#when-you-work-in-a-fork>
back to the upstream repository. We do not normally squash merge requests. A merge request with more than one commit should be buildable at each commit so a bisect of main does not break.
3.3.3. Checklist for Merge Requests#
Check the following items before you publish your merge requests:
The author name of each commit is a full name of the author.
The author email of each commit is a valid email address for the author.
The licence conditions of the contributed content allow an integration into the RTEMS code base.
If you are the copyright holder of the entire patch content, then please contribute it under the BSD-2-Clause license. For documentation use CC BY-SA 4.0.
Make sure you have a meaningful title which does not exceed 50 characters in one line. Use a “topic: The meaningful title” style. A topic could be the main component of the commit. Just have a look at existing commit messages.
Each patch has a good commit message. It should describe the reason for the change. It should list alternative approaches and why they were not chosen.
The code changes honour the coding style. At least do your changes in the style of the surrounding code.
Each patch contains no spelling mistakes and grammar errors.
Each patch is easy to review. It changes one thing only and contains no unrelated changes. Format changes should be separated from functional changes.
If commits correspond to Issues, the merge request should have “Close #X.” or “Update #X.” to update status once it is merged.
Each patch builds. All RTEMS tests link with every patch.
Each patch does not introduce new compiler warnings.
Each patch does not introduce new test failures in existing tests.
3.3.4. Review Process#
Merge requests sent to the RTEMS Gitlab undergo a public review process. At least two approvals are required before a merge request can be pushed to the RTEMS repository. It helps if you follow the Checklist for Merge Requests. An easy to review patch series which meets the quality standards of the RTEMS Project will be more likely to get integrated quickly.
The review process includes both objective and subjective feedback. You should reflect upon and consider all feedback before making or refusing changes. It is important to note that some feedback may be relevant at one point in time, but less relevant in the future. Also, what concerns one developer may not concern another. Just because you address all the feedback in one round of review does not mean your submission will be approved, as someone (even the same reviewer) may notice something that was not seen before. It is important to have patience, humility, and open-mindedness when engaging in open-source software review and approval processes. This is true for both contributors and reviewers.
Reviews should be conducted primarily via the GitLab interface using the in-line commenting feature. Follow-up comments to the same line should be threaded, while new comments should be added to the specific, relevant line of modified code. Although high-level comments about the entire patch set are allowed, the most useful commments are those that are specifically targeted to problematic lines of code.
3.3.5. Updating a Merge Request#
As you make changes to your merge request through the review process, you will either be layering additional patches on top of your current patch set, or you will be rebasing your patch set. Either approach is acceptable, but remember that every patch in your patch set must pass continuous integration testing and adhere to the Checklist for Merge Requests. Most often, this means that you should rebase the patch set in your merge request to include the updates.
There are several ways you can rebase the patch set. The following is one suggested workflow:
3.4. Before making changes, create a new local branch of your merge request. Make#
: your changes on this branch, so that you can always go back to your previous state. Always keep your original branch until you have pushed a new, clean version that supersedes it. Even then, you may want to keep your original branch around in case something went wrong that you did not notice, such as you accidentally removed a necessary commit while rebasing.
# Make and commit changes locally until you are satisfied with your code
3.5. Interactively rebase your local branch using git rebase --interactive
#
: to allow you to select the order of commits and to reword or fixup commits. One good strategy here is to reorder and fixup commits in one round and then reword them in a second round, so that you get your commits in the right order and shape you want before finalizing the patch descriptions.
3.6. Force-push your local branch to your merge request branch on your fork. If#
: something goes wrong, you can revert back to your local version.
3.6.1. Rebasing a Merge Request#
You can follow a similar process as Updating a Merge Request to rebase your merge request branch to an updated target branch, e.g., to pick up changes on main
. In this case, after creating a local branch, use git pull --rebase
stopping to fix merge conflicts along the way. If it gets out of hand, you can either abort
the rebase or you can go back to your original branch.
When merge conflicts are too much to handle doing a rebase, you may instead like to create a fresh branch from main
and then use git-cherry-pick
to pull commits from your merge request branch on to the head of main
. If you are having too much trouble, ask for help.
3.6.2. Approvers#
Merge Request approvals must be from a code owner, identified by the CODEOWNERS
file and by sub-groups beneath Approvers
. Any one who has requested approval permission can approve a merge request. Once a patch series is approved for integration into the RTEMS code base it can be merged by anyone with merge rights, which may include an automated bot.
Approvers are volunteering their time so be polite. If you do not get a response to a merge request after five working days, please send a reminder on the merge request or send email to the Developers Mailing List.
3.6.3. Why Contribute?#
If you are writing a major extension to RTEMS, such as a port to a new CPU family (processor architecture) or model, a new target board, a major rewrite of some existing component, or adding some missing functionality, please keep in mind the importance of keeping other developers informed. Part of being a good cooperating member of the RTEMS development team is the responsibility to consider what the other developers need in order to work effectively.
Nobody likes to do a lot of work and find it was duplicated effort. So when you work on a major new feature, you should tell Developers Mailing List what you are working on, and give occasional reports of how far you have come and how confident you are that you will finish the job. This way, other developers (if they are paying attention) will be aware which projects would duplicate your effort, and can either join up with you, or at least avoid spending time on something that will be unnecessary because of your work. If, for whatever reason, you are not in a position to publicly discuss your work, please at least privately let other developers know about it so they can look out for duplicated effort or possible collaborators.
You should also monitor the Users Mailing List and Developers Mailing List to see if someone else mentions working on a similar project to yours. If that happens, speak up!
If you are thinking of taking a contract to develop changes under a temporary delayed-release agreement, please negotiate the agreement so that you can give progress reports before the release date, even though you cannot release the code itself. Also please arrange so that, when the agreed-on date comes, you can release whatever part of the job you succeeded in doing, even if you have not succeeded in finishing it. Someone else may be able to finish the job.
Many people have done RTEMS ports or BSPs on their own, to a wide variety of processors, without much communication with the RTEMS development team. However, much of this work has been lost over time, or have proven very hard to integrate. So, what we are asking is that, to the maximum extent possible, you communicate with us as early on and as much as possible.
3.6.4. Common Questions and Answers#
Here are some questions RTEMS porters may have with our answers to them. While the focus here is on new ports and BSPs, we believe that the issues are similar for other RTEMS development efforts including student efforts to implement new algorithmic optimizations.
Our engineers understand our target environment better than anyone else, and we have a tight schedule. Why should we work with the RTEMS developers, when we can get the code out faster by whacking it out on our own?
You understand your target environment better than anyone else. However, the RTEMS developers understand RTEMS better than anyone else; furthermore, the RTEMS developers tend to have a wide breadth of experience across a large number of processors, boards, peripherals, and application domains. It has been our experience that few problems encountered in embedded systems development are unique to a particular processor or application. The vast majority of the time an issue that arises in one project has also shown up in other projects.
The intimate knowledge of RTEMS internals as well as a wide breadth of embedded systems knowledge means that there is a good chance that at least one RTEMS developer has already addressed issues you are likely to face when doing your port, BSP, or application. The developers can help guide you towards a workable long term solution, possibly saving you significant time in your development cycle.
If getting the sources into the official RTEMS distributions is one of your goals, then engaging other RTEMS developers early will also likely shorten your development time. By interacting as early as possible you are more likely to write code which can be easily accepted into the official sources when you are finished. If you wait until you think you are done to begin interacting with the RTEMS team, you might find that you did some things wrong and you may have to rewrite parts of your RTEMS port, which is a waste of your valuable time.
Why should we care if our port is integrated into the official RTEMS sources? We can distribute it ourselves to whoever is interested.
Yes, the RTEMS licenses allows you to do that. But by doing so, you end up having to maintain that code yourself; this can be a significant effort over time as the RTEMS sources change rapidly.
You also lose the advantage of wider exposure by including your port in the official RTEMS sources maintained by the RTEMS Project. The wider exposure in the RTEMS developer and tester community will help keep your work up to date with the current sources. You may even find that volunteers will run the ever-growing test suite on your port and fix problems during the development cycle – sometimes without your intervention.
It has been our experience that integrated ports tend to ultimately be of better quality and stay up to date from release to release.
Why should we communicate up front? We are happy to let the RTEMS developers integrate our stuff later.
See above. It will save work for you over both the short and the long term, and it is the right thing to do.
Aspects of my target environment that my application exploits are still under NDA.
Nevertheless, if the target hardware is built of any commercial parts that are generally available including, but not limited to, the CPU or peripherals, then that portion of your work is still of general use. Similarly, if you have written software that adheres to existing API or interface standards, then that portion is also of general use. Our experience is that most embedded applications do utilize a custom mix of hardware and application, but they are built upon layers of hardware and software components that are in no way unique to the project.
If you are porting to an unreleased CPU family or model, then just announcing it is important because other RTEMS users may be planning to use it and some of them may already be trying to port RTEMS on their own. Your customers might be happier to know that your port will eventually be available. Also, there is no requirement that RTEMS include all features or ports at any particular time, so you are encouraged to submit discrete pieces of functionality in stages.
Assume that your processor has some new functionality or peripherals. However that functionality is still covered by NDA, but the basic core architecture is not. It is still to your advantage to go ahead and work with the developers early to provide a “base port” for the CPU family. That base port would only use the publicly available specifications until such time as the NDA is lifted. Once the NDA is lifted you can work with the developers to provide the code necessary to take advantage of the new functionality.
Ultimately, cooperating with the free software community as early as possible helps you by decreasing your development cycle, decreasing your long term maintenance costs and may help raise interest in your processor by having a free compiler implementation available to anyone who wants to take a look.
3.7. Commercial Support Services#
The wider RTEMS community has developers and organizations who can provide commercial support services. These services range from training, implementing new features in RTEMS, deployment of RTEMS, helping establish a new project environment for a team, to application and system design.
The RTEMS Project does not endorse or promote any provider of these services and we recommend you use a search engine to locate a suitable provider. If you are unsure please contact a provider and see what is available.
If you develop a new feature or you have someone do this for you we recommend you have the work submitted to the project and merged. Once accepted into the project the work will be maintained as part of the development process within the project and this is a benefit for.
4. Host Computer#
RTEMS applications are developed using cross-development tools running on a development computer, more often called the host computer. These are typically your desktop machine or a special build server. All RTEMS tools and runtime libraries are built from source on your host machine. The RTEMS Project does not maintain binary builds of the tools. This differs to what you normally experience with host operating systems however this approach works well. RTEMS is not a host operating system and it is not a distrbution. Deploying binary packages for every possible host operating system is too big a task for the RTEMS Project and it is not a good use of core developer time. Their time is better spent making RTEMS better and faster.
The RTEMS Project’s aim is to give you complete freedom to decide on the languages used in your project, which version control system, and the build system for your application.
The rule for selecting a computer for a developer is more is better
but we do understand there are limits. Projects set up different configurations, some have a development machine per developer while others set up a tightly controlled central build server. RTEMS Ecosystem is flexible and lets you engineer a development environment that suites you. The basic specs are:
Multicore processor
8G bytes RAM
256G harddisk
RTEMS makes no demands on graphics.
If you are using a VM or your host computer is not a fast modern machine do not be concerned. The tools may take longer to build than faster hardware however building tools is something you do once. Once the tools and RTEMS are built all your time can be spent writing and developing your application. It may take longer than an hour for the ARM architecture and with all BSPs it can be many hours.
4.1. Python#
RTEMS uses Python in a range of host tools for users and developer. RTEMS supports:
Python3 and Python2 for user tools,
Python3 for developer tools.
Python2 is now end of life however the RTEMS Project will continue to provide support for its user commands. We do this to support older host operating systems some users may be forced to use. At some point the project will drop support for Python2 so we recommend users look at ways to transition to Python3 if it is not easily available.
Developers of RTEMS are required to have Python3 available. RTEMS tools used by developers for the development and maintenance of RTEMS are Python3 only.
All RTEMS Tools that can be invoked from the command line start with the following line:
#! /usr/bin/env python
The env
command is available on all POSIX host operating systems and it searches the $PATH
environment variable for the python
command invoking it with the script as the first argument. This means you need to have a suitable python
command on your host to run the RTEMS user tools. Not all hosts provide a python
command. If your host does not you need to find a way to provide one. The following are some examples you can use to solve this problem.
Python2 by default always provides a python
command.
4.1.1. Virtual Environment#
Python3 provides virtual environment support. This is a great way to manage Python on a single host. You can have a number of virtual environments with a different mix of installed Python packages with different versions that do not clash.
Virtual environment always provide a python
command. This makes it ideal if your host only provides Python3 and there is no default python
command.
A virtual environment is created once and when you need to use it you activate it and when finished you deactivate it.
The following shows how to create a virtual environment using different methods. You can select the method that best suites you.
To create a virtual environment using the Python3 venv
module:
python3 -m venv rtems-py
To create a virtual environment for a specific version of Python3 you can enter the command:
python3.7 -m venv rtems-py
You can also install the virtualenv
package on your host if it is avaliable then enter the following create command:
virtualenv rtems-py
To activate the virtual environment:
. rtems-py/bin/activate
You will see your prompt change to reflect the virtual environment you have active. To check if you now have a python
command enter:
type python
The output will be something similar to the following:
(rtems-py) $ type python
python is /home/chris/development/rtems-py/bin/python
4.1.2. Symbolic Link#
If your host does not provide the python
command you can add a symbolic link to it.
Note
We recommend you do not add the symbolic link in any of your operating system controlled directories as it is changing your operating system.
We suggest you add the symbolic link to a directory under your home directory adding that directory to your environment’s PATH
variable. The following commands show how to do this:
cd
mkdir bin
cd bin
ln -s `command -v python3` python
export PATH=$HOME/bin:$PATH
Note
You will need to modify your shell’s initialization scripts to make the PATH
change permanent.
4.1.3. Directly Invoking Python#
It is valid to specifically invoke any python script directly. To do this simply prepend the specific version of python you wish to use. For example to run the waf
build system command with Python3 use:
python3 ./waf
4.2. Host Operating Systems#
A wide range of host operating systems and hardware can be used. The host operating systems supported are:
Linux
FreeBSD
NetBSD
Apple OS X
Windows
Solaris
The functionality on a POSIX operating such as Linux and FreeBSD is similar and most features on Windows are supported but you are best to ask on the Users Mailing List if you have a specific question.
We recommend you maintain your operating system by installing any updates.
We also recommend you keep your environment to the bare minimum, particularly the PATH variable. Using environment variables has been proven over the years to be difficult to manage in production systems.
Warning
The RSB assumes your host is set up and the needed packages are installed and configured to work. If your host has not been set up please refer to section that covers your host’s packages you need to install.
Warning
Do not put spaces or special characters in the directories you use to build RTEMS. Many of the packages built by the RSB use GNU make, which cannot handle spaces in pathnames. If there is a space in the pathname the build will fail. Special characters are also likely to confuse build systems.
Note
RSB and RTEMS have a matching git branch for each version of RTEMS. For example, if you want to build a toolchain for 4.11, then you should checkout the 4.11 branch of the RSB:
$ git checkout -t origin/7.0
Branches are available for the 4.9, 4.10, 4.11 and 5 versions of RTEMS.
4.3. POSIX Hosts#
POSIX hosts are most Unix operating systems such as Linux, FreeBSD and NetBSD. RTEMS development works well on Unix and can scale from a single user and a desktop machine to a team with decentralised or centralised development infrastructure.
4.3.1. Root Access#
You either have root
access to your host development machine or you do not. Some users are given hardware that is centrally managed. If you do not have root
access you can create your work environment in your home directory. You could use a prefix of $HOME/development/rtems
or $HOME/rtems
. Note, the $HOME
environment variable can be substituted with ~
.
Choose an Installation Prefix details using Prefixes to manage the installation.
RTEMS Tools and packages do not require root
access to be built and we encourage you to not build the tools as root
. If you need to control write access then it is best to manage this with groups assigned to users.
If you have root
access you can decide to install the tools under any suitable prefix. This may depend on the hardware in your host development machine. If the machine is a centralised build server the prefix may be used to separate production versions from the test versions and the prefix paths may have restricted access rights to only those who manage and have configuration control of the machine. We call this project sandboxing and Project Sandboxing explains this in more detail.
4.3.2. Linux#
BSP Build will require pax
package if RTEMS is configured with the --enable-tests
option, see Building RTEMS Tests. This package is not installed , by default, on many Linux distributions, you can check for it using your package manager. Install it, if it is not present on your system.
A number of different Linux distrubutions are known to work. The following have been tested and report as working.
4.3.2.1. ArchLinux#
The following packages are required on a fresh Archlinux 64bit installation:
# pacman -S base-devel gdb xz unzip ncurses git zlib
Archlinux, by default installs texinfo-5
which is incompatible for building GCC 4.7 tree. You will have to obtain texinfo-legacy
from AUR
and provide a manual override:
# pacman -R texinfo
$ yaourt -S texinfo-legacy
# ln -s /usr/bin/makeinfo-4.13a /usr/bin/makeinfo
4.3.2.2. CentOS#
The following packages are required on a minimal CentOS 6.3 or CentOS 7 64-bit installation:
# yum install autoconf automake binutils gcc gcc-c++ gdb make patch pax \
bison flex xz unzip ncurses-devel texinfo zlib-devel python-devel git
On CentOS 8, the pax
command is now provided by the spax
package, you need to enable the PowerTools repository. and use Python3. On a fresh install, the following commands should install everything you need for RTEMS development:
# dnf install yum-utils
# dnf config-manager --set-enabled PowerTools
# dnf update
# dnf groupinstall "Development Tools"
# dnf install python3 python3-pip python3-setuptools python3-devel
# dnf install texinfo spax
# alternatives --set python /usr/bin/python3
The minimal CentOS distribution is a specific DVD that installs a minimal system. If you use a full system some of these packages may have been installed.
4.3.2.3. Rocky#
On Rocky Linux 9 the PowerTools has been renamed as crb
. On a fresh install, the following commands should install everything you need for RTEMS development:
# dnf install yum-utils
# dnf config-manager --enable crb
# dnf update
# dnf groupinstall "Development Tools"
# dnf install python3 python3-pip python3-setuptools python3-devel
# dnf install texinfo
At present there does not seem to be a solution for pax
on Rocky 9.
4.3.2.4. Fedora#
The RTEMS Source Builder has been tested on Fedora 19 64bit with the following packages:
# yum install ncurses-devel python-devel git bison gcc cvs gcc-c++ \
flex texinfo patch perl-Text-ParseWords zlib-devel
4.3.2.5. Raspbian#
The is the Debian distribution for the Raspberry Pi. The following packages are required:
$ sudo apt-get install autoconf automake bison flex binutils gcc g++ gdb \
texinfo unzip ncurses-dev python-dev git
It is recommended you get Model B of the Pi with 512M of memory and to mount a remote disk over the network. The tools can be built on the network disk with a prefix under your home directory as recommended and end up on the SD card.
4.3.2.6. Ubuntu#
The latest version is Ubuntu 24.04 LTS 64-bit. This section also includes Xubuntu. A minimal installation was used and the following packages installed:
$ sudo apt install build-essential g++ gdb unzip pax bison flex texinfo \
python3-dev python-is-python3 libncurses-dev zlib1g-dev \
ninja-build pkg-config
The name of packages changes over time. You need the package with Python development libraries for C/C++ programs. The following is needed for recent versions:
$ sudo apt-get install python git
It is likely necessary that you will have to enable the Ubuntu Source Repositories. Users have suggested the following web pages which have instructions:
4.3.2.7. Linux Mint#
zlib package is required on Linux Mint. It has a different name (other than the usual zlib-dev):
# sudo apt-get install zlib1g-dev
4.3.2.8. openSUSE#
The RTEMS Source Builder has been tested on openSUSE Leap 15.4 64bit. Starting with a clean install with source repositories enabled, the following zypper command installs the required packages:
# sudo zypper in -t pattern devel_C_C++ devel_python3
In addition, the following command can set python3 as the default python interpreter:
# sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
4.3.3. FreeBSD#
The RTEMS Source Builder has been tested on FreeBSD 9.1, 10.3, 11 and 12 64bit versions. You need to install some ports. They are:
# pkg install -y python
# pkg install -y gsed
For FreeBSD 13, you will need to install the packages listed above, as well as the following additional ones. They are:
# pkg install -y bison texinfo gmake binutils
FreeBSD’s default C compiler is LLVM and installing the host’s GCC compiler package may break building GCC. We recommend you do not install the GCC package and you use the default C compiler.
If you wish to build Windows (mingw32) tools please install the following ports:
# pkg install -y mingw32-binutils mingw32-gcc
# pkg install -y mingw32-zlib mingw32-pthreads
The zlip and pthreads ports for MinGW32 are used when builiding a Windows QEMU.
Check if your kernel has a /dev/fd
directory. If it does not we recommend you run as root the following command to speed up Python 3’s subprocess support:
# mount -t fdescfs none /dev/fd
The support speeds up closing file descriptors when creating subprocesses.
4.3.4. NetBSD#
The RTEMS Source Builder has been tested on NetBSD 6.1 i386. Packages to add are:
# pkg_add ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/6.1/devel/gmake-3.82nb7.tgz
# pkg_add ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/6.1/devel/bison-2.7.1.tgz
# pkg_add ftp://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/6.1/archivers/xz-5.0.4.tgz
4.4. Apple macOS#
Apple’s macOS is supported. You need to download and install a recent version of the Apple developer application Xcode. Xcode is available in the App Store. Make sure you install the Command Line Tools add on available for download within Xcode and once installed open a Terminal shell and enter the command cc
and accept the license agreement.
The normal prefix when working on macOS as a user is under your home directory. Prefixes of $HOME/development/rtems
or $HOME/rtems
are suitable.
Choose an Installation Prefix details using Prefixes to manage the installation.
Homebrew and Macports should work but are not tested by the project as they are rolling releases making it difficult to reproduce any problems there may be. We recommend reaching out to those projects for support.
Intel and Apple silicon is supported.
4.4.1. Python#
Building GDB requires the installation of Python’s development libraries. Building GDB includes the Python runtime header Python.h
and linking to the Python runtime libraries. The RSB detects a valid header and libraries before starting a GDB build.
It is recommended you run the RSB in a Python virtual environment. A virtual environment manages paths for you, provides a python
executable mapped to the version the virtual environment is built with and a command to find the appropiate runtime header and library files GDB needs. Virtual environments make it easier to update Python to a newer version if this is needed.
Apple has removed support for Python’s development libraries from recent versions of MacOS as users can manage Python using the installer packages provided by the Python project.
To install:
Download a Python installer for MacOS from https://www.python.org/.
Run the installer and install Python.
Open a terminal and update your shell profile using the command Python provides. For Python 3.12 the command is:
/Applications/Python\ 3.12/Update\ Shell\ Profile.command
Check with:
% type python3.12 python3.12 is /Library/Frameworks/Python.framework/Versions/3.12/bin/python3.12
Create a virtual environment:
mkdir $HOME/development/rtems cd $HOME/development/rtems python3.12 -m venv py3.12
Activate the virtual environment:
. $HOME/development/rtems/py3.12/bin/activate
You are now ready to the build the tools within the virtual environment.
4.4.2. Sonoma#
The RSB is supported on Sonoma and Applie silicon.
4.4.3. Ventura#
The RSB is supported on Ventura and Intel silicon.
4.4.4. Monterey#
The RSB is supported on Ventura and Intel silicon.
4.4.5. Catalina#
In the macOS Catalina 10.15 Release Notes Apple deprecated several scripting language runtimes such as Python 2.7. See also Xcode 11 Release Notes. Due to the deprecated Python 2.7 support, we recommend to install and use the latest Python 3 release from python.org.
4.4.6. Sierra#
The RSB works on Sierra with the latest Xcode.
4.4.7. Mavericks#
The RSB works on Mavericks and the GNU tools can be built for RTEMS using the Mavericks clang LLVM tool chain. You will need to build and install a couple of packages to make the RSB pass the sb-check
. These are CVS and XZ. You can get these tools from a packaging tool for macOS such as MacPorts or HomeBrew.
I do not use third-party packaging on macOS and prefer to build the packages from source using a prefix of /usr/local
. There are good third-party packages around however they sometimes bring in extra dependence and that complicates my build environment and I want to know the minimal requirements when building tools. The following are required:
- . The XZ package’s home page is http://tukaani.org/xz/ and I use version
5.0.5. XZ builds and installs cleanly.
4.5. Microsoft Windows#
RTEMS supports Windows as a development host and the tools for most architectures are available. The RTEMS Project relies on the GNU tools for compilers and debuggers and we use the simulators that come with GDB and QEMU. The Windows support for these tools varies and the RTEMS Project is committed to helping the open source community improve the Windows experience. If something is not working or supported please email the Users Mailing List.
The RTEMS Project’s Windows tools can be native Windows executables which give the user the best possible experience on Windows. Native Windows programs use the standard Windows DLLs and paths. Integration with standard Windows integrated development tools such as editors is straight forward. POSIX emulation environments such as Cygwin and the MSYS2 shell have special executables that require a POSIX emulation DLL and these emulation DLLs add an extra layer of complexity as well as a performance over-head. The RTEMS Project uses these POSIX emulation shells to run configure scripts that come with various open source packages such as gcc
so they form an important and valued part of the environment we describe here. The output of this procedure forms the tools you use during your application development and they do not depend on the emulation DLLs.
The performance of a native Windows compiler is as good as you can have on Windows and the performance compiling a single file will be similar to that on a host like Linux or FreeBSD given the same hardware. Building the tools from source is much slower on Windows because POSIX shells and related tools are used and the POSIX emulation overhead it much much slower than a native POSIX operating system like Linux and FreeBSD. This overhead is only during the building of the tools and the RTEMS kernel and if you use a suitable build system that is native to Windows your application development should be similar to other operating systems.
Building is known to work on Windows 7 64bit Professional
and Windows 10 64bit
.
4.5.1. Windows Path Length#
Windows path length is limited and can cause problems when building the tools. The standard Windows API has a MAX_PATH
length of 260 characters. This can effect some of the tools used by RTEMS. It is recommended you keep the top level directories as short as possible when building the RTEMS tools and you should also keep an eye on the path length when developing your application. The RTEMS built tools can handle much longer path lengths however some of the GNU tools such as those in the binutils
package cannot.
The release packages of the RSB when unpacked have top level file names that are too big to build RTEMS. You need to change or rename that path to something smaller to build. This is indicated in released-version.
4.5.2. Windows Spaces In Paths#
Occasionally, a program will fail on Windows with errors that appear as if a directory or file name was partially parsed by some utility or program. This can be caused by having directories of file names with spaces. Programs written in scripting languages sometimes fail to properly quote file names and the space is incorrectly interpreted.
Parts of the PATH inherited from the native Windows environment often include directory names with spaces. Sometimes it is necessary to set the PATH explicitly to avoid these.
4.5.3. Parallel Builds with Make#
The MSYS2 GNU make
has problems when using the jobs
option. The RSB defaults to automatically using as many cores as the host machine has. To get a successful build on Windows it is recommended you add the --jobs=none
option to all RSB build set commands.
4.5.4. POSIX Support#
Building the RTEMS compilers, debugger, the RTEMS kernel and a number of other third-party packages requires a POSIX environment. On Windows you can use Cygwin or MSYS2. This document focuses on MSYS2. It is smaller than Cygwin and comes with the Arch Linux package manager pacman
.
MSYS2 provides MinGW64 support as well as a POSIX shell called MSYS2. The MinGW64 compiler and related tools produce 64bit native Windows executables. The shell is a standard Bourne shell and the MSYS2 environment is a stripped Cygwin shell with enough support to run the various configure
scripts needed to build the RTEMS tools and the RTEMS kernel.
MSYS2 is built around the pacman
packaging tool. This makes MSYS2 a distribution and that is a welcome feature on Windows. You get a powerful tool to manage your development environment on Windows.
4.5.5. Python#
We need Python to build the tools as the RSB is written in Python and we need suitable Python libraries to link to GDB as RTEMS makes use of GDB’s Python support. This places specific demands on the Python we need installed and available and MSYS2 provides suitable Python versions we can use. You need to make sure you have the correct type and version of Python installed.
We cannot use the Python executables created by the Python project (python.org) as they are built by Microsoft’s C (MSC) compiler. Linking the MSC Python libraries with the MinGW64 executables is not easy and MSYS provides us with a simple solution so we do not support linking MSC libraries.
MSYS2 provides two types and two versions of Python executables, MinGW and MSYS and Python version 2 and 3. For Windows we need the MinGW executable so we have suitables libraries and we have to have Python version 2 because on Windows GDB only builds with Python2.
You also need to install the MSYS version of Python along with the MinGW64 Python2 package. The MSYS Python is version 3 and the RSB can support version 2 and 3 of Python and it helps handle some of the long paths building GCC can generate.
4.5.6. MSYS2#
MSYS2 is installed on a new machine using the MSYS2 installer found on https://msys2.github.io/. Please select the x86_64
variant for 64bit support. Run the installer following the 7 steps listed on the page.
MSYS2 uses the pacman
package manager. The Arch Linux project has detailed documentation on how to use pacman
. What is shown here is a just few examples of what you can do.
Open a 64bit MSYS shell from the Start Menu:
Note
If you ever see error: no hosts defaults found; please add
you have probably opened an MSYS2 32bit Shell. Close all 32bit Shell windows and open the MSYS2 64bit Shell.
The packages we require are:
python
mingw-w64-x86_64-python2
mingw-w64-x86_64-python3
mingw-w64-x86_64-gcc
flex
git
bison
cvs
diffutils
make
patch
tar
texinfo
unzip
Note
The actual output provided may vary due to changes in the dependent packages or newer package versions.
Install the packages using pacman
:
$ pacman -S python mingw-w64-x86_64-python3 mingw-w64-x86_64-python2 \
mingw-w64-x86_64-gcc \
bison flex cvs diffutils git make patch tar texinfo unzip
resolving dependencies...
looking for conflicting packages...
.... output shortened for brevity ....
The base installer executable puts the compiler you want to use in /mingw64/bin
which needs to be added to the beginning of your PATH
. You can do that for example by adding this line to the end of ${HOME}/.bashrc
:
export PATH=/mingw64/bin:$PATH
You will also likely want to add to PATH
the bin
directory of the prefix where you plan to install RTEMS.
4.5.7. Cygwin#
Building on Windows is a little more complicated because the Cygwin shell is used rather than the MSYS2 shell. The MSYS2 shell is simpler because the detected host triple is MinGW so the build is a standard cross-compiler build. A Canadian cross-build using Cygwin is supported if you would like native tools or you can use a Cygwin built set of tools.
Install a recent Cygwin version using the Cygwin setup tool. Select and install the groups and packages listed:
Group | Package |
Archive | bsdtar |
Archive | unzip |
Archive | xz |
Devel | autoconf |
Devel | autoconf2.1 |
Devel | autoconf2.5 |
Devel | automake |
Devel | binutils |
Devel | bison |
Devel | flex |
Devel | gcc4-core |
Devel | gcc4-g++ |
Devel | git |
Devel | make |
Devel | mingw64-x86_64-binutils |
Devel | mingw64-x86_64-gcc-core |
Devel | mingw64-x86_64-g++ |
Devel | mingw64-x86_64-runtime |
Devel | mingw64-x86_64-zlib |
Devel | patch |
Devel | zlib-devel |
MinGW | mingw-zlib-devel |
Python | python |
The setup tool will add a number of dependent package and it is ok to accept them.
Disabling Windows Defender improves performance if you have another up to date virus detection tool installed and enabled. The excellent Process Hacker 2
tool can monitor the performance and the Windows Defender service contributed a high load. In this case a third-party virus tool was installed so the Windows Defender service was not needed.
To build a MinGW tool chain a Canadian cross-compile (Cxc) is required on Cygwin because the host is Cygwin therefore a traditional cross-compile will result in Cygiwn binaries. With a Canadian cross-compile a Cygwin cross-compiler is built as well as the MinGW RTEMS cross-compiler. The Cygwin cross-compiler is required to build the C runtime for the RTEMS target because we are building under Cygiwn. The build output for an RTEMS 4.10 ARM tool set is:
chris@cygwin ~/development/rtems/src/rtems-source-builder/rtems
$ ../source-builder/sb-set-builder --log=l-arm.txt \
--prefix=$HOME/development/rtems/7.0 4.10/rtems-arm
RTEMS Source Builder - Set Builder, v0.2
Build Set: 4.10/rtems-arm
config: expat-2.1.0-1.cfg
package: expat-2.1.0-x86_64-w64-mingw32-1
building: expat-2.1.0-x86_64-w64-mingw32-1
reporting: expat-2.1.0-1.cfg -> expat-2.1.0-x86_64-w64-mingw32-1.html
config: tools/rtems-binutils-2.20.1-1.cfg
package: arm-rtems4.10-binutils-2.20.1-1 <1>
building: arm-rtems4.10-binutils-2.20.1-1
package: (Cxc) arm-rtems4.10-binutils-2.20.1-1 <2>
building: (Cxc) arm-rtems4.10-binutils-2.20.1-1
reporting: tools/rtems-binutils-2.20.1-1.cfg ->
arm-rtems4.10-binutils-2.20.1-1.html
config: tools/rtems-gcc-4.4.7-newlib-1.18.0-1.cfg
package: arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1
building: arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1
package: (Cxc) arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1
building: (Cxc) arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1
reporting: tools/rtems-gcc-4.4.7-newlib-1.18.0-1.cfg ->
arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1.html
config: tools/rtems-gdb-7.3.1-1.cfg
package: arm-rtems4.10-gdb-7.3.1-1
building: arm-rtems4.10-gdb-7.3.1-1
reporting: tools/rtems-gdb-7.3.1-1.cfg -> arm-rtems4.10-gdb-7.3.1-1.html
config: tools/rtems-kernel-4.10.2.cfg
package: arm-rtems4.10-kernel-4.10.2-1
building: arm-rtems4.10-kernel-4.10.2-1
reporting: tools/rtems-kernel-4.10.2.cfg -> arm-rtems4.10-kernel-4.10.2-1.html
installing: expat-2.1.0-x86_64-w64-mingw32-1 -> /cygdrive/c/Users/chris/development/rtems/7.0
installing: arm-rtems4.10-binutils-2.20.1-1 -> /cygdrive/c/Users/chris/development/rtems/7.0 <3>
installing: arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1 -> /cygdrive/c/Users/chris/development/rtems/7.0
installing: arm-rtems4.10-gdb-7.3.1-1 -> /cygdrive/c/Users/chris/development/rtems/7.0
installing: arm-rtems4.10-kernel-4.10.2-1 -> /cygdrive/c/Users/chris/development/rtems/7.0
cleaning: expat-2.1.0-x86_64-w64-mingw32-1
cleaning: arm-rtems4.10-binutils-2.20.1-1
cleaning: arm-rtems4.10-gcc-4.4.7-newlib-1.18.0-1
cleaning: arm-rtems4.10-gdb-7.3.1-1
cleaning: arm-rtems4.10-kernel-4.10.2-1
Build Set: Time 10:09:42.810547 <4>
Warning
Cygwin documents the ‘Big List Of Dodgy Apps’ or ‘BLODA’. The link is http://cygwin.com/faq/faq.html#faq.using.bloda and it is worth a look. You will see a large number of common pieces of software found on Windows systems that can cause problems. My testing has been performed with NOD32 running and I have seen some failures. The list is for all of Cygwin so I am not sure which of the listed programs effect the RTEMS Source Biulder. The following FAQ item talks about fork failures and presents some technical reasons they cannot be avoided in all cases. Cygwin and it’s fork MSYS are fantastic pieces of software in a difficult environment. I have found building a single tool tends to work, building all at once is harder.
5. Deployment#
Deployment is a process companies, organizations or teams use to control and manage delivery of RTEMS tools, kernels and third party libraries. Deployed tools, kernels and libraries are packaged and controlled so the same tools and libraries are used in all phases of a project.
The Quick Start guide details how tools are built using the RSB. The tools are installed on your development computer and available for you to build applications. That build can be viewed as the simplest form of deployment because it is simple and easy however it does not scale. Building the tools and kernel on each development machine in a project or company is time consuming, difficult to get right and costly to audit.
This section covers the building of tools, kernels and third party libraries using the RSB for deployment. Custom RSB buildset files are supported across releases giving you an easy update path. The RSB can generate a single tarfile for any prefix without needing to install the pieces built helping ease integration with packaging systems and continuous integration (CI) for automated workflows.
5.1. RSB Deployment#
The RSB provides support for deployment using custom buildset files. A custom buildset file resides outside the RSB and can build tools for a number of architectures and kernels for BSPs. Deployment can include third party libraries if a single BSP is being built.
The RSB --no-install
option builds the tools and kernel without the final installation phase. A prefix that is not accessible when running the RSB can be used. This is important if a CI flow is being used.
The buildset tar file option --bset-tar-file
packages the build’s staging directory tree into a single tar file. The tar file can be used as the input source to a packaging system.
Buildset configuration files can be tested by adding the --dry-run
option to the sb-set-builder
command line.
The buildset examples that follow assume the prefix path used does not exist or is not writable and the environment path does not include any RTEMS tools.
5.1.1. Deployment Repository#
Create a repository to hold a project’s buildset configuration files:
$ mkdir a-project
$ cd a-project
$ git init
Add the RSB as a sub-module:
$ git submodule add \
ssh://git@gitlab.rtems.org:2222/rtems/tools/rtems-source-builder.git
Create a configuration directory:
$ mkdir config
$ git add config
5.1.2. Tools Configuration#
This example will build a single tool set with a local configuration file.
Create a configuration file for the project
:
$ vi config/project-tools.bset
Add the following to the buildset configuration file:
#
# Project Tools
#
7/rtems-aarch64
Commit the changes to the repository:
$ git add config/project-tools.bset
$ git commit -m "Add project aarch64 tools buildset"
Build a tarfile containing the tools using the RSB submodule:
$ ./rtems-source-builder/source-builder/sb-set-builder \
--prefix=/opt/project --log=project.txt \
--bset-tar-file --no-install \
project-tools
Once the build has finished the tar
directory will contain the project
tools in a tarfile:
$ ls tar
project-tools.tar.bz2
Inspect the tarfile to check the path matches the prefix used to build the tools (sizes may vary):
$ tar Jtvf tar/project-tools.tar.bz2 | less
drwxr-xr-x 0 chris eng 0 Sep 6 14:27 opt/project/bin/
-rwxr-xr-x 0 chris eng 1320888 Sep 6 14:20 opt/project/bin/aarch64-rtems7-addr2line
-rwxr-xr-x 0 chris eng 1358688 Sep 6 14:20 opt/project/bin/aarch64-rtems7-ar
-rwxr-xr-x 0 chris eng 2381976 Sep 6 14:20 opt/project/bin/aarch64-rtems7-as
-rwxr-xr-x 0 chris eng 1328440 Sep 6 14:27 opt/project/bin/aarch64-rtems7-c++
-rwxr-xr-x 0 chris eng 1316240 Sep 6 14:20 opt/project/bin/aarch64-rtems7-c++filt
-rwxr-xr-x 0 chris eng 1328440 Sep 6 14:27 opt/project/bin/aarch64-rtems7-cpp
-rwxr-xr-x 0 chris eng 60792 Sep 6 14:20 opt/project/bin/aarch64-rtems7-elfedit
-rwxr-xr-x 0 chris eng 1328440 Sep 6 14:27 opt/project/bin/aarch64-rtems7-g++
-rwxr-xr-x 0 chris eng 1328440 Sep 6 14:27 opt/project/bin/aarch64-rtems7-gcc
-rwxr-xr-x 0 chris eng 1328440 Sep 6 14:27 opt/project/bin/aarch64-rtems7-gcc-12.1.1
-rwxr-xr-x 0 chris eng 48568 Sep 6 14:27 opt/project/bin/aarch64-rtems7-gcc-ar
-rwxr-xr-x 0 chris eng 48568 Sep 6 14:27 opt/project/bin/aarch64-rtems7-gcc-nm
-rwxr-xr-x 0 chris eng 48576 Sep 6 14:27 opt/project/bin/aarch64-rtems7-gcc-ranlib
.....
5.1.3. Tools and Kernel#
This example builds a single tool set and an RTEMS kernel for a BSP using a buildset defined BSP settings.
We use the same a-project
repository from the previous example and add a new configuration. Add a configuration file to build the tools and a BSP:
$ vi config/project-tools-bsp.bset
Add the following to the buildset configuration file and save:
#
# Project Tools and BSP
#
%define with_rtems_bsp aarch64/versal_aiedge
%define with_rtems_bspopts BSP_XILINX_VERSAL_NOCACHE_LENGTH=0x4000000 \
BSP_XILINX_VERSAL_RAM_LENGTH=0x200000000
7/rtems-aarch64
7/rtems-kernel
The configuration provides BSP options. Commit the changes to the repository:
$ git add config/project-tools-bsp.bset
$ git commit -m "Add project tools and BSP buildset"
Build a tarfile of the tools and BSP using the RSB submodule:
$ ./rtems-source-builder/source-builder/sb-set-builder \
--prefix=/opt/project --log=project.txt \
--bset-tar-file --no-install \
project-tools-bsp
A buildset configuration file that uses buildset BSP defines is limited to a single architecture and the tools built need to match the architecture of the BSP.
You can specify more than one BSP to be built. An updated configuration could be:
%define with_rtems_bsp aarch64/versal_aiedge \
aarch64/zynqmp_apu
This is useful when deploying more than one BSP. If you need multiple architectures and BSPs consider the Tools and Kernel With Config example.
Buildset BSP options are applied to all BSPs in the BSP list. If they are specific to a BSP only specify a single BSP in the BSP define.
RTEMS 5 supports this type of buildset file.
5.1.4. Tools and Kernel with Config#
This example builds tool sets for different architectures and multiple BSPs for the architectures using a kernel configuration INI file.
Tools for the arch64
and arm
architectures are built and three BSPs each with different options.
We use the same a-project
repository from the previous example and add the new configurations. Add a configuration file to build the tools and BSPs:
$ vi config/project-tools-bsp-config.bset
Add the following to the buildset configuration file and save:
#
# Project Tools and BSPs
#
%define with_rtems_bsp_config config/project-bsps.ini
7/rtems-aarch64
7/rtems-arm
7/rtems-kernel
Add a kernel configuration INI file:
$ vi config/project-bsps.bset
Add the following to the kernel configuration INI file and save:
#
# Project BSPs
#
[DEFAULT]
RTEMS_POSIX_API = True
BUILD_SAMPLES = True
BUILD_TESTS = False
[aarch64/versal_aiedge]
BSP_XILINX_VERSAL_NOCACHE_LENGTH = 0x4000000
BSP_XILINX_VERSAL_RAM_LENGTH = 0x200000000
[aarch64/zynqmp_apu]
RTEMS_SMP = True
[arm/xilinx_zynq_zc706]
RTEMS_SMP = True
BSP_XILINX_VERSAL_NOCACHE_LENGTH = 0x4000000
BSP_XILINX_VERSAL_RAM_LENGTH = 0x200000000
Commit the changes to the repository:
$ git add config/project-tools-bsp-config.bset
$ git add config/project-bsps.ini
$ git commit -m "Add project tools and BSPs buildset and kernel config"
Build a tarfile of the tools and BSPs using the RSB submodule:
$ ./rtems-source-builder/source-builder/sb-set-builder \
--prefix=/opt/project --log=project.txt \
--bset-tar-file --no-install \
project-tools-bsp-config
5.1.5. Tools, Kernel and Packages#
Third party libraries can be built as part of a single RSB configuration if only one BSP is built at a time. The RSB support for building packages does not support building for multiple BSPs.
We use the same a-project
repository from the previous example and add a new configuration. Add a configuration file to build the tools, BSPs and LibBSD:
$ vi config/project-aarch64-tools-bsp-libbsd.bset
Add the following to the buildset configuration file and save:
#
# Project Tools, BSP and LibBSD
#
%define with_rtems_bsp aarch64/versal_aiedge
%define with_rtems_bspopts BSP_XILINX_VERSAL_NOCACHE_LENGTH=0x4000000 \
BSP_XILINX_VERSAL_RAM_LENGTH=0x200000000
6/rtems-aarch64
6/rtems-kernel
6/rtems-libbsd
Commit the changes to the repository:
$ git add config/project-aarch64-tools-bsp-libbsd.bset
$ git commit -m "Add project aarch64 tools, BSP and libbsd"
Build a tarfile of the tools, BSP and LibBSD using the RSB submodule:
$ ./rtems-source-builder/source-builder/sb-set-builder \
--prefix=/opt/project --log=project.txt \
--bset-tar-file --no-install \
project-aarch64-tools-bsp-libbsd
The tarfile can be reviewed to see the BSP libraries built (sizes may vary):
$ tar jtvf tar/project-aarch64-tools-bsp-libbsd.tar.bz2 | \
grep -e '\.a$' | grep -e 'versal_aiedge'
-rw-r--r-- 0 chris eng 138936312 Sep 7 14:58 opt/project/aarch64-rtems7/versal_aiedge/lib/libbsd.a
-rw-r--r-- 0 chris eng 686190 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libdebugger.a
-rw-r--r-- 0 chris eng 164086 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libftpd.a
-rw-r--r-- 0 chris eng 107560 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libftpfs.a
-rw-r--r-- 0 chris eng 978812 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libjffs2.a
-rw-r--r-- 0 chris eng 412354 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libmghttpd.a
-rw-r--r-- 0 chris eng 2099962 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/librtemsbsp.a
-rw-r--r-- 0 chris eng 29693496 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/librtemscpu.a
-rw-r--r-- 0 chris eng 435236 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/librtemscxx.a
-rw-r--r-- 0 chris eng 141234 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/librtemsdefaultconfig.a
-rw-r--r-- 0 chris eng 856514 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/librtemstest.a
-rw-r--r-- 0 chris eng 159004 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libtelnetd.a
-rw-r--r-- 0 chris eng 137386 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libtftpfs.a
-rw-r--r-- 0 chris eng 476692 Sep 7 14:56 opt/project/aarch64-rtems7/versal_aiedge/lib/libz.a
5.1.6. Tools, Kernel with Config and Packages#
This example builds the tools, kernel and LibBSD using an RSB configuration file and a kernel configuration file. The kernel configuration provides easier kernel and BSP option management.
Third party libraries can be built as part of a single RSB configuration if only one BSP is built at a time. The RSB support for building packages does not support building for multiple BSPs.
We use the same a-project
repository from the previous example and add a new configuration. Add a configuration file to build the tools, BSPs and LibBSD:
$ vi config/project-aarch-tools-bsp-libbsd-config.bset
Add the following to the buildset configuration file and save:
#
# Project Tools, BSP and LibBSD
#
%define with_rtems_bsp_config config/project-aarch64-bsp.ini
6/rtems-aarch64
6/rtems-kernel
6/rtems-libbsd
Add a kernel configuration INI file:
$ vi config/project-aarch64-bsp.bset
Add the following kernel configuration INI file and save:
#
# Project Versal AI Edge BSP
#
[DEFAULT]
RTEMS_POSIX_API = True
BUILD_SAMPLES = True
BUILD_TESTS = False
[aarch64/versal_aiedge]
BSP_XILINX_VERSAL_NOCACHE_LENGTH = 0x4000000
BSP_XILINX_VERSAL_RAM_LENGTH = 0x200000000
Commit the changes to the repository:
$ git add config/project-aarch64-tools-bsp-libbsd-config.bset
$ git add config/project-aarch64-bsp.ini
$ git commit -m "Add project aarch64 tools, BSP (with config) and libbsd"
Build the tarfile of the tools, BSP and LibBSD using the RSB submodule:
$ ./rtems-source-builder/source-builder/sb-set-builder \
--prefix=/opt/project --log=project.txt \
--bset-tar-file --no-install \
project-aarch64-tools-bsp-libbsd-config
6. Target Hardware#
6.1. Targets#
Target hardware that can run RTEMS is often referred to simply as the target because RTEMS is specifically aimed at that target hardware. An RTEMS executable is statically linked and executes in a single address space on the target hardware. A statically linked executable means the RTEMS Kernel, drivers, third-party packages and application code is linked into a single executable image. A single address space means no virtual memory and no memory protected process address space is running within the RTEMS arena and the RTEMS executive, drivers and application have unprotected access to the whole address space and all hardware.
Target hardware supported by RTEMS has a Board Support Package or BSP. A BSP is a specific instance of an RTEMS architecture that allows the creation of an RTEMS executable. You can view the layering as:
RTEMS targets are grouped by architectures and within an architecture there are a number of Board Support Packages or BPSs. An architecture is a specific class or family of processors and can be large such as ARM or specific such as the NIOS-II or Microblaze.
RTEMS is designed to be ported to new target hardware easily and efficiently.
6.2. Architectures#
An RTEMS architecture is a class or family of a processor architecture that RTEMS supports. The RTEMS architecture model follows the architecture model of GCC. An architecture in GCC results in a specific RTEMS GCC compiler. This compiler may support a range of processors in the family that may have differences in instructions sets, floating point support or other aspects. RTEMS configures GCC to create separate runtime libraries for each supported instruction set, floating point unit, vector unit, word size (e.g. 32-bit and 64-bit), endianess, code model, ABI, processor errata workarounds, and so on in the architecture. This is termed multilib. Multilibs are chosen automatically by GCC via selecting a specific set of machine options.
You can query the multilibs of a specific RTEMS GCC compiler via the -print-multi-lib
option:
$ sparc-rtems5-gcc -print-multi-lib
.;
soft;@msoft-float
v8;@mcpu=v8
leon3;@mcpu=leon3
leon3v7;@mcpu=leon3v7
leon;@mcpu=leon
leon3/gr712rc;@mcpu=leon3@mfix-gr712rc
leon3v7/gr712rc;@mcpu=leon3v7@mfix-gr712rc
leon/ut699;@mcpu=leon@mfix-ut699
leon/at697f;@mcpu=leon@mfix-at697f
soft/v8;@msoft-float@mcpu=v8
soft/leon3;@msoft-float@mcpu=leon3
soft/leon3v7;@msoft-float@mcpu=leon3v7
soft/leon;@msoft-float@mcpu=leon
soft/leon3/gr712rc;@msoft-float@mcpu=leon3@mfix-gr712rc
soft/leon3v7/gr712rc;@msoft-float@mcpu=leon3v7@mfix-gr712rc
soft/leon/ut699;@msoft-float@mcpu=leon@mfix-ut699
soft/leon/at697f;@msoft-float@mcpu=leon@mfix-at697f
Each printed line represents a multilib. The .
corresponds to the default multilib. It is used if a set of machine options does not match to a specialized multilib. The string before the ;
describes the directory in the GCC installation used for the particular multilib. After the ;
the set of machine options for this multilib follows separated by @
characters.
You can figure out the multilib selected by GCC for a set of machine options with the -print-multi-directory
option:
$ sparc-rtems5-gcc -print-multi-directory -mcpu=leon3
leon3
It is crucial that the RTEMS BSP, support libraries and the application code are compiled consistently with a compatible set of machine options. Otherwise, in the best case errors during linking will occur or you may end up silently with undefined behaviour which results in sporadic run-time crashes. A wrong set of machine options may result in a running application, however, with degraded performance, e.g. hardware floating point unit is not used by the mathematical library.
For a list of architectures supported by RTEMS please have a look at the sections of the Board Support Packages chapter.
RTEMS executables are statically linked for a specific target therefore a precise and exact match can be made for the hardware that extracts the best possible performance. The compiler supports the variants to the instruction set and RTEMS extends the specialization to specific processors in an architecture. This specialization gives RTEMS a finer resolution of features and capabilities a specific device may offer allowing the kernel, drivers and application to make the most of those resources. The trade off is portability however this is not important because the executable are statically linked for a single target.
Note
RTEMS support dynamically load code through the dlopen
interface. Loading code via this interface results in an executable image that is equivalent to statically linked executable of the same code. Dynamic loading is a system level tool for system architects.
6.3. Tiers#
RTEMS has a tiered structure for architecture and BSPs. It provides:
A way to determine the state of a BSP in RTEMS.
A quaility measure for changes entering the RTEMS source code.
The RTEMS project supports RTEMS Architecture Tiers. Each architecture resided in one of the numbered tiers. The tiers are number 1 to 4 where Tier 1 is the highest tier and Tier 4 is the lowest. Architectures move between tiers based on the level of support and the level of testing that is performed. An architecture requires continual testing and reporting of test results to maintain a tier level. The RTEMS Project’s continuous integration testing program` continually monitors and reports the test results.
The RTEMS Architecture Tier system provides a defined way to determine the state of an architecture in RTEMS. Architectures age and support for them drops off and the RTEMS Project needs a way to determine if an architecture should stay and be supported or depreciated and removed. The tier system also provides users with a clear understanding of the state of an architecture in RTEMS, often useful when deciding on a processor for a new project. It can also let a user know the RTEMS Project needs support to maintain a specific architecture. Access to hardware to perform testing is a large and complex undertaking and the RTEMS Project is always looking for user support and help. If you can help please contact someone and let us know.
The tier structure in RTEMS is support by the Buildbot continuous integration server. Changes to RTEMS are automatically built and tested and the results indicate if a BSP currently meets its tier status. As the RTEMS Project does not own hardware for every BSP, it is critical that users provide test results on hardware of interest.
The rules for Tiers are:
A BSP can only be in one of the following tiers:
Tier
Description
1
The RTEMS Kernel must build without error.
Tests are run on target hardware.
2
The RTEMS Kernel must build without error.
Tests can be run on simulation.
3
The RTEMS Kernel must build without error.
There are no test results.
4
The RTEMS Kernel does not build.
5
The BSP is to be removed after the next release.
An architecuture’s tier is set by the highest BSP tier reached.
The tier level for a BSP is set by the RTEMS Project team. Movement of BSP between tier level requires agreement. The Buildbot results indicate the minimum current tier level.
Changes to RTEMS may result in a BSP not meeting its tier are acceptable if the change is accompanied by an announcement and a plan on how this is to be resolved. Temporary drops in tier are expected and should be brief.
Test results are set on a per BSP basis by the RTEMS Project team. Changes to the test result values requires agreement. The test results are defined as:
Passes
Expected Failures
Expected failures must be explicitly listed. A BSP is required to have a valid test result entry on target hardware to reach tier 1.
7. BSP Build System#
The purpose of the build system is to produce and install artefacts from the RTEMS sources such as static libraries, start files, linker command files, configuration header files, header files, test programs, package description files, and third-party build system support files for a specific BSP in a user controlled configuration.
7.1. Overview#
The build system consists of three components which are all included in the RTEMS sources
the waf meta build system command line tool,
a wscript file used by
waf
, anda set of build specification items maintained by a text editor just like other source files.
The build system is controlled by the user through
commands passed to the
waf
command line tool,command line options passed to
waf
, andconfiguration files (e.g.
config.ini
) used bywscript
throughwaf
invocations.
Configurable things which are subject to a local installation variant such as paths to tools are intended to be passed as command line options to the waf
command line tool. Which BSPs are built and how they are configured by means of options is placed in configuration files (e.g. config.ini
). The configuration files may reside anywhere in the file system and the goal is to have it under version control by the user.
7.2. Work Flow#
There are five steps necessary to build and install one or more BSPs.
Select which BSPs you want to build. See also Deployment and
./waf bsplist
.Write a BSP build configuration file (e.g.
config.ini
) which determines which BSPs are built and how they are configured.Run the
./waf configure
command to generate the build environment.Build the BSP artefacts with
./waf
. The build uses the build environment created by./waf configure
. The BSP build configuration file (e.g.config.ini
) is no longer used and may be deleted.Install the BSP artefacts with
./waf install
.
7.3. Commands#
The build system is controlled by invocations of the ./waf
command line tool instead of the well known make
. Since waf is written in Python, a standard Python 2.7 or 3 installation without third-party packages is required to run it. The ./waf
command line tool must be invoked in the RTEMS source tree top-level directory.
Some commands accept the --rtems-specs
command line option. This option specifies paths to build specification items. It is an advanced option and there is normally no need to use it. It may be used to customize the build at the level of the build specification. For more information see the Build System
chapter of the RTEMS Software Engineering guide.
7.3.1. Help#
Use ./waf --help
to get a list of commands and options.
7.3.2. BSP List#
The BSP list command ./waf bsplist
loads the build specification items and generates a list of base BSPs from it. The list is sorted by architecture and base BSP name. Which base BSPs are listed can be controlled by the --rtems-bsps
command line option. It expects a comma-separated list of Python regular expressions which select the desired BSP variants. The path to the build specification items can be specified by the --rtems-specs
command line option.
$ ./waf bsplist --rtems-bsps=sparc/
sparc/at697f
sparc/erc32
sparc/gr712rc
sparc/gr740
sparc/leon2
sparc/leon3
sparc/ut699
sparc/ut700
$ ./waf bsplist --rtems-bsps='/leon,/rv64imac$'
riscv/rv64imac
sparc/leon2
sparc/leon3
7.3.3. BSP Defaults#
The BSP defaults command ./waf bspdefaults
loads the build specification items and generates a list options with default values for each base BSP from it. The list is sorted by architecture and base BSP name. Which base BSPs are listed can be controlled by the --rtems-bsps
command line option. Default values may depend on the selected compiler. The compiler can be specified by the --rtems-compiler
command line option. The path to the build specification items can be specified by the --rtems-specs
command line option.
$ ./waf bspdefaults --rtems-bsps=gr712rc --rtems-compiler=gcc | grep ABI_FLAGS
ABI_FLAGS = -mcpu=leon3 -mfix-gr712rc
$ ./waf bspdefaults --rtems-bsps=gr712rc --rtems-compiler=clang | grep ABI_FLAGS
ABI_FLAGS = -mcpu=gr712rc
7.3.4. Configure#
The configure command ./waf configure
loads the BSP build configuration files and the build specification items and configures the build environment accordingly. The configuration files can be specified by the --rtems-config
command line option. It expects a comma-separated list of paths to the configuration files. By default, the file config.ini
is used. The paths to RTEMS tools can be specified by the --rtems-tools
command line option. It expects a comma-separated list of prefix paths to tools, e.g. compiler, linker, etc. By default, the installation prefix is used for the RTEMS tools. Tools are searched in the prefix path and also in a bin
subdirectory of the prefix path. The path to the build specification items can be specified by the --rtems-specs
command line option.
7.3.5. Build, Clean, and Install#
The commands ./waf
, ./waf clean
, and ./waf install
load the build specification items according to the specification paths stored in the build environment. The BSP build configuration files (e.g. config.ini
) used by the ./waf configure
command to create the build environment are not longer used and may be deleted. The build commands perform a dependency tracking and re-build artefacts if input sources changed. Input sources are also the build specification.
7.4. Configuration#
The BSP build configuration is done via INI-style configuration files. The configuration files are consumed by the ./waf configure
command. By default, the file config.ini
is used. You can specify other configuration files with the --rtems-config
command line option. The configuration files consist of sections and options (key-value pairs).
To build a particular BSP, you have to create a section with the BSP variant name.
[sparc/erc32]
This one line configuration file is sufficient to build the base BSP sparc/erc32
with default values for all options. The base BSPs are determined by the build specification. The ./waf bsplist
command lists all base BSPs. You can create your own BSP names. However, in this case you have to inherit from a base BSP. The inheritance works only within an architecture, e.g. a riscv
BSP cannot inherit options from an arm
BSP.
[sparc/foobar]
INHERIT = erc32
The inheritance works recursively and must end up in a base BSP.
[sparc/foo]
INHERIT = erc32
[sparc/bar]
INHERIT = foo
A child BSP variant inherits all options from the parent BSP variant. The child BSP can override the inherited options.
You can determine the compiler used to build the BSP with the COMPILER
option.
[sparc/gr740_gcc]
INHERIT = gr740
COMPILER = gcc
[sparc/gr740_clang]
INHERIT = gr740
COMPILER = clang
Use the ./waf bspdefaults
command to get a list of all configuration options with default values.
$ ./waf bspdefaults --rtems-bsps=sparc/erc32
[sparc/erc32]
# Flags passed to the library archiver
ARFLAGS = crD
# Warning flags passed to the C compiler
CC_WARNING_FLAGS = -Wmissing-prototypes -Wimplicit-function-declaration -Wstrict-prototypes -Wnested-externs
# Warning flags passed to the C++ compiler
CXX_WARNING_FLAGS =
# Flags passed to the linker (GNU ld)
LDFLAGS = -Wl,--gc-sections
# Enable the Ada support
__RTEMS_ADA__ = False
# Enable the RTEMS internal debug support
RTEMS_DEBUG = False
...
# Install the legacy application Makefile framework.
INSTALL_LEGACY_MAKEFILES = True
It is not recommended to blindly add all the options obtained through the ./waf bspdefaults
command to custom configuration files. The specified options should be kept at the necessary minimum to get the desired build.
Some projects may still want to specify all options in a configuration file to be independent of changes in the base BSP. You can review differences between the user and base BSP values with the diff
command.
$ ./waf bspdefaults --rtems-bsps=sparc/erc32 > config.ini
$ sed -i 's/BUILD_TESTS = False/BUILD_TESTS = True/' config.ini
$ ./waf bspdefaults --rtems-bsps=sparc/erc32 | diff -u - config.ini
--- config.ini 2019-12-04 08:21:36.049335872 +0100
+++ - 2019-12-04 08:21:41.187432405 +0100
@@ -31,7 +31,7 @@
# Build the Ada test programs (may be also enabled by BUILD_TESTS)
BUILD_ADATESTS = False
# Build the test programs
-BUILD_TESTS = False
+BUILD_TESTS = True
# Build the benchmark programs (may be also enabled by BUILD_TESTS)
BUILD_BENCHMARKS = False
# Build the file system test programs (may be also enabled by
There is a special section DEFAULT
which can be used to specify default values for all other sections of the configuration file. In the following example configuration file, building of the tests is enabled for the sparc/erc32
and the riscv/griscv
BSP.
[DEFAULT]
BUILD_TESTS = True
[sparc/erc32]
[riscv/griscv]
7.5. Migration from Autoconf/Automake#
The Autoconf/Automake based build system used a configure
command to configure a single target architecture and one or more BSPs. The make
command was used to build it. The configure
command is replaced by a ./waf configure
invocation with configuration file. The make
command is replaced by ./waf
and make install
is replaced by ./waf install
.
Here are some hints for how a configure command line can be converted to options in the configuration file of the waf
based build system. BSP options given at the configure command line have to be added to the BSP section in the configuration file.
--target=${arch}-rtems6
--enable-rtembsp=${bsp}
To build a BSP add
[${arch}/${bsp}]
to the configuration file.--enable-ada
|--disable-ada
Set
__RTEMS_ADA__
toTrue
orFalse
in the BSP section of the configuration file.--enable-multiprocessing
|--disable-multiprocessing
Set
RTEMS_MULTIPROCESSING
toTrue
orFalse
in the BSP section of the configuration file.--enable-paravirt
|--disable-paravirt
Set
RTEMS_PARAVIRT
toTrue
orFalse
in the BSP section of the configuration file.--enable-profiling
|--disable-profiling
Set
RTEMS_PROFILING
toTrue
orFalse
in the BSP section of the configuration file.--enable-posix
|--disable-posix
Set
RTEMS_POSIX_API
toTrue
orFalse
in the BSP section of the configuration file.--enable-rtems-debug
|--disable-rtems-debug
Set
RTEMS_DEBUG
toTrue
orFalse
in the BSP section of the configuration file.--enable-smp
|--disable-smp
Set
RTEMS_SMP
toTrue
orFalse
in the BSP section of the configuration file.--enable-tests
|--disable-tests
Set
BUILD_TESTS
toTrue
orFalse
in the BSP section of the configuration file.--enable-tests=samples
Set
BUILD_SAMPLES
toTrue
orFalse
in the BSP section of the configuration file.
Please have a look at the following example configuration file.
# --target=sparc-rtems6 --enable-rtemsbsp=erc32
[sparc/erc32]
# --enable-ada
__RTEMS_ADA__ = True
# --enable-multiprocessing
RTEMS_MULTIPROCESSING = False
# --disable-paravirt
RTEMS_PARAVIRT = False
# --enable-profiling
RTEMS_PROFILING = True
# --disable-posix
RTEMS_POSIX_API = False
# --enable-rtems-debug
RTEMS_DEBUG = True
# --disable-smp
RTEMS_SMP = False
# --enable-tests
BUILD_TESTS = True
# BSP_POWER_DOWN_AT_FATAL_HALT=
BSP_POWER_DOWN_AT_FATAL_HALT = False
8. Board Support Packages#
A Board Support Package or BSP is the software that glues a specific target or board or piece of hardware to RTEMS so it’s services are available to applications.
RTEMS contains a large number of BSPs for commonly available simulators and target hardware.
You can see the current BSP list in the RTEMS sources by asking RTEMS with:
$ ./rtems-bsps
8.1. aarch64 (AArch64)#
8.2. arm (ARM)#
8.2.1. altera-cyclone-v (Intel Cyclone V)#
This BSP offers only one variant, the altcycv_devkit
. This variant supports the Intel Cyclone V system on chip. The basic hardware initialization is not performed by the BSP. A boot loader with device tree support must be used to start the BSP, e.g. U-Boot.
The BSP is known to run on these boards:
8.2.1.1. Boot via U-Boot#
The application executable file (ELF file) must be converted to an U-Boot image. Use the following commands:
arm-rtems7-objcopy -O binary app.exe app.bin
gzip -9 -f -c app.bin > app.bin.gz
mkimage -A arm -O linux -T kernel -a 0x00300000 -e 0x00300000 -n RTEMS -d app.bin.gz app.img
Use the following U-Boot commands to boot an application via TFTP download:
tftpboot ${loadaddr} app.img && run loadfdt && bootm ${loadaddr} - ${fdt_addr} ; reset
The loadfdt
command may be not defined in your U-Boot environment. Just replace it with the appropriate commands to load the device tree at ${fdt_addr}
.
8.2.1.2. Clock Driver#
The clock driver uses the Cortex-A9 MPCore Global Timer
.
8.2.1.3. Console Driver#
The console driver supports up to two on-chip NS16550 UARTs. The console driver does not configure the pins.
8.2.1.4. I2C Driver#
There is a legacy I2C driver. It should be converted to the I2C driver framework.
8.2.1.5. Network Interface Driver#
The network interface driver is provided by the libbsd
. It is initialized according to the device tree. It supports checksum offload.
8.2.1.6. MMC/SDCard Driver#
The MMC/SDCard driver is provided by the libbsd
. It is initialized according to the device tree. Pin re-configuration according to the serial clock frequency is not supported. DMA transfers are supported.
8.2.1.7. USB Host Driver#
The USB host driver is provided by the libbsd
. It is initialized according to the device tree. The driver works in polled mode.
8.2.1.8. Caveats#
The clock and pin configuration support is quite rudimentary and mostly relies on the boot loader.
8.2.2. atsam#
Board support package for the Atmel SAM V71/V70/E70/S70 chip platform.
The BSP is customized to a particular board/chip variant by means of BSP config options.
Use ATSAM_CHIP = XYZ
to select the chip variant where XYZ
is one of same70j19
, same70j20
, same70j21
, same70n19
, same70n20
, same70n21
, same70q19
, same70q20
, same70q21
, sams70j19
, sams70j20
, sams70j21
, sams70n19
, sams70n20
, sams70n21
, sams70q19
, sams70q20
, sams70q21
, samv71j19
, samv71j20
, samv71j21
, samv71n19
, samv71n20
, samv71n21
, samv71q19
, samv71q20
, samv71q21
. By default the BSP uses the ATSAMV71Q21 chip. Not all variants are tested.
Use ATSAM_SDRAM = XYZ
to select the SDRAM variant where XYZ
is one of is42s16100e-7bli
, is42s16320f-7bl
and mt48lc16m16a2p-6a
. Not all variants are tested with all controller and speed combinations.
Use BOARD_MAINOSC = XYZ
to set the main oscillator frequency in Hz (default 12MHz).
Use ATSAM_MCK = XYZ
to set the MCK frequency that should be used. The default case (123000000) enables operation of an external SDRAM on the SAMv71 Explained evaluation kit. Some other configurations (e.g. 150MHz) would be too fast on that board.
Your application can also overwrite the clock settings. If you have a bootloader with one setting in your internal flash and an application with another setting in your external SDRAM, you should also use the ATSAM_CHANGE_CLOCK_FROM_SRAM = 1
option. To overwrite the clock settings, define the following structures in your application:
const struct atsam_clock_config atsam_clock_config = {
.pllar_init = my_custom_pllar_value,
.mckr_init = my_custom_mckr_value,
.mck_freq = my_resulting_mck_frequency
};
const struct BOARD_Sdram_Config BOARD_Sdram_Config = {
.sdramc_tr = my_custom_sdramc_tr_value,
.sdramc_cr = my_custom_sdramc_cr_value,
.sdramc_mdr = my_custom_sdramc_mdr_value,
.sdramc_cfr1 = my_custom_sdramc_cfr1_value
};
Use ATSAM_SLOWCLOCK_USE_XTAL = 0
to disable the usage of the external 32 kHz oscillator for the slow clock. This is useful for example for the SAM E70 Xplained kit.
Use ATSAM_CONSOLE_BAUD = XYZ
to set the initial baud for console devices (default 115200).
Use ATSAM_CONSOLE_DEVICE_TYPE = XYZ
to set the device type for /dev/console
, use 0
for USART and 1
for UART (default USART).
Use ATSAM_CONSOLE_DEVICE_INDEX = XYZ
to set the device index for /dev/console
(default 1
, e.g. USART1).
Use ATSAM_CONSOLE_USE_INTERRUPTS = XYZ
to set the use interrupt driven mode for console devices (used by default).
Use ATSAM_MEMORY_NULL_SIZE = XYZ
to set the size of NULL pointer protection area in bytes (default 0x00000000
).
Use ATSAM_MEMORY_TCM_SIZE = XYZ
to set the size of tightly coupled memories (TCM) in bytes (default 0x00000000
). Note: ITCM is reduced by the ATSAM_MEMORY_NULL_SIZE
.
Use ATSAM_MEMORY_QSPIFLASH_SIZE = XYZ
to set the size of QSPI flash in bytes (default 0x00200000
).
The pins may be configured by the application at link-time. See <bsp/pin-config.h>
.
The clock driver uses the ARMv7-M Systick.
The console driver supports the USART and UART devices.
The default linker command file places the code into the internal flash. There are the alternative linker command files linkcmds.sdram
, linkcmds.qspiflash
and linkcmds.intsram
that use other memories. To use them in your application, add the following linker flags: LDFLAGS += -qnolinkcmds -T linkcmds.XYZ
.
The fast text section uses the ITCM. The fast data section uses the DTCM.
Data and instruction cache are enabled during system start. The RTEMS cache manager is supported with exception of the freeze functions.
8.2.3. beagle#
This BSP supports four variants, beagleboardorig
(for the original BeagleBoard), beagleboardxm
(for the BeagleBoard-xM), beaglebonewhite
(for the original BeagleBone) and beagleboneblack
(for the BeagleBone Black). The beagleboneblack
should also work for the PocketBeagle.
Currently the only distinction in the BSP are between the beagleboards
and the beaglebones
, but the 4 names are specified in case hardware-specific distinctions are made in the future, so this can be done without changing the usage.
Note that the beagleboards
are not well tested because the hardware isn’t available any more. Expect that some drivers won’t work out of the box.
The basic hardware initialization is not performed by the BSP. A boot loader with device tree support must be used to start the BSP, e.g., U-Boot.
8.2.3.1. Boot via U-Boot#
To boot via uboot, the ELF must be converted to a U-Boot image like below:
arm-rtems7-objcopy hello.exe -O binary app.bin
gzip -9 app.bin
mkimage -A arm -O linux -T kernel -a 0x80000000 -e 0x80000000 -n RTEMS -d app.bin.gz rtems-app.img
All beagles have memory starting at 0x80000000 so the load & run syntax is the same.
Getting the Device Tree Blob#
The Device Tree Blob (DTB) is needed to load the device tree while starting up the kernel. We build the dtb from the FreeBSD source matching the commit hash from the libbsd HEAD of freebsd-org. For example if the HEAD is at “19a6ceb89dbacf74697d493e48c388767126d418” Then the right Device Tree Source (DTS) file is: freebsd/freebsd
Please refer to the Device Tree to know more about building and applying the Device Trees.
Writing the uEnv.txt file#
The uEnv.txt file is needed to set any environment variable before the kernel is loaded. Each line is a u-boot command that the uboot will execute during start up.
Add the following to a file named uEnv.txt:
setenv bootdelay 5
uenvcmd=run boot
boot=fatload mmc 0 0x80800000 rtems-app.img ; fatload mmc 0 0x88000000 am335x-boneblack.dtb ; bootm 0x80800000 - 0x88000000
Booting from SD#
You can either use the U-Boot that is on the on-board eMMC of the BeagleBone. For that, copy the generated rtems-app.img
, the am335x-boneblack.dtb
device tree and the uEnv.txt
to a FAT formatted SD card. Any recent enough U-Boot will pick up the uEnv.txt
and boot based on that.
If you want to boot purely from SD card (you have to clear the on-board eMMC for that) or if you want to write the application to the eMMC, you additionally need the MLO
and u-boot.img
on your SD card. You can get these either by building U-Boot yourself. Or you an get them from one of the pre-build images that you can download from beagleboard.org.
Note
U-Boot needs to be configured to allow for Legacy format images to be loaded. If not, the following error will be shown when booting the RTEMS image:
Wrong Image Type for bootm command
ERROR -91: can’t get kernel image!
Older versions (<v2022.01) of U-Boot will normally allow this by default. Newer versions might need to be reconfigured. Make sure the CONFIG_LEGACY_IMAGE_FORMAT
is set to y
in the U-Boot config when compiling.
Booting via Network#
The Beagle can also be booted via a TFTP server. To do that using an U-Boot console on the BeagleBones, use the following commands:
uboot# setenv ipaddr 192.168.12.20
uboot# setenv serverip 192.168.12.10
uboot# echo starting from TFTP
uboot# tftp 0x88000000 am335x-boneblack.dtb
uboot# tftp 0x80800000 rtems-app.img
uboot# dcache off ; icache off
uboot# bootm 0x80800000 - 0x88000000
The BeagleBoards use Ethernet over USB. Therefore the commands are a bit different. Note that these commands haven’t been tested recently and you might have to add a devicetree similar to the BeagleBone:
uboot# setenv serverip 192.168.12.10
uboot# setenv ipaddr 192.168.12.62
uboot# setenv usbnet_devaddr e8:03:9a:24:f9:10
uboot# setenv usbethaddr e8:03:9a:24:f9:11
uboot# usb start
uboot# echo starting from TFTP
uboot# tftp 0x80800000 rtems-app.img
uboot# dcache off ; icache off
uboot# bootm 0x80800000
8.2.3.2. Drivers#
TODO(These drivers are present but not documented yet):
Clock driver.
Network Interface Driver.
SDcard driver.
GPIO Driver.
Console driver.
PWM Driver.
RTC driver.
I2C Driver#
The Beagle i2c initialization is based on the device tree. To initialize a i2c device, the user has to enable the respective node in the device tree using overlays.
For registering an I2C device with a custom path (say /dev/i2c-eeprom
) an overlay has to be provided. The overlay must add an additional attribute rtems,path
with the custom path as value to the respective i2c node.
For example,
/dts-v1/;
/ {
compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
fragment@0 {
target = <0xffffffff>;
__overlay__ {
compatible = "rtems,bsp-i2c", "ti,omap4-i2c";
status = "okay";
rtems,path = "/dev/i2c-eeprom";
};
};
__fixups__ {
i2c0 = "/fragment@0:target:0";
};
};
The above example registers a custom path /dev/i2c-eeprom
for i2c0.
SPI Driver#
The SPI device /dev/spi-0
can be registered with bbb_register_spi_0()
For registering with a custom path, the bsp_register_spi()
can be used.
The function prototype is given below:
rtems_status_code bsp_register_spi(
const char *bus_path,
uintptr_t register_base,
rtems_vector_number irq
);
8.2.3.3. Debugging using libdebugger#
RTEMS’s libdebugger
requires the ARM debug resources be enabled for it to work. The TI SOC used on the beagleboneblack
board provides no access for software to the ARM defined debug enable signal DBGEN
. The signal is negated on power up locking software out of the ARM debug hardware. The signal can only be accessed via the JTAG interface.
The beagleboneblack
BSP provides a low level solution to enable the DBGEN
signal via the JTAG interface if the board has the following hardware modification installed. The modification requires the addition of two small wire links soldered to the pads of the JTAG connect on the underside of the board. A small length of fine wire, a fine tip soldering iron, some good quality solder and a pair of fine tip pliers are required. If you are new to soldering I suggest you find something to practice on first.
The modification details and software driver can be found in the BSP in the file bsps/arm/beagle/start/bspdebug.c
. The driver is automatically run and the DBGEN
is asserted via JTAG when libdebugger
is started.
The modification is:
Locate P2 on the bottom side of the board. It is the JTAG connector pads. If you look at the underside of the board with the SD card holder to the right the pads are top center left. There are 20 pads in two columns. The pads are numbered 1 at the top left then 2 top right, 3 is second top on the left, 4 is second top to the right, then the pin number increments as you move left then right down the pads.
Connect P2 to P5.
Connect P7 to P13.
The resulting wiring is:
1 === /--=== 2
3 === | === 4
5 ===--/ === 6
7 ===--\ === 8
9 === | === 10
11 === | === 12
13 ===--/ === 14
15 === === 16
17 === === 18
19 === === 20
Fig. 8.1 BeagleBone Black JTAG Hardware Modification#
If libdebugger
fails to detect the registers open the bspdebug.c
source and change has_tdo
to 1
, save then rebuild and install the BSP. This will turn on an internal feeback to check the JTAG logic. Discard the edit once the hardware is working.
8.2.3.4. Debugging Beagle Bone Black using a JTAG debugger and gdb#
Debugging a Beagle Bone Black (or variants) is also possible using a hardware JTAG debugger. The JTAG is available via P2. The footprint is for an ARM 20 pin cTI connector. That connector should be used, if it is necessary to have access to commercially available adapters.
For hand-made cables and adapters a standard 1.27mm pitch header and a 0.635mm ribbon cable can be much cheaper. But note that even if it looks compatible, it’s not the same pin out as a ARM Cortex 20 pin connector!
A lot of JTAG adapters that are working together with OpenOCD will work. There are also commercially available systems (like Segger J-Link) that work well with the Beagle. Note that the JTAG debugger has to be compatible with ARM Cortex A8. Cortex M only debuggers (like the Segger J-Link Edu Mini) won’t work.
If the debugger offers a gdb server (like OpenOCD or Segger J-Link) the following gdb start script can be used:
define reset
echo -- Reset target and wait for U-Boot to start kernel.\n
monitor reset
# RTEMS U-Boot starts at this address.
tbreak *0x80000000
# Linux starts here.
tbreak *0x82000000
continue
echo -- Disable watchdog.\n
set *(uint32_t*)0x44e35048=0xAAAA
while (*(uint32_t*)0x44e35034 != 0)
end
set *(uint32_t*)0x44e35048=0x5555
while (*(uint32_t*)0x44e35034 != 0)
end
echo -- Overwrite kernel with application to debug.\n
load
end
target remote :2331
Note that you might have to replace the monitor reset
by some other command that resets the target using your specific debugger. You also have to replace the target remote :2331
to match the port of your gdb server.
The script expects that the Beagle Bone Black starts some application from an SD card or from eMMC. It defines a reset
command that does the following:
reset the target
let U-Boot run, initialize the base system, load an FDT and an application
break at the application entry point
disable the watchdog
overwrite the application that has been loaded by U-Boot with the application provided as an command line argument to gdb
This method has the advantage that the application is executed in nearly the same environment like it would be executed if loaded by U-Boot directly (except for the watchdog).
8.2.3.5. Debugging using a JTAG debugger and gdb without any bootcode#
Note: These instructions haven’t been tested for quite some time. So you maybe have to adapt them. If possible, prefer the method with a dummy application described above.
To run RTEMS from scratch (without any other bootcode) on the beagles, you can comfortably load the executables over JTAG using gdb. This is necessarily target-specific however.
BBXM
For access to JTAG using openocd, see simscripts/bbxm.cfg.
openocd then offers access to gdb using simscripts/gdbinit.bbxm.
start openocd using bbxm.cfg
copy your .exe to a new dir and that gdbinit file as .gdbinit in the same dir
go there and start gdb: $ arm-rtems4.11-gdb hello.exe
gdb will invoke the BBXM hardware initialization in the bbxm.cfg and load the ELF over JTAG. type ‘c’ (for continue) to run it.
breakpoints, C statement and single-instruction stepping work.
beaglebone white
This has been tested with openocd and works but not in as much detail as for the BBXM yet (i.e. loading an executable from scratch).
8.2.3.6. Testing#
Note: These instructions haven’t been tested for quite some time. So you maybe have to adapt them. Please update the documentation if you find bugs.
To build and run the tests for this BSP, use the RTEMS tester. The necessary software can be built with the RTEMS source builder.
To build the BSP for testing:
set CONSOLE_POLLED=1 in the configure environment, some tests assume console i/o is polled
Enable the tests during BSP configuration
Then you can run the tests:
Qemu
Linaro Qemu can emulate the beagleboard xm and so run all regression tests in software. Build the bbxm.bset from the RTEMS source builder and you will get qemu linaro that can run them. There is a beagleboardxm_qemu bsp in the RTEMS tester to invoke it with every test.
bbxm hardware
This requires JTAG, see README.JTAG. Use the beagleboardxm bsp in the RTEMS tester. It starts gdb to connect to openocd to reset the target and load the RTEMS executable for each test iteration.
8.2.4. csb336#
TODO.
8.2.5. csb337#
TODO.
8.2.6. edb7312#
TODO.
8.2.7. fvp (Fixed Virtual Platform)#
The BSP for the Arm Fixed Virtual Platforms offers one variant. You need a license from Arm to run the simulator. The fvp_cortex_r52
variant supports a simulation of the Cortex-R52 processor. The BSP supports the SMP configuration.
8.2.7.1. Run an Executable#
To run an executable on a single Cortex-R52 processor use:
FVP_BaseR_Cortex-R52x1 -C bp.vis.disable_visualisation=1 -a build/arm/fvp_cortex_r52/testsuites/samples/ticker.exe
To run an executable on a four Cortex-R52 processors use:
FVP_BaseR_Cortex-R52x4 -C bp.vis.disable_visualisation=1 -a build/arm/fvp_cortex_r52/testsuites/samples/ticker.exe
8.2.7.2. Clock Driver#
The clock driver uses the ARMv7-AR Generic Timer
.
8.2.7.3. Console Driver#
The console driver uses the semihosting SYS_READC
and SYS_WRITEC
system calls.
8.2.8. gumstix#
TODO.
8.2.9. imx (NXP i.MX)#
This BSP offers only one variant, the imx7
. This variant supports the i.MX 7Dual processor and the i.MX 6UL/ULL processor family (with slightly different clock settings). The basic hardware initialization is not performed by the BSP. A boot loader with device tree support must be used to start the BSP, e.g. U-Boot or barebox.
8.2.9.1. Build Configuration Options#
The following options can be used in the BSP section of the waf configuration INI file. The waf defaults can be used to inspect the values.
BSP_PRESS_KEY_FOR_RESET
If defined to a non-zero value, then print a message and wait until pressed before resetting board when application terminates.
BSP_RESET_BOARD_AT_EXIT
If defined to a non-zero value, then reset the board when the application terminates.
BSP_PRINT_EXCEPTION_CONTEXT
If defined to a non-zero value, then print the exception context when an unexpected exception occurs.
BSP_FDT_BLOB_SIZE_MAX
The maximum size of the device tree blob in bytes (default is 262144).
CONSOLE_USE_INTERRUPTS
Use interrupt driven mode for console devices (enabled by default).
IMX_CCM_IPG_HZ
The IPG clock frequency in Hz (default is 67500000).
IMX_CCM_UART_HZ
The UART clock frequency in Hz (default is 24000000).
IMX_CCM_ECSPI_HZ
The ECSPI clock frequency in Hz (default is 67500000).
IMX_CCM_AHB_HZ
The AHB clock frequency in Hz (default is 135000000).
IMX_CCM_SDHCI_HZ
The SDHCI clock frequency in Hz (default is 196363000).
8.2.9.2. Clock settings for different boards#
The default clock settings are targeted for an i.MX 7Dual evaluation board using U-Boot. Some other boards with different boot loaders need different settings:
Phytec phyCORE-i.MX 6ULL (system on module) with MCIMX6Y2CVM08AB and a barebox bootloader (version
2019.01.0-bsp-yocto-i.mx6ul-pd19.1.0
):
IMX_CCM_IPG_HZ=66000000
IMX_CCM_UART_HZ=80000000
IMX_CCM_AHB_HZ=66000000
IMX_CCM_SDHCI_HZ=198000000
IMX_CCM_ECSPI_HZ=60000000
8.2.9.3. Boot via U-Boot#
The application executable file (ELF file) must be converted to an U-Boot image. Use the following commands:
arm-rtems7-objcopy -O binary app.exe app.bin
gzip -9 -f -c app.bin > app.bin.gz
mkimage -A arm -O linux -T kernel -a 0x80200000 -e 0x80200000 -n RTEMS -d app.bin.gz app.img
Use the following U-Boot commands to boot an application via TFTP download:
tftpboot ${loadaddr} app.img && run loadfdt && bootm ${loadaddr} - ${fdt_addr} ; reset
The loadfdt
command may be not defined in your U-Boot environment. Just replace it with the appropriate commands to load the device tree at ${fdt_addr}
.
8.2.9.4. Boot via barebox#
The same command like for U-Boot can be used to generate an application image. In a default configuration barebox expects an fdt image called oftree
and a kernel image called zImage
in the root folder of the bootable medium (e.g. an SD card).
8.2.9.5. Clock Driver#
The clock driver uses the ARMv7-AR Generic Timer
.
8.2.9.6. Console Driver#
The console driver supports up to seven on-chip UARTs. They are initialized according to the device tree. The console driver does not configure the pins.
8.2.9.7. I2C Driver#
I2C drivers are registered by the i2c_bus_register_imx()
function. The I2C driver does not configure the pins.
#include <assert.h>
#include <bsp.h>
void i2c_init(void)
{
int rv;
rv = i2c_bus_register_imx("/dev/i2c-0", "i2c0");
assert(rv == 0);
}
8.2.9.8. SPI Driver#
SPI drivers are registered by the spi_bus_register_imx()
function. The SPI driver configures the pins according to the pinctrl-0
device tree property. SPI transfers with a continuous chip select are limited by the FIFO size of 64 bytes. The driver has no DMA support.
#include <assert.h>
#include <bsp.h>
void spi_init(void)
{
int rv;
rv = spi_bus_register_imx("/dev/spi-0", "spi0");
assert(rv == 0);
}
8.2.9.9. Network Interface Driver#
The network interface driver is provided by the libbsd
. It is initialized according to the device tree. It supports checksum offload and interrupt coalescing. IPv6 transmit checksum offload is not implemented. The interrupt coalescing uses the MII/GMII clocks and can be controlled by the following system controls:
dev.ffec.<unit>.int_coal.rx_time
dev.ffec.<unit>.int_coal.rx_count
dev.ffec.<unit>.int_coal.tx_time
dev.ffec.<unit>.int_coal.tx_count
A value of zero for the time or count disables the interrupt coalescing in the corresponding direction.
On the Phytec phyCORE-i.MX 6ULL modules the PHY needs an initialization for the clock. A special PHY driver handles that (ksz8091rnb
). Add it to your libbsd config like that:
#define RTEMS_BSD_CONFIG_BSP_CONFIG
#define RTEMS_BSD_CONFIG_INIT
SYSINIT_DRIVER_REFERENCE(ksz8091rnb, miibus);
#include <machine/rtems-bsd-config.h>
On chips with two Ethernet controllers, the MDIO lines are shared between the two controllers for a number of chips variants. This is currently supported with some restrictions on the initialization order. For this configuration to work, you have to make sure that the pins are assigned to the Ethernet controller that is initialized first. The initialization order in libbsd
depends on the order of the Ethernet controllers in the device tree. So if (for example) fec2
is defined in the device tree sources before fec1
, make sure that the MDIO lines are routed to fec2
and that the Ethernet PHYs are a sub-node of fec2
in the device tree.
Note that the clock for the second Ethernet controller is not necessarily enabled in the CCM
. On the i.MX6UL/ULL, the clock will be enabled by the startup code if the node that is compatible with fsl,imx6ul-anatop
can be found in the device tree. If you have trouble with the second Ethernet controller make sure that the ENET2_125M_EN
bit in the CCM_ANALOG_PLL_ENET
register is set as expected.
8.2.9.10. MMC/SDCard Driver#
The MMC/SDCard driver (uSDHC module) is provided by the libbsd
. It is initialized according to the device tree. Pin re-configuration according to the serial clock frequency is not supported. Data transfers are extremely slow. This is probably due to the missing DMA support.
8.2.9.11. Caveats#
The clock and pin configuration support is quite rudimentary and mostly relies on the boot loader. For a pin group configuration see imx_iomux_configure_pins()
. There is no power management support.
8.2.10. imxrt (NXP i.MXRT)#
This BSP offers multiple variants. The imxrt1052
supports the i.MXRT 1052 processor on a IMXRT1050-EVKB (tested with rev A1). Some possibilities to adapt it to a custom board are described below.
NOTE: The IMXRT1050-EVKB has an backlight controller that must not be enabled without load. Make sure to either attach a load, disable it by software or disable it by removing the 0-Ohm resistor on it’s input.
The imxrt1166-cm7-saltshaker
supports an application specific board. Adapting it to another i.MXRT1166 based board works similar like for the imxrt1052
BSP.
8.2.10.1. Build Configuration Options#
Please see the documentation of the IMXRT_*
and BSP_*
configuration options for that. You can generate a default set of options with:
./waf bspdefaults --rtems-bsps=arm/imxrt1052 > config.ini
8.2.10.2. Adapting to a different board#
This is only a short overview for the most important steps to adapt the BSP to another board. Details for most steps follow further below.
The device tree has to be adapted to fit the target hardware.
A matching clock configuration is necessary (simplest method is to generate it with the NXP PinMux tool)
The
dcd_data
has to be adapted. That is used for example to initialize SDRAM.imxrt_flexspi_config
has to be adapted to match the Flash connected to FlexSPI (if that is used).BOARD_InitDEBUG_UARTPins
should be adapted to match the used system console.
8.2.10.3. Boot Process of IMXRT1050-EVKB#
There are two possible boot processes supported:
The ROM code loads a configuration from HyperFlash (connected to FlexSPI), does some initialization (based on device configuration data (DCD)) and then starts the application. This is the default case.
linkcmds.flexspi
is used for this case.Some custom bootloader does the basic initialization, loads the application to SDRAM and starts it from there. Select the
linkcmds.sdram
for this.
For programming the HyperFlash in case 1, you can use the on board debugger integrated into the IMXRT1050-EVKB. You can generate a flash image out of a compiled RTEMS application with for example:
arm-rtems7-objcopy -O binary build/arm/imxrt1052/testsuites/samples/hello.exe hello.bin
Then just copy the generated binary to the mass storage provided by the debugger. Wait a bit till the mass storage vanishes and re-appears. After that, reset the board and the newly programmed application will start.
NOTE: It seems that there is a bug on at least some of the on board debuggers. They can’t write more than 1MB to the HyperFlash. If your application is bigger than that (like quite some of the applications in libbsd), you should use an external debugger or find some alternative programming method.
For debugging: Create a special application with a while(true)
loop at end of bsp_start_hook_1
. Load that application into flash. Then remove the loop again, build your BSP for SDRAM and use a debugger to load the application into SDRAM after the BSP started from flash did the basic initialization.
8.2.10.4. Flash Image#
For booting from a HyperFlash (or other storage connected to FlexSPI), the ROM code of the i.MXRT first reads some special flash header information from a fixed location of the connected flash device. This consists of the Image vector table (IVT), Boot data and Device configuration data (DCD).
In RTEMS, these flash headers are generated using some C-structures. If you use a board other than the IMXRT1050-EVKB, those structures have to be adapted. To do that re-define the following variables in your application (you only need the ones that need different values):
#include <bsp/flash-headers.h>
const uint8_t imxrt_dcd_data[] =
{ /* Your DCD data here */ };
const ivt imxrt_image_vector_table =
{ /* Your IVT here */ };
const BOOT_DATA_T imxrt_boot_data =
{ /* Your boot data here */ };
const flexspi_nor_config_t imxrt_flexspi_config =
{ /* Your FlexSPI config here */ };
You can find the default definitions in bsps/arm/imxrt/start/flash-*.c
. Take a look at the i.MX RT1050 Processor Reference Manual, Rev. 4, 12/2019
chapter 9.7 Program image
or i.MX RT1166 Processor Reference Manual, Rev. 0, 05/2021
chapter 10.7 Program image
for details about the contents.
8.2.10.5. FDT#
The BSP uses a FDT based initialization. The FDT is linked into the application. You can find the default FDT used in the BSPs in bsps/arm/imxrt/dts
. The FDT is split up into two parts. The controller specific part is put into an dtsi
file. The board specific one is in the dts file. Both are installed together with normal headers into ${PREFIX}/arm-rtems7/${BSP}/lib/include
. You can use that to create your own device tree based on that. Basically use something like:
/dts-v1/;
#include <imxrt/imxrt1050-pinfunc.h>
#include <imxrt/imxrt1050.dtsi>
&lpuart1 {
pinctrl-0 = <&pinctrl_lpuart1>;
status = "okay";
};
&chosen {
stdout-path = &lpuart1;
};
/* put your further devices here */
&iomuxc {
pinctrl_lpuart1: lpuart1grp {
fsl,pins = <
IMXRT_PAD_GPIO_AD_B0_12__LPUART1_TX 0x8
IMXRT_PAD_GPIO_AD_B0_13__LPUART1_RX 0x13000
>;
};
/* put your further pinctrl groups here */
};
You can then convert your FDT into a C file with (replace YOUR.dts
and similar with your FDT source names):
sh> arm-rtems7-cpp -P -x assembler-with-cpp \
-I ${PREFIX}/arm-rtems7/imxrt1052/lib/include \
-include "YOUR.dts" /dev/null | \
dtc -O dtb -o "YOUR.dtb" -b 0 -p 64
sh> rtems-bin2c -A 8 -C -N imxrt_dtb "YOUR.dtb" "YOUR.c"
You’ll get a C file which defines the imxrt_dtb
array. Make sure that your new C file is compiled and linked into the application. It will overwrite the existing definition of the imxrt_dtb
in RTEMS.
8.2.10.6. Clock Driver#
The clock driver uses the generic ARMv7-M Clock
.
8.2.10.7. IOMUX#
The i.MXRT IOMUXC is initialized based on the FDT. For that, the pinctrl-0
fields of all devices with a status of ok
or okay
will be parsed.
8.2.10.8. Console Driver#
LPUART drivers are registered based on the FDT. The special rtems,path
attribute defines where the device file for the console is created.
The stdout-path
in the chosen
node determines which LPUART is used for the console.
8.2.10.9. I2C Driver#
I2C drivers are registered based on the FDT. The special rtems,path
attribute defines where the device file for the I2C bus is created.
Limitations:
Only basic I2C is implemented. This is mostly a driver limitation and not a hardware one.
8.2.10.10. SPI Driver#
SPI drivers are registered based on the FDT. The special rtems,path
attribute defines where the device file for the SPI bus is created.
Note that the SPI-pins on the evaluation board are shared with the SD card. Populate R278, R279, R280, R281 on the IMXRT1050-EVKB (Rev A) to use the SPI pins on the Arduino connector.
By default, the native chip selects are used. If you want to use GPIOs as chip select instead, you can use the cs-gpios
and num-cs
attributes just like on a Linux SPI controller. A maximum of IMXRT_LPSPI_MAX_CS
pins can be used.
The hardware doesn’t support selecting no native chip select during a transfer. Therefore one native chip select has to be reserved as a dummy if you want to be able to use GPIOs. The pin function for this chip select must not be configured on any pin. Dummy will be the first of the first four chip selects that is not a native one. Example configuration:
&lpspi4 {
status = "okay";
pinctrl-0 = <&my_pinctrl_lpspi4>;
cs-gpios = <0>, <0>, <&gpio1 1 0>, <0>, <&gpio11 5 1>;
num-cs = <5>;
}
In this case, CS2 will be the dummy chip select and no pin must be configured with that function. CS0, CS1 and CS3 are just native chip selects and should be used via pin functions. GPIO1.1 is used as a high active CS and GPIO11.5 a low active one.
Limitations:
Only a basic SPI driver is implemented. This is mostly a driver limitation and not a hardware one.
GPIO CS pins on i.MXRT10xx are not tested. The chip has a lot of errate so they might not work.
Switching from one mode (CPOL/CPHA) to another one can lead to single wrong edges on the CLK line if GPIO CS pins are involved. Make sure to stuff a dummy transfer with
SPI_NO_CS
set if you use multiple modes together with a GPIO CS.
8.2.10.11. Network Interface Driver#
The network interface driver is provided by the libbsd
. It is initialized according to the device tree.
Note on the hardware: The i.MXRT1050 EVKB maybe has a wrong termination of the RXP, RXN, TXP and TXN lines. The resistors R126 through R129 maybe shouldn’t be populated because the used KSZ8081RNB already has an internal termination. Ethernet does work on short distance anyway. But keep it in mind in case you have problems. Source: https://community.nxp.com/t5/i-MX-RT/Error-in-IMXRT1050-EVKB-and-1060-schematic-ethernet/m-p/835540#M1587
8.2.10.12. NXP SDK files#
A lot of peripherals are currently not yet supported by RTEMS drivers. The NXP SDK offers drivers for these. For convenience, the BSP compiles the drivers from the SDK. But please note that they are not tested and maybe won’t work out of the box. Everything that works with interrupts most likely needs some special treatment.
The SDK files are imported to RTEMS from the NXP mcux-sdk git repository that you can find here: nxp-mcuxpresso/mcux-sdk
The directory structure has been preserved and all files are in a bsps/arm/imxrt/mcux-sdk
directory. All patches to the files are marked with #ifdef __rtems__
markers.
The suggested method to import new or updated files is to apply all RTEMS patches to the mcux-sdk repository, rebase them to the latest mcux-sdk release and re-import the files. The new base revision should be mentioned in the commit description to make future updates simpler.
A import helper script (that might or might not work on newer releases of the mcux-sdk) can be found here: https://raw.githubusercontent.com/c-mauderer/nxp-mcux-sdk/d21c3e61eb8602b2cf8f45fed0afa50c6aee932f/export_to_RTEMS.py
8.2.10.13. Clocks and SDRAM#
The clock configuration support is quite rudimentary. The same is true for SDRAM. It mostly relies on the DCD and on a static clock configuration that is taken from the NXP SDK example projects.
If you need to adapt the DCD or clock config to support a different hardware, you should generate these files using the NXP MCUXpresso Configuration Tools. You can add the generated files to your application to overwrite the default RTEMS ones or you can add them to RTEMS in a new BSP variant.
As a special case, the imxrt1052 BSP will adapt it’s PLL setting based on the chip variant. The commercial variant of the i.MXRT1052 will use a core clock of 600MHz for the ARM core. The industrial variants only uses 528MHz. For other chip or BSP variants, you should adapt the files generated with the MCUXpresso Configuration Tools.
8.2.10.14. Caveats#
The MPU settings are currently quite permissive.
There is no power management support.
On the i.MXRT1166, sleeping of the Cortex M7 can’t be disabled even for debugging purposes. That makes it hard for a debugger to access the controller. To make debugging a bit easier, it’s possible to overwrite the idle thread with the following one in the application:
void * _CPU_Thread_Idle_body(uintptr_t ignored) { (void)ignored; while (true) { /* void */ } }
8.2.11. lm3s69xx#
TODO.
8.2.12. lpc176x#
TODO.
8.2.13. lpc24xx (NXP LPC17XX/LPC24XX/LPC40XX)#
This BSP offers only several variants. The following variants support the Embedded Artits LPC4088 Developer’s Kit and earlier board generations:
lpc17xx_ea_ram
lpc17xx_ea_rom_int
lpc24xx_ea
lpc40xx_ea_ram
lpc40xx_ea_rom_int
They can be used as a base line for customization. The basic hardware initialization is performed by the BSP. It can be customized via configuration options and configuration tables. See also <bsp/start-config.h>.
8.2.13.1. Clock Driver#
The clock driver of the Cortex-M variants uses the ARMv7-M Systick
. The older ARM7TDMI variants use the TMR0
timer module.
8.2.13.2. Console Driver#
The console driver supports up to four on-chip UARTs. Initialization can be customized via the lpc24xx_uart_probe_1()
, lpc24xx_uart_probe_2()
and lpc24xx_uart_probe_3()
functions.
8.2.13.3. I2C Bus Driver#
I2C bus drivers are registered by the lpc24xx_register_i2c_0()
, lpc24xx_register_i2c_1()
and lpc24xx_register_i2c_2()
functions. The I2C driver does not configure the pins. See also <bsp/i2c.h>.
8.2.13.4. SPI Bus Driver#
SPI bus drivers are registered by the lpc24xx_register_ssp_0()
, lpc24xx_register_ssp_1()
and lpc24xx_register_ssp_2()
functions. The SSP driver does not configure the pins. See also <bsp/ssp.h>.
8.2.13.5. Network Interface Driver#
Only a legacy network driver is support. For a libbsd
base driver the platform support is missing, see if_lpe.c.
8.2.13.6. USB Driver#
The USB host driver (OHCI) is provided by the libbsd
.
8.2.13.7. Framebuffer Driver#
For a custom framebuffer driver see <bsp/lcd.h>.
8.2.13.8. RTC Driver#
There is a standard RTC driver available using the on-chip RTC module.
8.2.14. raspberrypi#
The ‘raspberrypi’ BSP supports the single core models (Zero, Zero W, A+, B+), and the ‘raspberrypi2’ BSP supports the Raspberry Pi 2, Raspberry Pi 3 A+, and Raspberry Pi 3. The Raspberry Pi 4 is supported by the AArch64 Raspberry Pi BSP. The default bootloader on the Raspberry Pi which is used to boot Raspbian or other OS can be also used to boot RTEMS. U-boot can also be used.
8.2.14.1. Setup SD card#
The Raspberry Pis have an unconventional booting mechanism. The GPU boots first, initializes itself, runs the bootloader and starts the CPU. The bootloader looks for a kernel image, by default the kernel images must have a name of the form kernel*.img
but this can be changed by adding kernel=<img_name>
to config.txt
.
You must provide the required firmware files on the SD card for the GPU to proceed, and thereby to boot RTEMS. The BSP currently boots up with an older version of the official firmware. These files can be downloaded from the Raspberry Pi Firmware Repository. You can remove the kernel*.img
files if you want to, but don’t touch the other files.
Copy these files in to a SD card with FAT filesystem.
8.2.14.2. Kernel image#
The following steps show how to run hello.exe
on a Raspberry Pi 2. The same instructions can be applied to Raspberry Pi 1 also. Other executables can be processed in a similar way.
To create the kernel image:
$ arm-rtems7-objcopy -Obinary hello.exe kernel.img
Copy the kernel image to the SD card.
Make sure you have these lines below, in your config.txt
.
dtoverlay=disable-bt
kernel_address=0x200000
kernel=kernel.img
8.2.14.3. SPI Driver#
SPI drivers are registered by the rpi_spi_init(bool bidirectional_mode)
function.
#include <assert.h>
#include <bsp.h>
void spi_init(void)
{
int rv;
rv = rpi_spi_init(false);
assert(rv == 0);
}
8.2.14.4. I2C Driver#
I2C drivers are registered by the rpi_setup_i2c_bus()
function.
#include <assert.h>
#include <bsp.h>
void i2c_init(void)
{
int rv;
rv = rpi_setup_i2c_bus();
assert(rv == 0);
}
8.2.14.5. Testing using QEMU#
QEMU can be built using RSB. Navigate to <SOURCE_BUILDER_DIR>/rtems
and run this command.
$ ../source-builder/sb-set-builder --prefix=<TOOLCHAIN_DIR> devel/qemu
Note: Replace <SOURCE_BUILDER_DIR>
and <TOOLCHAIN_DIR>
with the correct path of the directories. For example, if you used quick-start section as your reference, these two will be $HOME/quick-start/src/rsb
and $HOME/quick-start/rtems/5
respectively,
QEMU along with GDB can be used for debugging, but it only supports Raspberry Pi 2 and the emulation is also incomplete. So some of the features might not work as expected.
Make sure your version of QEMU is newer than v2.6, because older ones don’t support Raspberry Pis.
$ qemu-system-arm -M raspi2 -m 1G -kernel hello.exe -serial mon:stdio -nographic -S -s
This starts QEMU and creates a socket at port localhost:1234
for GDB to connect.
The Device Tree Blob (DTB) is needed to load the device tree while starting up the kernel. The BSP uses information from this file to initialize the drivers.
Make sure you pass in the correct DTB file. There are currently two version of DTB for the Raspberry Pi 2 bcm2709-rpi-2-b.dtb
and bcm2710-rpi-2-b.dtb
. The bcm2709-rpi-2-b.dtb
is for Raspberry Pi 2 Model B and bcm2710-rpi-2-b.dtb
is for Raspberry Pi 2 Model B v1.2
We need to pass in the DTB file to GDB before running the example.
In a new terminal, run GDB using
$ arm-rtems7-gdb hello.exe
This will open GDB and will load the symbol table from hello.exe. Issue the following commands in the GDB prompt.
(gdb) tar remote:1234
(gdb) load
(gdb) restore bcm2709-rpi-2-b.dtb binary 0x2ef00000
(gdb) set $r2 = 0x2ef00000
This will connect GDB to QEMU and will load the DTB file and the application.
(gdb) continue
The continue
command will run the executable.
Note: Add set scheduler-locking on
in GDB if you have any issues running the examples.
8.2.15. realview-pbx-a9#
The arm/realview_pbx_a9_qemu
BSP is intended to be used with Qemu. The Qemu realview-pbx-a9
machine can be used to run SMP tests using for example the Qemu -smp 4
command line option.
The command line to execute an ELF file app.exe
on this Qemu machine is:
export QEMU_AUDIO_DRV="none"
qemu-system-arm -net none -nographic -M realview-pbx-a9 -m 256M -kernel app.exe
You do not need to specify a device tree blob.
8.2.16. rtl22xx#
TODO.
8.2.17. smdk2410#
TODO.
8.2.18. stm32f4#
TODO.
8.2.19. stm32h7#
This BSP supports the STM32H7 Series.
The BSP is known to run on these boards on specified core with using specified BSP variant.
Board name | Core name | BSP variant name |
---|---|---|
M7 | arm/stm32h7 | |
M7 | arm/nucleo-h743zi | |
M7 | arm/stm32h7b3i-dk | |
M7 | arm/stm32h757i-eval | |
M4 | arm/stm32h757i-eval-m4 | |
M7 | arm/stm32h747i-disco | |
M4 | arm/stm32h747i-disco-m4 |
8.2.19.1. Clock Driver#
The clock driver uses the ARMv7-M Systick
module. The HSE (external oscillator) value can also be different for different evaluation or custom boards, so it is recommended to check the default values of the BSP.
8.2.19.2. Console Driver#
The console driver supports the on-chip UART and USART modules. Even the MCU supports about 10 U(S)ARTs, only those supported by the chosen board are enabled by default configuration. The board needs to support some kind of connector-based connection to the U(S)ART in order for the feature to be considered supported here.
8.2.19.3. Network Interface Driver#
The network interface driver if_stmac
is provided by the libbsd
.
8.2.19.4. USB Host Driver#
The USB host driver dwc_otg
is provided by the libbsd
.
8.2.19.5. SD/MMC Driver#
The SDMMC driver st_sdmmc
is provided by the libbsd
.
The default initialization is done for the STM32H743I-EVAL 2 board.
To use different pins, you can create a HAL_SD_MspInit()
function in your application that overwrites the default one defined in RTEMS
. If you don’t have direction lines like on the evaluation board, you can just skip initializing these pins.
If you want to use a different number of data lines, another polarity for the data direction pins, a different voltage or similar, you have to redefine st_sdmmc_get_config()
(normally provided by libbsd
) in your application.
Known limitations:
Currently 1.8V signaling is not implemented. Therefore higher speeds like used for UHS cards are not available. All cards fall back to High Speed transfers.
The driver uses the IDMA only. MDMA is currently not implemented. For SDMMC1 that means that the memory buffers can only come from AXI SRAM, QSPI memory, Flash or the FMC (SDRAM, …). The internal SRAM1, SRAM2, SRAM3 and SRAM4 are not supported. SDMMC2 should not have that limitation. See ST AN5200 “Getting started with STM32H7 Series SDMMC host controller” for more details.
8.2.19.6. How to run RTEMS on the board#
Following few paragraphs save a purpose of simple HOWTO or a quick starting guide for the users not versed in STM32 toolchain and their boards workflow.
Board hardware setup#
Connect board with the host computer using micro-USB cable connected to micro-USB connector on the board marked with ‘ST-LINK V3E’ in case of evaluation and discovery boards or with ‘USB PWR’ in case of Nucleo board.
STM32CubeIDE installation#
Download and install STM32CubeIDE from https://www.st.com/en/development-tools/stm32cubeide.html. Install the software into the user directory. On Linux install with ‘sudo’ command to install as a root since as part of the installation USB permissions rules for ST-Link GDB server are also installed. The reason for installing into the user directory is that the IDE is based on Eclipse, which provides its own update method and this will not work well in case of read-only access to the installation directory. In case of any troubles consult installation manual provided by ST here https://www.st.com/resource/en/user_manual/um2563-stm32cubeide-installation-guide-stmicroelectronics.pdf. Although we will not used full fledged IDE here, the package provides ST-Link GDB Server which will be used for uploading RTEMS binaries to the board memory.
STM32CubeProgrammer installation#
Download and install STM32CubeProgrammer from https://www.st.com/en/development-tools/stm32cubeprog.html. We will use this software for board setup required for RTEMS and later when something goes wrong to delete content of the MCU flash memory. The software is also internally used by the ST-Link GDB Server from STM32CubeIDE so it is crucial to have it installed.
Board ST-Link firmware upgrade#
Download ST-Link board firmware upgrade package from https://www.st.com/en/development-tools/stsw-link007.html. The software is distributed in a form of Java jar file for Linux and Mac OSX and in a form of Windows binary for MS Windows. Unpack it somewhere and run it with
$ unzip en.stsw-link007-v3-9-3_v3.9.3.zip
$ cd stsw-link007/AllPlatforms
$ java -jar STLinkUpgrade.jar
Click on Open in update mode button and then if Version and Update to Firmware version information are different in shown version number/code, click on Upgrade button and wait till upgrade finishes.
$ sudo apt install libusb-1.0-0
Dual core board setup for RTEMS#
Current RTEMS BSP supports running MCU in a single-core mode only on either M7 core or M4 core. That means that to not leave other core interfering with the system we either need to upload short infinite loop code to it or we may switch off the core completely. The second option is what is described here. The board by default switches on and starts both cores. Based on chosen BSP variant you may like to switch off other core with using STMCubeProgrammer tool. Go to the directory where you have installed STMCubeProgrammer software and run it with
$ cd bin
$ ./STM32CubeProgrammer
Important
It is absolutely necessary you will do that from inside the bin directory where STM32CubeProgrammer binary resides. If you don’t, then programmer UI will crash on attempt to connect to the board. Probable reason is a bug in the programmer which is not able to correctly locate its C dynamic library responsible for connecting to the ST-Link board interface. Version 2.9.0 of the programmer is described here. Other versions may behave a bit differently.
When you start the programmer application, the UI window of the programmer will appear. Click on green Connect button in the right upper corner of the UI. This will connect programmer to the board. Then click on OB icon in the left upper corner. Actually this is hidden menu item which you can un-hide by clicking on menu icon (three horizontal stripes) in the upper left corner. When you click on OB or Option bytes in un-hidden state, then click on User Configuration in the options list and when the user configuration list opens unselect preselected BCM4 item inside it to switch off M4 core or unselect preselected BCM7 item to switch off M7 core from starting up. The action needs to be saved by clicking on Apply button below the option table.
Warning
Be careful! Wrong setup in STM32H7 configuration may result in bricked board.
Do not forget to disconnect the programmer application from the board by clicking on green Disconnect button in the upper right corner and then close the programmer UI.
Important
If you keep programmer connected then you will not be able to connect ST-Link GDB server to the board and upload RTEMS binary to it.
STM32CubeIDE ST-Link GDB Server setup#
In order to use STM provided ST-Link GDB server externally, that is not from inside the IDE, we need to configure it. Please go to the directory where you have installed STM32CubeIDE software. Look for file containing ST-LINK string inside its name. Following shell command sequence shows example about how to find it.
$ cd $HOME/sfw/stm32cubeide_1.8.0
$ find . -name 'ST-LINK*'
./plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.0.200.202202231230/tools/bin/ST-LINK_gdbserver.sh
./plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.0.200.202202231230/tools/bin/ST-LINK_gdbserver
./plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.0.100.202109301221/tools/bin/ST-LINK_gdbserver.sh
./plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.0.100.202109301221/tools/bin/ST-LINK_gdbserver
Notice that in this particular installation case we already have two versions of GDB server installed. This is due to fact that version 1.8.0 of the IDE was later upgraded to 1.9.0 version. Anyway, we will choose to use the latest one, or if there is only one, then the only one installed. Please go to its bin directory. E.g.
$ cd plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.0.200.202202231230/tools/bin
Now, you will need to edit provided config.txt file inside the directory. Use your favorite editor. Open the file and scroll down to its end. You will see following comment:
###############################################################
# -cp <path> : Path to STM32CubeProgrammer
# Modify to correct path
# for STM32_Programmer_CLI executable
###############################################################
-cp
and here you will need to place path where your STM32CubeProgrammer is installed directly behind the -cp parameter. E.g.
###############################################################
# -cp <path> : Path to STM32CubeProgrammer
# Modify to correct path
# for STM32_Programmer_CLI executable
###############################################################
-cp /home/karel/sfw/stm32cubeide_1.8.0/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.linux64_2.0.200.202202231230/tools/bin
Once you are done with it, you can save the file and close the editor. Let’s verify that GDB server is configured and running well by starting it inside the shell. Please go inside the directory where ST-LINK_gdbserver.sh is located and run it by:
$ ./ST-LINK_gdbserver.sh
If everything is all right and if you have board still connected to the host computer then you should see output like following:
$ ./ST-LINK_gdbserver.sh
STMicroelectronics ST-LINK GDB server. Version 6.1.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.
Starting server with the following options:
Persistent Mode : Enabled
LogFile Name : debug.log
Logging Level : 31
Listen Port Number : 61234
Status Refresh Delay : 15s
Verbose Mode : Disabled
SWD Debug : Enabled
COM frequency = 24000 kHz
Target connection mode: Default
Reading ROM table for AP 0 @0xe00fefd0
Hardware watchpoint supported by the target
ST-LINK Firmware version : V3J9M3
Device ID: 0x450
PC: 0x8028fa4
ST-LINK device status: HALT_MODE
ST-LINK detects target voltage = 3.28 V
ST-LINK device status: HALT_MODE
ST-LINK device initialization OK
Stm32Device, pollAndNotify running...
SwvSrv state change: 0 -> 1
Waiting for connection on port 61235...
Waiting for debugger connection...
Waiting for connection on port 61234...
In output above you can see ST-Link GDB server waiting for debugger connection. If this is the case in your case, then you can finish GDB server by hitting Ctrl-C key combination.
RTEMS BSP samples build and run#
We will use STM32H747I-DISCO board as an example hereafter. If you use different board please adjust configuration steps in BSP configuration accordingly. You should use BSP variant name specified for your particular board in the table above.
Generate default configuration for the board:
$ ./waf bspdefaults --rtems-bsps=arm/stm32h747i-disco > stm32h747i-disco.ini
Regenerate build specification cache (needs a couple of seconds)...
To run basic hello world or ticker samples you do not need to modify default BSP configuration here as the compilation of basic RTEMS demo samples is enabled by default. Let’s continue with configuration of the RTEMS source by running following command. Please change the RTEMS tools installation prefix to suite your installation.
$ ./waf configure --rtems-bsps=arm/stm32h747i-disco --rtems-config=./stm32h747i-disco.ini --rtems-tools=$HOME/workspace/rtems-tools
Setting top to : /home/rtems/workspace/rtems
Setting out to : /home/rtems/workspace/rtems/build
Configure board support package (BSP) : arm/stm32h747i-disco
Checking for program 'arm-rtems6-gcc' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-gcc
Checking for program 'arm-rtems6-g++' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-g++
Checking for program 'arm-rtems6-ar' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-ar
Checking for program 'arm-rtems6-ld' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-ld
Checking for program 'ar' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-ar
Checking for program 'g++, c++' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-g++
Checking for program 'ar' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-ar
Checking for program 'gas, gcc' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-gcc
Checking for program 'ar' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-ar
Checking for program 'gcc, cc' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-gcc
Checking for program 'ar' : /home/rtems/workspace/rtems-tools/bin/arm-rtems6-ar
Checking for asm flags '-MMD' : yes
Checking for c flags '-MMD' : yes
Checking for cxx flags '-MMD' : yes
'configure' finished successfully (0.454s)
Build the BSP including samples using build command:
$ ./waf build
the command outputs a lot of information about files being compiled and ends with output like:
Waf: Leaving directory `/home/rtems/workspace/rtems/build/arm/stm32h747i-disco'
'build_arm/stm32h747i-disco' finished successfully (12.086s)
As your RTEMS BSP including samples is compiled, we will proceed with running the hello world sample on the board now. Open 3 shell windows for the test on the host computer. Also make sure board is connected to the computer and is running. It does not matter if manufacturer’s demo is running there or if you navigated to some demo part and left it there. ST-Link GDB server always takes over the board when connected to it.
Start GDB server in the first window by switching to GDB server directory and running the shell script. This is from testing machine installation, the path to GDB server will probably look different in your installation case.
$ cd sfw/stm32cubeide_1.8.0/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.linux64_2.0.200.202202231230/tools/bin
$ ./ST-LINK_gdbserver.sh
STMicroelectronics ST-LINK GDB server. Version 6.1.0
Copyright (c) 2022, STMicroelectronics. All rights reserved.
Starting server with the following options:
Persistent Mode : Enabled
LogFile Name : debug.log
Logging Level : 31
Listen Port Number : 61234
Status Refresh Delay : 15s
Verbose Mode : Disabled
SWD Debug : Enabled
COM frequency = 24000 kHz
Target connection mode: Default
Reading ROM table for AP 0 @0xe00fefd0
Hardware watchpoint supported by the target
ST-LINK Firmware version : V3J9M3
Device ID: 0x450
PC: 0x8028fa4
ST-LINK device status: HALT_MODE
ST-LINK detects target voltage = 3.28 V
ST-LINK device status: HALT_MODE
ST-LINK device initialization OK
Stm32Device, pollAndNotify running...
SwvSrv state change: 0 -> 1
Waiting for connection on port 61235...
Waiting for debugger connection...
Waiting for connection on port 61234...
In second shell window you will need to run your terminal program and connect to the board virtual serial port. Following steps describes how to do that on the Ubuntu 20.04. The recommended way here is to use minicom. Let’s install it first by:
$ sudo apt install minicom
And run it with root privileges to be able to reach USB serial port provided by board:
$ sudo minicom -s
The minicom is invoked with configuration menu open. Go into the Serial port setup and hit a key to select Serial Device setup. Change /dev/modem from there into /dev/ttyACM0 and hit Enter key. Hit f key to change hardware flow control from Yes to No. When you are done with it, you can hit Enter key to finish this part of configuration and then scrolls in menu to Exit and hit Enter key on it. The minicom will switch to terminal mode with just provided configuration.
In the third shell window navigate into the BSP build directory and start RTEMS GDB with the hello.exe sample.
$ arm-rtems6-gdb build/arm/stm32h747i-disco/testsuites/samples/hello.exe
GNU gdb (GDB) 10.1.90.20210409-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-rtems6".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from build/arm/stm32h747i-disco/testsuites/samples/hello.exe...
(gdb)
Now, you need to connect GDB with the ST’s GDB server by:
(gdb) target extended-remote :61234
Remote debugging using :61234
0x08028fa4 in ?? ()
(gdb)
and finally you will need to load hello.exe binary into the board memory by:
(gdb) load
Loading section .start, size 0x458 lma 0x24000000
Loading section .text, size 0xfca8 lma 0x24000480
Loading section .init, size 0xc lma 0x24010128
Loading section .fini, size 0xfecc lma 0x24010134
Loading section .rodata, size 0x1aab lma 0x24020000
Loading section .ARM.exidx, size 0x8 lma 0x24021aac
Loading section .eh_frame, size 0x4 lma 0x24021ab4
Loading section .init_array, size 0x4 lma 0x24021ab8
Loading section .fini_array, size 0x4 lma 0x24021abc
Loading section .rtemsroset, size 0x540 lma 0x24021ac0
Loading section .data, size 0x6a4 lma 0x24022000
Start address 0x24000400, load size 140923
Transfer rate: 684 KB/sec, 2562 bytes/write.
(gdb)
If everything went fine, then you can run the RTEMS binary by using cont GDB command.
Note
Memory address values in the load output in the gdb shows that we have loaded our application into the AXI SRAM. Memory addresses will be different when loading into different part of MCU memory.
(gdb) cont
Continuing.
Note that this command should never finish. To see the actual output from RTEMS switch to the second shell window with minicom (or other terminal emulation program) running and you should see hello output there:
*** BEGIN OF TEST HELLO WORLD ***
*** TEST VERSION: 6.0.0.50ce036cfbd9807a54af47eb60eadb6a33a9e82d
*** TEST STATE: EXPECTED_PASS
*** TEST BUILD:
*** TEST TOOLS: 10.3.1 20220224 (RTEMS 6, RSB 49e3dac17765fa82ce2f754da839638ee352f95c, Newlib 64b2081)
Hello World
*** END OF TEST HELLO WORLD ***
[ RTEMS shutdown ]
RTEMS version: 6.0.0.50ce036cfbd9807a54af47eb60eadb6a33a9e82d
RTEMS tools: 10.3.1 20220224 (RTEMS 6, RSB 49e3dac17765fa82ce2f754da839638ee352f95c, Newlib 64b2081)
executing thread ID: 0x08a010001
Since default RTEMS BSP configuration resets the board after run immediately you can also see output from the immediately started ST demo:
STM32H747I-DISCO_MB1248: Out Of the Box Demonstration V1.0.1 (Build Aug 22 2019 at 11:56:22)
STM32H747I-DISCO_MB1248: ST Menu Launcher V1.1.0
CPU running at 400MHz, Peripherals at 100MHz/100Mz
which is not a problem here at all. Later we can reconfigure BSP to not reset board to prevent demo output here.
How to load binary file into the QSPI NOR#
Connect the board to your host computer using micro-USB cable. Start STM32CubeProgrammer and connect it to the board by clicking on Connect button which is located in the right upper corner of the programmer application UI. For accessing QSPI connected memory you will need to configure programmer’s external loader which needs to match your target board. Click on EL icon (or External loaders) in the left sidebar menu. Either go thorough the list of external loaders or just search for your board by typing board name (or part of the name) into the search bar located on top of the table view. When you find your board, select it by selecting rectangle in the Select table column. That’s what is needed to make programmer ready to program your board memory. For uploading file to the board, you need to continue with clicking on Erase & programming menu item in the left sidebar menu. It’s second item from the top. Now, let’s select your file to upload by clicking on Browse button and selecting the file name from your host computer filesystem. The most important thing here is to specify start address of flashing process. You need to do that by typing start address into the Start address field.
Note
Usually external memory connected to QSPI has 0x90000000 starting address.
When all is set you can click on Start Programming button.
Important
Cube programmer is very picky about files it shows in the file list. The only recognized suffixes are: elf, bin, hex and similar. Also do not try to fool programmer by renaming let’s say text file to bin file. It’ll detect file type as ascii text and will not show it in the list of files to flash. So bin file type is really for media types like avi, jpeg, mpeg or for binary dumps from elf files. If you need to save text file, convert it to hex file first.
8.2.20. tms570#
This BSP family supports the two evaluation boards:
BSP build options allow you to customize the BSP variants. The
tms570lc4357_hdk
tms570ls3137_hdk
BSP variants use the internal flash for code, the internal SRAM for data, and perform a basic system initialization including setting up the SDRAM controller. The
tms570lc4357_hdk_sdram
tms570ls3137_hdk_sdram
do not use the internal flash and use the SDRAM for code and data. They rely on a basic system initialization.
8.2.21. xen (Xen on ARM)#
This BSP enables RTEMS to run as a guest virtual machine in AArch32 mode on the Xen hypervisor for ARMv8 platforms.
Drivers:
Clock: ARMv7-AR Generic Timer
Console: Virtual PL011 device
Interrupt: GICv2
BSP variants:
xen_virtual: completely virtualized guest with no dependence on underlying hardware
The xen_virtual BSP variant relies on standard Xen features, so it should be able to run on any ARMv8 platform.
Xen allows for the passthrough of hardware peripherals to guest virtual machines. BSPs could be added in the future targeting specific hardware platforms and include the appropriate drivers.
This BSP was tested with Xen running on the Xilinx Zynq UltraScale+ MPSoC using the Virtuosity distribution maintained by DornerWorks.
8.2.21.1. Execution#
This procedure describes how to run the ticker sample application that should already be built with the BSP.
The ticker.exe
file can be found in the BSP build tree at:
arm-rtems7/c/xen_virtual/testsuites/samples/ticker.exe
The ticker.exe
elf file must be translated to a binary format.
arm-rtems7-objcopy -O binary ticker.exe ticker.bin
Then place the ticker.bin
file on the dom0 filesystem.
From the dom0 console, create a configuration file ticker.cfg
with the following contents.
name = "ticker"1G
kernel = "ticker.bin"
memory = 8
vcpus = 1
gic_version = "v2"
vuart = "sbsa_uart"
Create the virtual machine and attach to the virtual vpl011 console.
xl create ticker.cfg && xl console -t vuart ticker
To return back to the dom0 console, press both Ctrl
and ]
on your keyboard.
8.2.21.2. Additional Information#
8.2.22. xilinx-zynq#
This BSP supports the Xilinx Zynq range of devices. This family of devices contain the same ARM hard IP and the different parts have different sizes of programable logic.
The BSP defaults may need to be adjusted using configure
BSP options to match the size of memory your board may have.
8.2.22.1. Bootloader#
The bootloader initialises the Zynq device. The Xilinx tool provide an interface to configure the hardware. This is includes the buses, clocks, memory and UART board rate. The output of this is called ps7_init
and it a C file. The Xilinx SDK builds a first stage boot loader (FSBL) using this file.
The U-Boot boot loader has it’s own FSBL called MLO
to initialise the hardware.
8.2.22.2. Clocks#
An application can provide a function called:
uint32_t a9mpcore_clock_periphclk(void);
to return the peripheral clock. Normally this is half the CPU clock. This function is declared weak
so you can override the default behaviour by providing it in your application.
8.2.22.3. Console#
The console driver for the UARTs will always be initialized to a baud rate of 115200 with 8 bit characters, 1 stop bit and no parity bits during start up. Previous configurations programmed into the hardware by the Xilinx tools or a bootloader will be overwritten.
The settings for the console driver can be changed by the user application through the termios API afterwards.
8.2.22.4. Network#
The Cadence network interface driver of LibBSD works on the Xilinx Zynq platform. The hardware checksum support works on real hardware but does not seem to be supported on Qemu therefore the default state is to disable IFCAP_TXCSUM
and IFCAP_RXCSUM
and this can be enabled from the shell with:
ifconfig cgem0 rxcsum txcsum
or with an ioctl()
call to the network interface driver with SIOCSIFCAP
and the mask IFCAP_TXCSUM
and IFCAP_RXCSUM
set.
8.2.22.5. Debugging with xilinx_zynq_a9_qemu#
To debug an application add the QEMU options -s
. If you need to debug an initialisation issue also add -S
. For example to debug a networking application you could use:
qemu-system-arm -M xilinx-zynq-a9 -m 256M -no-reboot -serial \
null -serial mon:stdio -nographic \
-net nic,model=cadence_gem -net vde,id=vde0,sock=/tmp/vde1 \
-kernel myapp.exe \
-s -S
Start GDB with the same executable QEMU is running and connect to the QEMU GDB server:
(gdb) target remote :1234
If your application is crashing set a breakpoint on the fatal error handler:
(gdb) b bsp_fatal_extension
Enter continue to run the application. Running QEMU loads the executable and initialises the CPU. If the -S
option is provided the CPU is held in reset. Without the option the CPU runs starting RTEMS. Either way you are connecting to set up target and all you need to do is continue:
(gdb) c
If you have a crash and the breakpoint on bsp_fatal_extension
is hit, load the following a GDB script:
define arm-crash
set $code = $arg0
set $r0 = ((const rtems_exception_frame *) $code)->register_r0
set $r1 = ((const rtems_exception_frame *) $code)->register_r1
set $r2 = ((const rtems_exception_frame *) $code)->register_r2
set $r3 = ((const rtems_exception_frame *) $code)->register_r3
set $r4 = ((const rtems_exception_frame *) $code)->register_r4
set $r5 = ((const rtems_exception_frame *) $code)->register_r5
set $r6 = ((const rtems_exception_frame *) $code)->register_r6
set $r7 = ((const rtems_exception_frame *) $code)->register_r7
set $r8 = ((const rtems_exception_frame *) $code)->register_r8
set $r9 = ((const rtems_exception_frame *) $code)->register_r9
set $r10 = ((const rtems_exception_frame *) $code)->register_r10
set $r11 = ((const rtems_exception_frame *) $code)->register_r11
set $r12 = ((const rtems_exception_frame *) $code)->register_r12
set $sp = ((const rtems_exception_frame *) $code)->register_sp
set $lr = ((const rtems_exception_frame *) $code)->register_lr
set $pc = ((const rtems_exception_frame *) $code)->register_pc
set $cpsr = ((const rtems_exception_frame *) $code)->register_cpsr
end
Enter the command:
(gdb) arm-crash code
Enter bt
to see the stack back trace.
The script moves the context back to the crash location. You should be able to view variables and inspect the stack.
The fatal error handler runs inside an exception context that is not the one than generated the exception.
8.2.23. xilinx-zynqmp#
This BSP supports the Xilinx Zynq UltraScale+ MPSoC platform.
8.2.24. Xilinx ZynqMP RPU#
This BSP supports the Real-time Processing Unit (RPU) on the Xilinx Zynq UltraScale+ MPSoC and RFSoC platforms. The RPU has two Cortex-R5 cores which can operate in lock-step or split mode. Basic hardware initialization is performed by the Cortex-R5 FSBL and the BSP. This BSP supports the GICv2 interrupt controller available to the RPU subsystem. Since the RPU subsystem only varies in speed, this BSP should be functional across all chip variants as well as on Xilinx’s QEMU branch. There are three BSP variants available for customization:
zynqmp_rpu_lock_step
zynqmp_rpu_split_0
zynqmp_rpu_split_1
The zynqmp_rpu_lock_step
BSP variant is intended to be used for the RPU in lock-step mode. In this case, the ATCM and BTCM will be used as a combined memory area for code and data. The zynqmp_rpu_split_0
and zynqmp_rpu_split_1
BSP variants are intended to be used for the RPU in split mode for core 0 and 1 respectively. The core 0 variant initializes the GIC distributor. The core 1 variants waits for the GIC distributor initialization done by core 0 during the system initialization. The DDR RAM is a shared resource and should be used according to applications-specific requirements. The default BSP settings for the DDR RAM usage aimed at testing the BSP variants.
8.2.24.1. Clock Driver#
The clock driver uses one of the available triple timer counters (TTCs) as the timer interrupt source.
8.2.24.2. Console Driver#
The console driver supports the default Qemu emulated ARM PL011 PrimeCell UART as well as the physical ARM PL011 PrimeCell UART in the ZynqMP hardware.
8.2.24.3. Boot on ZynqMP Hardware#
On the ZynqMP RPU, RTEMS can be started by Cortes-R5 u-boot, Cortex-A53 u-boot, via JTAG, or directly as part of BOOT.bin. For quick turnaround during testing, it is recommended to use Cortex-A53 u-boot to avoid repeated BOOT.bin generation since the provided Cortex-R5 u-boot is highly limited and has no network or MMC/SD access.
Note that if the RPU image is started by the Cortex-A53 u-boot, the program sections located at ZYNQMP_RPU_RAM_INT_0_ORIGIN and ZYNQMP_RPU_RAM_INT_1_ORIGIN must be manually relocated from DDR to TCM since the TCMs are not directly available to the Cortex-A53 cores at their Cortex-R5 internal addresses. This can be accomplished by disabling dcache in u-boot and using u-boot’s “cp” command. Once this is done, the program can be started at 0x0 by using u-boot’s “cpu” command to first disable core 4 and then release it in split mode.
8.2.24.4. Hardware Boot Image Generation#
When generating BOOT.bin from components, the BIF file should include at least entries for the Cortex-R5 FSBL ([bootloader,destination_cpu=r5-0]) and the Cortex-R5 application ([destination_cpu=r5-0]). The Cortex-R5 application should be either a u-boot or RTEMS ELF binary. The Cortex-R5 u-boot binary can be obtained by building it from Xilinx’s u-boot repository. The Cortex-R5 FSBL can be obtained setting up an appropriate platform project in Xilinx’s current development system.
8.2.24.5. Boot on QEMU#
The executable image is booted by Qemu in ELF format.
8.2.24.6. Running Executables on QEMU#
Xilinx’s qemu-devicetrees repository must be used in conjunction with the Xilinx QEMU available via RSB. Executables generated by this BSP can be run using the following command:
qemu-system-aarch64 -no-reboot -nographic -M arm-generic-fdt -serial null \
-serial mon:stdio -device loader,file=example.exe,cpu-num=4 \
-device loader,addr=0xff5e023c,data=0x80088fde,data-len=4 \
-device loader,addr=0xff9a0000,data=0x80000218,data-len=4 \
-hw-dtb /xlnx-qemu-devtrees-path/LATEST/SINGLE_ARCH/board-zynqmp-zcu102.dtb \
-m 4096 -display none
8.2.24.7. Debugging Executables on QEMU#
Debugging the RPU cores under QEMU presents unique challenges due to requiring the AArch64 QEMU to emulate the entire processing subsystem. Debugging requires a multi-arch GDB which can be created by adding “–enable-targets=all” to the normal GDB configure line and then building as normal.
To attach to the RPU core once QEMU is started with “-s -S”, The following steps are required:
aarch64-rtems6-gdb
(gdb) tar ext :1234
(gdb) add-inferior
(gdb) inferior 2
(gdb) file example.exe
(gdb) attach 2
8.3. i386#
8.3.1. pc386#
This BSP supports a standard Intel/AMD PC on i386 and up CPUs. If run on a Pentium or above, the TSC register is used for timing calibration purposes rather than relying entirely on the i8254. Partial support is implemented for more modern PCs which do not have a complete complement of legacy peripherals.
The BSP is able to utilize up to 3 GB of available RAM and up to 16 CPUs. Hyper-threading is supported, but may not be detected by the BSP successfully.
Note
BSP capability to detect target hardware SMP details is limited due to fact the SMP support is implemented based on Intel Multi-Processor Specification (MPS). Final version of the specification is version 1.4 which was released on July 1, 1995. On most newer machines the MPS functionality was more or less supplanted by more modern ACPI (Advanced Configuration and Power Interface). Still, on some machine SMP support may be fragile at least at the platform detection and initialization state depending on the target BIOS/ACPI/MPS compatibility implementation.
There are several BSP variants provided which differ only in the target CPU optimization. The most general is pc386
which is tuned for i386. The pc486
variant is tuned for i486, pc585
is tuned for Pentium, pc586-sse
is tuned for Pentium processor supporting SSE instructions. Finally pc686
is tuned for Pentium Pro processor, but generating only instructions for Pentium and pcp4
is tuned and generating instructions for Pentium4 processor including SSE3 instructions.
8.3.1.1. Build Configuration Options#
BSP_PRESS_KEY_FOR_RESET
If defined to a non-zero value, then print a message and wait until any key is pressed before resetting board when application terminates (disabled by default).
BSP_RESET_BOARD_AT_EXIT
If defined to a non-zero value, then reset the board when the application terminates (enabled by default).
BSP_PRINT_EXCEPTION_CONTEXT
If defined to a non-zero value, then print the exception context when an unexpected exception occurs (enabled by default).
BSP_VERBOSE_FATAL_EXTENSION
If defined to a non-zero value, then print more information in case of a fatal error (enabled by default).
BSP_ENABLE_VGA
Enables VGA console driver (enabled by default).
BSP_ENABLE_COM1_COM4
Enables support of COM1 thorough COM4 (enabled by default).
USE_COM1_AS_CONSOLE
Enforces usage of COM1 as a console device (disabled by default).
BSP_ENABLE_IDE
Enables legacy IDE driver (enabled by default).
IDE_USE_PRIMARY_INTERFACE
Allows RTEMS to use storage drive(s) connected to the primary IDE interface. Disable if (i) the target hardware does not have primary IDE interface or (ii) it does not have any drive attached to the primary IDE interface or (iii) there is no need to use drive(s) attached to the primary IDE interface at all (enabled by default).
IDE_USE_SECONDARY_INTERFACE
Allows RTEMS to use storage drive(s) connected to the secondary IDE interface. Enable if (i) the target hardware does have secondary IDE interface and (ii) there is at least one drive attached to the secondary IDE interface and (iii) there is a need to use drive(s) attached to the secondary IDE interface (disabled by default).
BSP_VIDEO_80x50
Sets the VGA display to 80x50 character mode (disabled by default).
CLOCK_DRIVER_USE_TSC
Enforces clock driver to use TSC register available on Pentium and higher class CPUs. If disabled and
CLOCK_DRIVER_USE_8243
is disabled too, then BSP will choose clock driver mechanism itself during the runtime (disabled by default).CLOCK_DRIVER_USE_8254
Enforces clock driver to use 8254 chip. If disabled and
CLOCK_DRIVER_USE_TSC
is disabled too, then BSP will choose clock driver mechanism itself during the runtime (disabled by default).NUM_APP_DRV_GDT_DESCRIPTORS
Defines how many descriptors in GDT may be allocated for the application or driver usage.
USE_CIRRUS_GD5446
Enables usage of Cirrus GD5446 graphic card for RTEMS frame-buffer (disabled by default).
USE_VGA
Enables usage of generic VGA graphic card for RTEMS frame-buffer (disabled by default).
USE_VBE_RM
Enables usage of graphic card implementing VESA BIOS Extensions for RTEMS frame-buffer (enabled by default).
BSP_GDB_STUB
Enables GDB support for debugging over serial port (enabled by default).
8.3.1.2. Runtime Options#
The BSP supports several runtime options. They may be used by either setting during boot by using target hardware bootloader or by using Qemu’s -append
command-line parameter in case BSP application is run inside the Qemu emulator.
- --console=<dev>#
specifies console device. E.g.
--console=/dev/com1
. COM device name may also be followed by a baud rate like--console=/dev/com2,19200
The pc386 BSP family uses 9600 as a default baud rate for console over UART (/dev/comX) with 8 data bits, no parity and 1 stop bit.
- --printk=<dev>#
specifies target device for printk/getk calls. E.g.
--printk=/dev/vgacons
If the specified console device is not present then suitable fallback device is selected based on the device order specified in Console Drivers
.
- --video=<mode>#
specifies required video mode. The options applies only to the systems supporting VESA BIOS Extensions. Choices are
auto
which selects graphic mode automatically ornone
/off
which disables initialization of the graphic driver or direct specification of resolution and/or color depth by<resX>x<resY>[-<bpp>]
. E.g.--video=none
disables graphic driver. Using--video=1280x1024
sets video mode to 1280x1024 pixels mode while--video=800x600-32
sets video mode to 800x600 pixels with 32bit color depth.
- --disable-com1-com4#
disables usage of COM1 thorough COM4.
- --gdb=<dev>#
specifies UART device for communication between BSP’s GDB stub and GDB running on a host system. Option accepts device and baud rate like the
--console
option above. E.g.--gdb=/dev/com2,115200
instructs BSP to use COM2 device for GDB stub/host communication with the speed of 115200 bauds.
The default GDB stub/host is similar to console over UART, i.e., 9600 baud rate, 8 data bits, no parity and 1 stop bit.
- --gdb-break#
halts BSP execution at a break point in the BSP initialization code and waits for GDB connection.
- --gdb-remote-debug#
outputs the GDB remote protocol data to printk.
8.3.1.3. Testing with Qemu#
To test with Qemu, we need to:
Build / install Qemu (most distributions should have it available on the package manager).
Booting RTEMS in Qemu#
$ qemu-system-i386 -m 128 -no-reboot -append \
"--video=off --console=/dev/com1" -nographic -kernel ./hello.exe
This command boots hello.exe
application located in current directory and sets Qemu to provide 128MB RAM and to switch both Qemu’s and BSP’s video off.
Booting RTEMS in KVM accelerated Qemu#
When the Qemu host hardware and OS support KVM, it is possible to use it to accelerate BSP run by using -machine type=q35,accel=kvm
Qemu option. Depending on the Qemu host configuration it may or may not require administrator privileges to run the command.
$ sudo qemu-system-i386 -machine type=q35,accel=kvm -m 128 -no-reboot \
-append "--video=off --console=/dev/com1" -nographic -kernel \
./dhrystone.exe
This command boots dhrystone.exe
application and sets Qemu to use KVM acceleration.
8.3.1.4. Running on a PC hardware#
There are several ways how to start RTEMS BSP application on the real PC hardware.
Booting with GRUB boot-loader#
In case the target machine does already have Linux with GRUB boot loader installed, then the most easy way to load and boot RTEMS is to use GRUB. This may be done in following steps:
prepare RTEMS binary and save it either to Linux partition/directory accessible from GRUB or to an USB stick.
boot machine to GRUB menu.
Note
Some Linux installations hide GRUB menu by default and quickly continues with booting default Linux option. If this is the case, then during the boot hold down ‘Shift’ key to un-hide the menu.
press
c
key to get into the GRUB’s command-line mode.use
ls
command to observe drives and partitions on them. If unsure, use ‘ls’ command with drive/partition description to show the target file system content. E.g.ls (hd1,msdos1)/
will list files on the second drive, first partition which is formatted using fat/vfat file-system.
Note
Use ls (hdX, partY)
without a slash at the end to show information about the partition.
use
multiboot
command to load the RTEMS application binary for boot. E.g.multiboot (hd1,msdos2)/rtems/ticker.exe
will load ticker.exe from the second drive, second partition with fat/vfat file-system and its rtems directory.
use
boot
command to boot loaded binary.
Note
Advantage of using GRUB for booting RTEMS is the GRUB’s support for both classical BIOS and UEFI boot. This way RTEMS may be booted even on UEFI only systems.
Booting with PXE/iPXE#
PXE booting is more complex than GRUB based booting and hence requires more infrastructure configuration. The booting may be done in two possible ways:
using iPXE booted from an USB stick or a hard drive
It may be done using following steps:
Download iPXE ISO image from http://boot.ipxe.org/ipxe.iso
Either record it to CD/DVD or copy it to an USB stick
boot from the medium above on the target hardware
wait for
Press Ctrl-B for the iPXE command line...
prompt and once it appears pressCtrl-B
key.use ‘dhcp’ command to configure network interface card
use ‘boot’ command to boot RTEMS application from specified tftp server. E.g.
boot tftp://10.0.0.5/hello.exe
will boot hello.exe application from the tftp server on host with 10.0.0.5 IP address.
Whole interaction may look as:
Press Ctrl-B for the iPXE command line...
iPXE> dhcp
Configuring (net0 <mac address>)..... ok
iPXE> boot tftp://10.0.0.5/hello.exe
using built in network card’s PXE BIOS to boot into iPXE
This way is more complex and requires network infrastructure configuration changes which description is out of the scope of this documentation. Generic steps how to achieve this are:
use target hardware BIOS/SETUP to enable PXE booting on the board
setup network router to announce tftp server and file on it as a part of the router’s BOOTP/DHCP protocol reply. You should use http://boot.ipxe.org/undionly.kpxe as a payload for non-UEFI based booting. Put that file into tftp server served/root directory.
reboot target hardware and it should run network card PXE BIOS which should obtain IP address from the network router and load undionly.kpxe file from the tftp server. Once this is done, familiar iPXE UI appears. Follow steps described in previous paragraph to boot RTEMS application.
Note
It is not possible to use UEFI based PXE booting. Neither directly by the network card PXE BIOS nor indirectly by booting into iPXE. UEFI booting in both cases is not currently supported.
8.3.1.5. Clock Drivers#
The BSP supports two clock drivers. If there is no build option used (see Build Configuration Options
) for selecting particular clock driver, then the decision which is used is done during the runtime.
i8254 based driver. It is used on pre-Pentium CPUs by default.
TSC register based driver. It is used on Pentium and later CPUs by default.
8.3.1.6. Console Drivers#
The BSP console supports device drivers for a variety of devices including VGA/keyboard and a number of serial ports. The default console is selected based on which devices are present in the following order of priority:
VGA with PS/2 keyboard
COM1 thorough COM4
Any COM devices on the PCI bus including IO and memory mapped
PCI-based UART devices are named /dev/pcicom<number>
as they are probed and found. The numbers sequence starts with 1. E.g. first PCI UART device found is accessible with /dev/pcicom1
name.
Besides supporting generic devices above, the BSP also support specific UART chips. The drivers for those are not initialized automatically, but requires initialization from the application code:
Exar 17d15x (NS16550 compatible multiport PCI UART)
8.3.1.7. Frame-Buffer Drivers#
The BSP supports several drivers implementing RTEMS frame-buffer API. The default driver is for card(s) implementing VESA BIOS Extensions. Others may be enabled by using appropriate build option (see Build Configuration Options
). Available drivers support:
generic VGA graphic card
Cirrus Logic GD5446
generic graphic card supporting VESA BIOS Extensions
8.3.1.8. Network Interface Drivers#
The network interface drivers are provided by the libbsd
.
8.3.1.9. USB Host Drivers#
The USB host drivers are provided by the libbsd
.
8.3.1.10. RTC Drivers#
There are several real time clock devices supported by drivers in the BSP.
Maxim DS1375
Mostek M48T08/M48T18 (Maxim/Dallas Semiconductor DS1643 compatible)
Motorola MC146818A
Renesas ICM7170
8.3.1.11. I2C Drivers#
There are several drivers for various I2C bus connected peripherals supported by the BSP. Supported peripherals are:
EEPROM
Maxim DS1621 temperature sensor
Semtech SC620 Octal LED Driver
8.3.1.12. SPI Drivers#
There are several devices which connect to serial peripheral interfaces supported by the BSP.
M25P40 flash
FM25L256 fram
memory devices
SD card
8.3.1.13. Legacy Drivers#
The BSP source code provides legacy drivers for storage and network devices. The usage of legacy drivers is discouraged and description of such use is out of the scope of this documentation. Interested users should consult BSP source code directly but use legacy driver only when it is not possible to use similar driver provided by libbsd
.
Storage Drivers#
IDE/ATA
AM26LV160/M29W160D flash
Network Drivers#
3Com 3c509
3Com 3c90x (Etherlink XL family)
Novell NE2000
Western Digital WD8003
Intel 82586
Intel EtherExpress PRO/100
Cirrus Logic CS8900
DEC/Intel 21140
SMC 91111
Opencores Ethernet Controller
National Semiconductor SONIC DP83932
8.4. m68k (Motorola 68000 / ColdFire)#
8.4.1. av5282#
TODO.
8.4.2. genmcf548x#
TODO.
8.4.3. mcf5235#
TODO.
8.4.4. mcf5329#
8.4.4.1. Overview#
This BSP is heavily based on the MCF5235 BSP. The MCF5329EVB is a Motorola evaluation board (Zoom) with a LogicPD MCF5329-10 SODIMM-144 card. The development kit features the MCF5329 based Fire Engine, as well as a plug-in system-on-module containing 32 MB of DDR-SDRAM. The board also includes 2 MB of boot flash, 16 MB of NAND flash, a core frequency of 240MHz, an onboard 800x600 LCD controller, FEC, USB, uarts, CAN bus, QSPI, I2C, and 10/100 Ethernet.
You can find the link to MCF5329 Reference Manual below:
8.4.5. uC5282#
TODO.
8.5. microblaze (MicroBlaze)#
8.5.1. KCU105 QEMU#
The basic hardware initialization is performed by the BSP. This BSP supports the QEMU emulated Xilinx AXI Interrupt Controller v4.1.
8.5.1.1. Boot via ELF#
The executable image is booted by QEMU in ELF format.
8.5.1.2. Clock Driver#
The clock driver supports the QEMU emulated Xilinx AXI Timer v2.0. It is implemented as a simple downcounter. If device tree support is enabled in the build configuration, the clock driver will use the node that is compatible with xlnx,xps-timer-1.00.a
from the device tree to configure the clock. The following device tree node properties are used to configure the clock driver: reg
, clock-frequency
, and interrupts
.
8.5.1.3. Console Driver#
The console driver supports the QEMU emulated Xilinx AXI UART Lite v2.0. It is initialized to a baud rate of 115200. If device tree support is enabled in the build configuration, the console driver will use the node that is compatible with xlnx,xps-uartlite-1.00.a
from the device tree to configure the console. The following device tree node properties are used to configure the console driver: reg
, status
, port-number
, and interrupts
.
8.5.1.4. Network Driver#
Support for networking is provided by the libbsd library. Network interface configuration is extracted from the device tree binary which, by default, is in <bsp/microblaze-dtb.h>. The device tree source for the default device tree is at dts/system.dts.
To replace the default device tree with your own, assuming my_device_tree.dts
is the name of your device tree source file, first you must convert your device tree to .dtb format.
$ dtc -I dts -O dtb my_device_tree.dts > my_device_tree.dtb
The device tree blob, my_device_tree.dtb
, can now be converted to a C file. The name system_dtb
is significant as it is the name expected by the BSP.
$ rtems-bin2c -C -A 8 -N system_dtb my_device_tree.dtb my_dtb
The BSP_MICROBLAZE_FPGA_DTB_HEADER_PATH
BSP configuration option can then be set to the path of the resulting source file, my_dtb.c
, in the waf INI file to include it in the BSP build.
BSP_MICROBLAZE_FPGA_DTB_HEADER_PATH = /path/to/my_dtb.c
8.5.1.5. QSPI NOR JFFS2 Driver#
The QSPI NOR JFFS2 driver supports the QEMU emulated n25q512a11 QSPI NOR flash device. It is initialized to a page size of 256 bytes and a sector size of 64 KiB. If device tree support is enabled in the build configuration, the QSPI NOR JFFS2 driver will use the node that is compatible with xlnx,xps-spi-2.00.a
from the device tree to configure the QSPI NOR JFFS2 driver. The following device tree node properties are used to configure the QSPI NOR JFFS2 driver: reg
and interrupts
.
8.5.1.6. Running Executables#
A .dtb
(device tree blob) file should be provided to QEMU via the -hw-dtb
option. In the example command below, the device tree blob comes from the Xilinx Petalinux KCU105 MicroBlaze BSP (https://www.xilinx.com/support/download//content/xilinx/en/downloadNav/embedded-design-tools.html).
Executables generated by this BSP can be run using the following command:
$ qemu-system-microblazeel -no-reboot -nographic -M microblaze-fdt-plnx -m 256 \
-serial mon:stdio -display none -hw-dtb system.dtb -kernel example.exe
8.5.1.7. Debugging with QEMU#
To debug an application, add the option -s
to make QEMU listen for GDB connections on port 1234. Add the -S
option to also stop execution until a connection is made.
For example, to debug the hello sample and break at Init
, first start QEMU.
$ qemu-system-microblazeel -no-reboot -nographic -M microblaze-fdt-plnx -m 256 \
-serial mon:stdio -display none -hw-dtb system.dtb -kernel \
build/microblaze/kcu105_qemu/testsuites/samples/hello.exe -s -S
Then start GDB and connect to QEMU.
$ microblaze-rtems7-gdb build/microblaze/kcu105_qemu/testsuites/samples/hello.exe
(gdb) target remote localhost:1234
(gdb) break Init
(gdb) continue
8.5.2. KCU105#
The basic hardware initialization is performed by the BSP. This BSP supports the Xilinx AXI Interrupt Controller v4.1.
This BSP was tested using the Xilinx Kintex UltraScale FPGA KCU105 board configured with the default Petalinux KCU105 MicroBlaze BSP. The defaults may need to be adjusted using BSP configuration options to match the memory layout and configuration of your board.
8.5.2.1. Clock Driver#
The clock driver supports the Xilinx AXI Timer v2.0. It is implemented as a simple downcounter. If device tree support is enabled in the build configuration, the clock driver will use the node that is compatible with xlnx,xps-timer-1.00.a
from the device tree to configure the clock. The following device tree node properties are used to configure the clock driver: reg
, clock-frequency
, and interrupts
.
8.5.2.2. Console Driver#
The console driver supports the Xilinx AXI UART Lite v2.0. It is initialized to a baud rate of 115200. If device tree support is enabled in the build configuration, the console driver will use the node that is compatible with xlnx,xps-uartlite-1.00.a
from the device tree to configure the console. The following device tree node properties are used to configure the console driver: reg
, status
, port-number
, and interrupts
.
8.5.2.3. Debugging#
The following debugging procedure was used for debugging RTEMS applications running on the Xilinx KCU105 board using GDB.
First send an FPGA bitstream to the board using OpenOCD.
$ openocd -f board/kcu105.cfg -c "init; pld load 0 system.bit; exit"
After the board has been programmed, start the Vivado hw_server
application to serve as the debug server. Leave it running in the background for the rest of the process.
$ tools/Xilinx/Vivado/2020.2/bin/hw_server
With the debug server running, connect to the debug server with GDB, load the application, and debug as usual. By default the GDB server listens on port 3002.
$ microblaze-rtems7-gdb example.exe
(gdb) target extended-remote localhost:3002
(gdb) load
(gdb) break Init
(gdb) continue
8.6. mips (MIPS)#
8.6.1. csb350#
TODO.
8.6.2. hurricane#
TODO.
8.6.3. jmr3904#
TODO.
8.6.4. malta#
TODO.
8.6.5. rbtx4925#
TODO.
8.6.6. rbtx4938#
TODO.
8.7. moxie#
8.7.1. moxiesim#
TODO.
8.8. nios2 (Nios II)#
8.8.1. nios2_iss#
TODO.
8.9. or1k (OpenRISC 1000)#
8.9.1. generic_or1k#
TODO.
8.10. powerpc (PowerPC)#
8.10.1. beatnik#
TODO.
8.10.2. gen5200#
TODO.
8.10.3. gen83xx#
TODO.
8.10.4. haleakala#
TODO.
8.10.5. motorola_powerpc#
8.10.5.1. Boot Image Generation#
The application executable file (ELF file) must be converted to a boot image. Use the following commands:
powerpc-rtems7-objcopy -O binary -R .comment -S ticker.exe rtems
gzip -9 -f rtems
powerpc-rtems7-ld -o ticker.boot bootloader.o --just-symbols=ticker.exe -b binary rtems.gz -T ppcboot.lds -no-warn-mismatch
powerpc-rtems7-objcopy -O binary ticker.boot ticker.bin
8.10.6. mpc55xxevb#
TODO.
8.10.7. mpc8260ads#
TODO.
8.10.8. mvme3100#
TODO.
8.10.9. mvme5500#
TODO.
8.10.10. psim#
TODO.
8.10.11. qemuppc#
TODO.
8.10.12. qoriq (QorIQ)#
The BSP for the QorIQ chip family offers three variants. The qoriq_e500
variant supports the P-series chips such as P1020, P2010 and P2020. The qoriq_e6500_32
(32-bit ISA) and qoriq_e6500_64
(64-bit ISA) variants support the T-series chips such as T2080 and T4240. The basic hardware initialization is not performed by the BSP. A boot loader with device tree support must be used to start the BSP, e.g. U-Boot.
The BSP is known to run on these boards:
NXP P1020RDB
MicroSys miriac MPX2020 (System on Module)
Artesyn MVME2500 (VME64x SBC)
NXP T2080RDB
NXP T4240RDB
MEN G52A (CompactPCI Serial)
The qoriq_core_0
and qoriq_core_1
variants should be used with care. They are inteded for a RTEMS_MULTIPROCESSING
configuration on the P1020.
8.10.12.1. Boot via U-Boot#
The application executable file (ELF file) must be converted to an U-Boot image. Use the following commands:
powerpc-rtems7-objcopy -O binary app.exe app.bin
gzip -9 -f -c app.bin > app.bin.gz
mkimage -A ppc -O linux -T kernel -a 0x4000 -e 0x4000 -n RTEMS -d app.bin.gz app.img
Use the following U-Boot commands to boot an application via TFTP download:
tftpboot ${loadaddr} app.img && run loadfdt && bootm ${loadaddr} - ${fdt_addr} ; reset
8.10.12.2. Clock Driver#
The clock driver uses two MPIC global timer (QORIQ_CLOCK_TIMER
and QORIQ_CLOCK_TIMECOUNTER
). In case QORIQ_IS_HYPERVISOR_GUEST
is defined, then the PowerPC decrementer is used.
8.10.12.3. Console Driver#
The console driver supports the on-chip NS16550 compatible UARTs. In case QORIQ_IS_HYPERVISOR_GUEST
is defined, then the EPAPR byte channel is used for the console device.
8.10.12.4. Network Interface Driver#
The network interface driver is provided by the libbsd
. The DPAA is supported including 10Gbit/s Ethernet.
8.10.12.5. Topaz Hypervisor Guest#
For a Topaz hypervisor guest configuration use:
../configure --enable-rtemsbsp=qoriq_e6500_32 \
QORIQ_IS_HYPERVISOR_GUEST=1 \
QORIQ_UART_0_ENABLE=0 \
QORIQ_UART_1_ENABLE=0 \
QORIQ_TLB1_ENTRY_COUNT=16
You may have to adjust the linker command file according to your partition configuration.
8.10.13. ss555#
TODO.
8.10.14. t32mppc#
TODO.
8.10.15. tqm8xx#
TODO.
8.10.16. virtex#
TODO.
8.10.17. virtex4#
TODO.
8.10.18. virtex5#
TODO.
8.11. riscv (RISC-V)#
8.11.1. riscv#
Each variant in this first group corresponds to a GCC multilib option with different RISC-V standard extensions.
rv32i
rv32iac
rv32im
rv32imac
rv32imafc
rv32imafd
rv32imafdc
rv64imac
rv64imafd
rv64imafdc
Each variant reflects an ISA with ABI and code model choice. All rv64 BSPs have medany code model by default, while rv32 BSPs are medlow. The reason is that RV32 medlow can access the entire 32-bit address space, while RV64 medlow can only access addresses below 0x80000000. With RV64 medany, it’s possible to perform accesses above 0x80000000. The BSP must be started in machine mode.
The reference platforms for the rv* variants include the QEMU virt
and spike
machines and the Spike RISC-V ISA simulator.
The BSP also provides the following variants for specific hardware targets:
frdme310arty - The reference platform for this variant is the Arty FPGA board with the SiFive Freedom E310 reference design.
mpfs64imafdc - The reference platform for this variant is the Microchip PolarFire SoC Icicle Kit.
kendrytek210 - The reference platform for this variant is the Kendryte K210 SoC on the Sipeed MAiX BiT or Maixduino board.
8.11.1.1. Build Configuration Options#
The following options can be used in the BSP section of the waf
configuration INI file. The waf
defaults can be used to inspect the values.
BSP_PRESS_KEY_FOR_RESET
If defined to a non-zero value, then print a message and wait until pressed before resetting board when application terminates.
BSP_RESET_BOARD_AT_EXIT
If defined to a non-zero value, then reset the board when the application terminates.
BSP_PRINT_EXCEPTION_CONTEXT
If defined to a non-zero value, then print the exception context when an unexpected exception occurs.
BSP_FDT_BLOB_SIZE_MAX
The maximum size of the device tree blob in bytes (default is 65536).
BSP_DTB_IS_SUPPORTED
If defined to a non-zero value, then the device tree blob is embedded in the BSP.
BSP_DTB_HEADER_PATH
The path to the header file containing the device tree blob.
BSP_CONSOLE_BAUD
The default baud for console driver devices (default is 115200).
RISCV_MAXIMUM_EXTERNAL_INTERRUPTS
The maximum number of external interrupts supported by the BSP (default is 64).
RISCV_ENABLE_HTIF_SUPPORT
Enable the Host/Target Interface (HTIF) support (enabled by default).
RISCV_CONSOLE_MAX_NS16550_DEVICES
The maximum number of NS16550 devices supported by the console driver (default is 2).
RISCV_ENABLE_SIFIVE_UART_SUPPORT
Enable the SiFive console UART (disabled by default).
RISCV_RAM_REGION_BEGIN
The begin of the RAM region for linker command file (default is 0x80000000).
RISCV_RAM_REGION_SIZE
The size of the RAM region for linker command file (default 64MiB).
RISCV_ENABLE_FRDME310ARTY_SUPPORT
Enables support sifive Freedom E310 Arty board if defined to a non-zero value,otherwise it is disabled (disabled by default).
RISCV_ENABLE_MPFS_SUPPORT
Enables support Microchip PolarFire SoC if defined to a non-zero value, otherwise it is disabled (disabled by default).
RISCV_ENABLE_KENDRYTE_K210_SUPPORT
Enables support for the Kendtryte K210 SoC if defined to a non-zero value, otherwise it is disabled (disabled by default).
RISCV_BOOT_HARTID
The boot hartid (processor number) of risc-v cpu by default 0.
8.11.1.2. Interrupt Controller#
Exactly one Core Local Interruptor (CLINT) and exactly one Platform-Level Interrupt Controller (PLIC) are supported. The maximum number of external interrupts supported by the BSP is defined by the RISCV_MAXIMUM_EXTERNAL_INTERRUPTS
BSP option.
8.11.1.3. Clock Driver#
The clock driver uses the CLINT timer.
8.11.1.4. Console Driver#
The console driver supports devices compatible to:
“ucb,htif0” (depending on the
RISCV_ENABLE_HTIF_SUPPORT
BSP option),“ns16550a” (see
RISCV_CONSOLE_MAX_NS16550_DEVICES
BSP option),“ns16750” (see
RISCV_CONSOLE_MAX_NS16550_DEVICES
BSP option), and“sifive,uart0” (see
RISCV_ENABLE_SIFIVE_UART_SUPPORT
BSP option).
They are initialized according to the device tree. The console driver does not configure the pins or peripheral clocks. The console device is selected according to the device tree “/chosen/stdout-path” property value.
8.11.1.5. QEMU#
All of the BSP variants that start with rv can be run on QEMU’s virt and spike machines. For instance, to run the rv64imafdc
BSP with the following “config.ini” file.
[riscv/rv64imafdc]
Run the following QEMU command.
$ qemu-system-riscv64 -M virt -nographic -bios $RTEMS_EXE
$ qemu-system-riscv64 -M spike -nographic -bios $RTEMS_EXE
8.11.1.6. Spike#
All of the BSP variants that start with rv can be run on Spike. For instance, to run the rv64imafdc
BSP with the following “config.ini” file.
[riscv/rv64imafdc]
Run the following Spike command.
$ spike --isa=rv64imafdc $RTEMS_EXE
Unlike QEMU, Spike supports enabling/disabling a subset of the imafdc extensions and has support for further RISC-V extensions as well. A fault will be triggered if an executable built with rv64imafdc RISC-V’s -march option run on Spike with –isa=rv64i option. If no –isa option is specified, the default is rv64imafdc.
8.11.2. Microchip PolarFire SoC#
The PolarFire SoC is the 4x 64-bit RISC-V U54 cores and a 64-bit RISC-V E51 monitor core SoC from the Microchip.
The mpfs64imafdc
BSP variant supports the U54 cores but not the E51 because the E51 monitor core is reserved for the first stage bootloader (Hart Software Services). In order to boot from the first U54 core, RISCV_BOOT_HARTID
is set to 1 by default.
The device tree blob is embedded in the mpfs64imafdc
BSP variant by default with the BSP_DTB_IS_SUPPORTED
enabled and the DTB header path BSP_DTB_HEADER_PATH
is set to bsp/mpfs-dtb.h.
SMP test procedure for the Microchip PolarFire Icicle Kit:
The “config.ini” file.
[riscv/mpfs64imafdc]
BUILD_TESTS = True
RTEMS_POSIX_API=True
RTEMS_SMP = True
BSP_START_COPY_FDT_FROM_U_BOOT=False
BSP_VERBOSE_FATAL_EXTENSION = False
Build RTEMS.
$ ./waf configure --prefix=$HOME/rtems-start/rtems/7
$ ./waf
Convert .exe to .elf file.
$ riscv-rtems7-objcopy build/riscv/mpfs64imafdc/testsuites/smptests/smp01.exe build/riscv/mpfs64imafdc/testsuites/smptests/smp01.elf
Generate a payload for the smp01.elf
using the hss-payload-generator.
Copy
smp01.elf
file to the HSS/tools/hss-payload-generator/test directory.Go to hss-payload-generator source directory.
$ cd hart-software-services/tools/hss-payload-generator
Edit test/uboot.yaml file for the hart entry points and correct name of the binary file.
set-name: 'PolarFire-SoC-HSS::RTEMS'
hart-entry-points: {u54_1: '0x1000000000', u54_2: '0x1000000000', u54_3: '0x1000000000', u54_4: '0x1000000000'}
payloads:
test/smp01.elf: {exec-addr: '0x1000000000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_m, skip-opensbi: true}
Generate payload
$ ./hss-payload-generator -c test/uboot.yaml payload.bin
Once the payload binary is generated, it should be copied to the eMMC/SD.
FPGA design with HSS programming file.
Program the eMMC/SD with the payload binary.
Power Cycle the Microchip PolarFire Icicle Kit and stop at the HSS.
type “mmc” and then “usbdmsc” on the HSS terminal(UART0).
Load the payload.bin from the Host PC.
$ sudo dd if=payload.bin of=/dev/sdb bs=512
Reset the Microchip PolarFire SoC Icicle Kit.
Serial terminal UART1 displays the SMP example messages
*** BEGIN OF TEST SMP 1 ***
*** TEST VERSION: 6.0.0.ef33f861e16de9bf4190a36e4d18062c7300986c
*** TEST STATE: EXPECTED_PASS
*** TEST BUILD: RTEMS_POSIX_API RTEMS_SMP
*** TEST TOOLS: 12.1.1 20220622 (RTEMS 6, RSB 3cb78b0b815ba05d17f5c6
5865d246a8333aa087, Newlib ea99f21)
CPU 3 start task TA0
CPU 2 running Task TA0
CPU 3 start task TA1
CPU 1 running Task TA1
CPU 3 start task TA2
CPU 0 running Task TA2
*** END OF TEST SMP 1 ***
8.11.3. Kendryte K210#
The Kendryte K210 SoC is a dual core 64-bit RISC-V SoC with an AI NPU, built in SRAM, and a variety of peripherals. Currently just the console UART, interrupt controller, and timer are supported.
The device tree blob is embedded in the kendrytek210
BSP variant by default. When the kendrytek210 BSP variant is selected, BSP_DTB_IS_SUPPORTED
enabled and the DTB header path BSP_DTB_HEADER_PATH
is set to bsp/kendryte-k210-dtb.h
.
The kendrytek210
BSP variant has been tested on the following simulator and boards:
Renode.io simulator using the Kendrtye k210 model
Sipeed MAiX BiT board
Sipeed Maixduino board
Sipeed MAiX Dock board
Building the Kendryte K210 BSP
Configuration file config.ini
:
[riscv/kendrytek210]
RTEMS_SMP = True
Build RTEMS:
$ ./waf configure --prefix=$HOME/rtems-start/rtems/7
$ ./waf
Flash an executable to a supported K210 board
Binary images can be flashed to the Sipeed boards through the USB port using the kflash.py
utility available from the python pip utility.
$ riscv-rtems7-objcopy -Obinary ticker.exe ticker.bin
$ kflash.py --uart /dev/ttyUSB0 ticker.bin
After the image is flashed, the RTEMS image will automatically boot. It will also run when the board is reset or powered through the USB cable. The USB port provides the power and console UART. Plug the USB cable into a host PC and bring up a terminal emulator at 115200 baud, 8 data bits, 1 stop bit, no parity, and no flow control. On Linux the UART device is often /dev/ttyUSB0
.
Run a RTEMS application on the Renode.io simulator
RTEMS executables compiled with the kendrytek210 BSP can run on the renode.io simulator using the built-in K210 model. The simulator currently supports the console UART, interrupt controller, and timer.
To install renode.io please refer to the installation instructions. Once installed, save the following file as k210_rtems.resc
.
using sysbus
$bin?=@ticker.exe
mach create "K210"
machine LoadPlatformDescription @platforms/cpus/kendryte_k210.repl
showAnalyzer uart
sysbus Tag <0x50440000 0x10000> "SYSCTL"
sysbus Tag <0x50440018 0x4> "pll_lock" 0xFFFFFFFF
sysbus Tag <0x5044000C 0x4> "pll1"
sysbus Tag <0x50440008 0x4> "pll0"
sysbus Tag <0x50440020 0x4> "clk_sel0"
sysbus Tag <0x50440028 0x4> "clk_en_cent"
sysbus Tag <0x5044002c 0x4> "clk_en_peri"
macro reset
"""
sysbus LoadELF $bin
"""
runMacro $reset
After saving the above file in in the same directory as your RTEMS ELF images, start renode and load the k210_rtems.resc
script to start the emulation.
(monitor) s @k210_rtems.resc
You should see a renode UART window and the RTEMS ticker example output. If you want to run a different RTEMS image, you can edit the file or enter the following on the renode console.
(monitor) $bin=@smp08.exe
(monitor) s @k210_rtems.resc
The above example will run the SMP08 example instead of ticker.
Generating the Device Tree Header
The kendrytek210 BSP uses a built in device tree blob. If additional peripheral support is added to the BSP, the device tree may need to be updated. After editing the device tree source, compile it to a device tree blob with the following command:
$ dtc -O dtb -b 0 -o kendryte-k210.dtb kendryte-k210.dts
The dtb file can then be converted to a C array using the rtems-bin2c tool. The data for the device tree binary can then replace the existing device tree binary data in the kendryte-k210-dtb.h
header file.
8.11.4. BeagleV-Fire#
The BeagleV-Fire board is equipped with the Microchip’s PolarFire MPFS025T System on Chip (SoC), featuring a 5-core configuration. It includes 4 RV64GC cores for U54 and 1 RV64IMAC core for E51.
The Base BSP riscv/beaglevfire
for BeagleV-Fire board supports Clock, IRQs, Console and UART.
Configure the BSP: Following section in the INI-style configuration file, config.ini instructs the build system to build a riscv/beaglevfire
BSP variant
$ cd $HOME/quick-start/src/rtems
$ echo "[riscv/beaglevfire]" > config.ini
$ echo "BUILD_TESTS = True" >> config.ini
$ echo "RTEMS_POSIX_API = True" >> config.ini
$ echo "RTEMS_SMP = False" >> config.ini
$ echo "BSP_START_COPY_FDT_FROM_U_BOOT = False" >> config.ini
$ echo "BSP_VERBOSE_FATAL_EXTENSION = False" >> config.ini
The BeagleV-Fire supports Symmetric Multiprocessing (SMP) with its quad-core configuration. SMP enables efficient parallel processing across multiple cores, enhancing performance for multi-threaded applications.
RTEMS_SMP
: Set to False
to run the system in uniprocessor mode, where only one core (e.g., U54_1) handles processing.
To enable multiprocessing and utilize all available cores, set RTEMS_SMP = True
in config.ini. This configuration allows the BeagleV-Fire to utilize all cores efficiently for parallel processing tasks.
Generate a payload for executables using thehss-payload-generator
Copy executable file (e.g., hello.exe) to the HSS/tools/hss-payload-generator/test directory.
Go to hss-payload-generator source directory.
$ cd hart-software-services/tools/hss-payload-generator
Edit test/hss.yaml file for the hart entry points and correct name of the binary file (e.g., hello.exe).
A modified test/hss.yaml file is directly accessible in a fork
For uni-processing
:
set-name: 'PolarFire-SoC-HSS::RTEMS'
hart-entry-points: {u54_1: '0x1000000000'}
payloads:
test/hello.elf: {exec-addr: '0x1000000000', owner-hart: u54_1, priv-mode: prv_m, skip-opensbi: true}
For multi-processing
:
set-name: 'PolarFire-SoC-HSS::RTEMS'
hart-entry-points: {u54_1: '0x1000000000', u54_2: '0x1000000000', u54_3: '0x1000000000', u54_4: '0x1000000000'}
payloads:
test/hello.elf: {exec-addr: '0x1000000000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, secondary-hart: u54_4, priv-mode: prv_m, skip-opensbi: true}
Generate payload:
$ make
$ ./hss-payload-generator -c test/uboot.yaml payload.bin
Once the payload binary is generated, it should be copied to the eMMC/SD.
Program the eMMC/SD with the payload binary:
Setting Up UART Communication via the Debug serial console from the Host PC
List USB Serial Devices
$ ls /dev | grep -i ttyUSB
This will vary by host. The command lists all connected USB serial devices. Look for
ttyUSB0
or similar entries. See also the BeagleV-Fire docs.Modify the permissions of the identified USB serial device to allow read and write access
$ sudo chmod 777 /dev/ttyUSB0
Start a terminal session with the specified USB serial device at a baud rate of
115200
. This opens a communication channel between your host PC and the connected device
$ screen /dev/ttyUSB0 115200
Power up BeagleV-Fire board and stop at the HSS by pressing any key from keyboard (eg. Press
ENTER
)Enter HSS CLI commands
$ MMC
$ USBDMSC
These commands switch the HSS to handle MMC (MultiMediaCard) and USB Device Mass Storage Class operations, preparing it for the binary payload transfer.
Load the Payload from Host PC, use the
dd
command to copy the payload binary to the eMMC/SD card. Ensure the correct device path for eMMC/SD card. You can figure out which device to use for example by executingls -lt /dev/sd*
and seeing the most recently created disk, for example it could be/dev/sdg
. You should be careful to check this before running the command to flash the device:$ sudo dd if=payload.bin of=/dev/sdg bs=512
Reset the BeagleV-Fire board and check the output
*** BEGIN OF TEST HELLO WORLD ***
*** TEST VERSION: 6.0.0
*** TEST STATE: EXPECTED_PASS
*** TEST BUILD: RTEMS_POSIX_API
*** TEST TOOLS: 13.2.0 20230727 (RTEMS 6, RSB d24131ac781eeff8be5a4a5fd185d1be20176461, Newlib 176b19f)
Hello World
*** END OF TEST HELLO WORLD ***
8.11.5. noel#
This BSP supports the NOEL-V systems from Cobham Gaisler. The NOEL-V is a synthesizable VHDL model of a processor that implements the RISC-V architecture. It is part of the open source GRLIB IP Library. The following BSP variants correspond to common NOEL-V configurations:
noel32im
noel32imafd
noel64imac
noel64imafd
noel64imafdc
The start of the memory is set to 0x0 to match a standard NOEL-V system, but can be changed using the RISCV_RAM_REGION_BEGIN
configuration option. The size of the memory is taken from the information available in the device tree.
8.11.5.1. Reference Designs#
The BSP has been tested with NOEL-V reference designs for Digilent Arty A7, Microchip PolarFire Splash Kit, and Xilinx KCU105. See the accompanying quickstart guide for each reference design to determine which BSP configuration to use.
8.11.5.2. Build Configuration Options#
The following options can be used in the BSP section of the waf
configuration INI file. The waf
defaults can be used to inspect the values.
BSP_CONSOLE_USE_INTERRUPTS
Use the Termios interrupt mode in the console driver (true by default).
BSP_FDT_BLOB_SIZE_MAX
The maximum size of the device tree blob in bytes (262144 by default).
RISCV_CONSOLE_MAX_APBUART_DEVICES
The maximum number of APBUART devices supported by the console driver (2 by default).
RISCV_RAM_REGION_BEGIN
The begin of the RAM region for linker command file (0x0 by default).
RISCV_MAXIMUM_EXTERNAL_INTERRUPTS
The maximum number of external interrupts supported by the BSP (64 by default).
8.11.6. griscv#
This RISC-V BSP supports chips using the GRLIB.
8.11.7. NIOS V#
This BSP supports the NIOS V systems from Intel. The NIOS V is a synthesizable Verilog model of a processor that implements the RISC-V architecture. It is part of the Intel Quartus Prime Design Software and free licenses can be obtained from the Intel FPGA Self- Service Licensing Center. The following BSP variant corresponds to an example configuration of a NIOS V system running on an Intel FPGA Development Board:
niosvc10lp - Cyclone 10 LP Evaluation Board ($99)
The NIOS V IP comes in three variants: NIOS V/c
, NIOS V/m
, and NIOS V/g
. The NIOS V/c
does not support an OS (no interrupt controller). The NIOS V/m
is a bare bones CPU with an interrupt controller, trap controller, ECC module, timer, arihmetic logic unit, general purpose registers, control and status registers, instruction/data buses, and JTAG debug module. The NIOS V/g
includes all the features of the NIOS V/m
but adds an integer mul/div unit, a floating point unit, support for custom instructions, tightly coupled memory, and instruction/data caches. The floating point unit can be disabled on the NIOS V/g to save resources.
8.11.7.1. Reference Designs#
The BSP has been tested on the Intel Cyclone 10 LP Evaluation board. The reference design and how it was made can be found here. This compressed folder contains a README.md
file which describes how the reference design was built. The reference design implemented three different variants of the NIOS V processor: V/m, V/g, V/g with FPU.
8.11.7.2. Build Configuration Options#
The following options will need to be used in the BSP section of the waf
configuration INI file. The waf
defaults can be used to inspect the values.
NIOSV_EPCQ_ROM_REGION_BEGIN
The starting address of the EPCQ device connected to the NIOS V (0x11000000 by default).
NIOSV_EPCQ_ROM_REGION_SIZE
The size of the EPCQ device connected to the NIOS V (0x01000000 by default).
NIOSV_ONCHIP_ROM_REGION_BEGIN
The starting address of the On-Chip ROM connected to the NIOS V (0x10010000 by default).
NIOSV_ONCHIP_ROM_REGION_SIZE
The size of the On-Chip ROM connected to the NIOS V (4096 by default).
NIOSV_ONCHIP_RAM_REGION_BEGIN
The starting address of the On-Chip RAM connected to the NIOS V (0x10020000 by default).
NIOSV_ONCHIP_RAM_REGION_SIZE
The size of the On-Chip RAM connected to the NIOS V (8192 by default).
NIOSV_EXT_RAM_REGION_BEGIN
The starting address of the external RAM connected to the NIOS V (0x01000000 by default).
NIOSV_EXT_RAM_REGION_SIZE
The size of the external RAM connected to the NIOS V (0x00800000 by default).
NIOSV_IS_NIOSVG
Whether or not the
NIOS V/g
processor is used (false by default).NIOSV_HAS_FP
Whether or not the
NIOS V/g
processor has a FPU (false by default).
8.11.7.3. Building the Cyclone 10 LP BSP#
Configuration file config.ini
for NIOS V/m:
[riscv/niosvc10lp]
NIOSV_EPCQ_ROM_REGION_BEGIN = 0x11000000
NIOSV_EPCQ_ROM_REGION_SIZE = 0x01000000
NIOSV_ONCHIP_ROM_REGION_BEGIN = 0x10010000
NIOSV_ONCHIP_ROM_REGION_SIZE = 4096
NIOSV_ONCHIP_RAM_REGION_BEGIN = 0x10020000
NIOSV_ONCHIP_RAM_REGION_SIZE = 8192
NIOSV_EXT_RAM_REGION_BEGIN = 0x01000000
NIOSV_EXT_RAM_REGION_SIZE = 0x00800000
NIOSV_IS_NIOSVG = False
NIOSV_HAS_FP = False
Configuration file config.ini
for NIOS V/g:
[riscv/niosvc10lp]
NIOSV_EPCQ_ROM_REGION_BEGIN = 0x11000000
NIOSV_EPCQ_ROM_REGION_SIZE = 0x01000000
NIOSV_ONCHIP_ROM_REGION_BEGIN = 0x10010000
NIOSV_ONCHIP_ROM_REGION_SIZE = 4096
NIOSV_ONCHIP_RAM_REGION_BEGIN = 0x10020000
NIOSV_ONCHIP_RAM_REGION_SIZE = 8192
NIOSV_EXT_RAM_REGION_BEGIN = 0x01000000
NIOSV_EXT_RAM_REGION_SIZE = 0x00800000
NIOSV_IS_NIOSVG = True
NIOSV_HAS_FP = False
Configuration file config.ini
for NIOS V/g with FPU:
[riscv/niosvc10lp]
NIOSV_EPCQ_ROM_REGION_BEGIN = 0x11000000
NIOSV_EPCQ_ROM_REGION_SIZE = 0x01000000
NIOSV_ONCHIP_ROM_REGION_BEGIN = 0x10010000
NIOSV_ONCHIP_ROM_REGION_SIZE = 4096
NIOSV_ONCHIP_RAM_REGION_BEGIN = 0x10020000
NIOSV_ONCHIP_RAM_REGION_SIZE = 8192
NIOSV_EXT_RAM_REGION_BEGIN = 0x01000000
NIOSV_EXT_RAM_REGION_SIZE = 0x00800000
NIOSV_IS_NIOSVG = True
NIOSV_HAS_FP = True
Build RTEMS:
$ ./waf configure --prefix=$HOME/rtems-start/rtems/7
$ ./waf
8.11.7.4. Program Cyclone 10 LP Evaluation Board#
The README.md
file in the compressed folder describes how to build the FPGA configuration file, On-Chip ROM boot loader to load an executable from the EPCQ device to external RAM, an application executable, and a rtems_xx.jic
file for programming onto the EPCQ device using the Quartus programmer.
8.12. sparc (SPARC / LEON)#
8.12.1. erc32#
TODO.
8.12.2. leon2#
This BSP supports LEON2 systems, in particular the Microchip AT697F. The following default build configurations are provided:
leon2 - A generic LEON2 system with memory at 0x4000000.
at697f - For the AT697F. Built with
-mcpu=leon -mfix-at697f
.
The BSP contains UART, timer, and interrupt controller drivers. Drivers for PCI are available through the driver manager.
8.12.3. leon3#
This BSP supports the LEON3/4/5 systems from Cobham Gaisler. The following default build configurations are provided:
leon3 - A generic LEON3/4/5 system with memory at 0x4000000.
ut700 - For the UT700. Built with
-mcpu=leon3 -mfix-ut700
.ut699 - For the UT699. Built with
-mcpu=leon -mfix-ut699
.gr712rc - For the GR712RC. Built with
-mcpu=leon3 -mfix-gr712rc
.gr740 - For the GR740. Memory located at address 0x0.
The BSP contains UART, timer, and interrupt controller drivers. Drivers for additional peripherals are available through the driver manager.
8.12.3.1. Driver Manager#
The leon3 BSP includes an optional driver manager that handles drivers and devices on the AMBA and PCI Plug & Play buses. The driver manager can either be initialized manually by the user, or started automatically on startup by setting the RTEMS_DRVMGR_STARTUP
option. It can be configured to automatically instantiate a driver for each hardware device found.
Drivers for the following devices are provided and handled via the driver manager:
SpaceWire (GRSPW, GRSPW2, GRSPW2_DMA)
SpaceWire Router (GRSPWROUTER)
SpaceWire Time Distribution Protocol (SPWTDP)
CAN - non-DMA (OCCAN) and DMA (GRCAN, GRCANFD)
GPIO (GRGPIO)
L2 Cache (L2CACHE)
IOMMU (GRIOMMU)
ADC/DAC (GRADCDAC)
Timers (GPTIMER, GRTIMER)
1553 BC, RT and BM support (GR1553B)
I2C Master (I2CMST)
PCI (GRPCI2, GRPCI, PCIF)
Memory Controller (MCTRL)
Memory Scrubber (MEMSCRUB)
Pulse Width Modulation Generator (GRPWM)
CCSDS/ECSS Telemetry Encoder/Decoder (GRTM/GRTC)
CSDS Time Manager (GRCTM)
Ethernet (GRETH 10/100/1000) (requires network stack)
Performance counters (L4STAT)
Serial Peripheral Interface (AHBSTAT)
AHB Status (AHBSTAT)
8.12.3.2. Build Configuration Options#
The following options can be used in the BSP section of the waf
configuration INI file. The waf
defaults can be used to inspect the values.
CONSOLE_USE_INTERRUPTS
Use the Termios interrupt mode in the console driver (false by default).
RTEMS_DRVMGR_STARTUP
Enable the Driver Manager at startup (false by default).
8.13. x86_64#
8.13.1. amd64#
This BSP offers two variants: amd64
and amd64efi
. The BSP can run on UEFI-capable systems by using the FreeBSD bootloader in the case of amd64
or a multiboot2 compliant bootloader in the case of amd64efi
. The main difference of amd64efi
is that it utilizes the UEFI Boot Services for its functionality.
Currently the console driver, clock driver, and context switching are functional. ACPI functionality is supported through ACPICA and used for SMP (only supported in amd64
).
8.13.1.1. Build Configuration Options#
There are no BSP configuration options available at build time.
8.13.1.2. Testing with QEMU#
To test with QEMU, we need to:
Build / install QEMU (most distributions should have it available on the package manager).
Build UEFI firmware that QEMU can use to simulate an x86-64 system capable of booting a UEFI-aware kernel, through the
--bios
flag.
Building TianoCore’s UEFI firmware, OVMF#
Complete detailed instructions are available at TianoCore’s Github’s wiki.
Quick instructions (which may fall out of date) are:
$ git clone git://github.com/tianocore/edk2.git
$ cd edk2
$ make -C BaseTools
$ . edksetup.sh
Then edit Conf/target.txt
to set:
ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc
TARGET = DEBUG
TARGET_ARCH = X64
# You can use GCC46 as well, if you'd prefer
TOOL_CHAIN_TAG = GCC5
Then run build
in the edk2
directory - the output should list the location of the OVMF.fd
file, which can be used with QEMU to boot into a UEFI shell.
You can find the OVMF.fd
file like this as well in the edk2 directory:
$ find . -name "*.fd"
./Build/OvmfX64/DEBUG_GCC5/FV/MEMFD.fd
./Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd # the file we're looking for
./Build/OvmfX64/DEBUG_GCC5/FV/OVMF_CODE.fd
./Build/OvmfX64/DEBUG_GCC5/FV/OVMF_VARS.fd
Booting RTEMS in QEMU#
The amd64
variant supports being booted through the FreeBSD bootloader (Booting via the FreeBSD bootloader), meanwhile the amd64efi
variant supports being booted by a multiboot2 compliant bootloader, such as GRUB (Booting via GRUB).
Booting via the FreeBSD bootloader#
Note
The following section describes how to boot RTEMS using a FreeBSD VM, for a more self contained alternative check out Creating a FreeBSD Boot Image
The RTEMS executable produced (an ELF file) needs to be placed in the FreeBSD’s /boot/kernel/kernel
’s place.
To do that, we first need a hard-disk image with FreeBSD installed on it. Download FreeBSD’s installer “memstick” image for amd64 and then run the following commands, replacing paths as appropriate.
$ qemu-img create freebsd.img 8G
$ OVMF_LOCATION=/path/to/ovmf/OVMF.fd
$ FREEBSD_MEMSTICK=/path/to/FreeBSD-11.2-amd64-memstick.img
$ qemu-system-x86_64 -m 1024 -serial stdio --bios $OVMF_LOCATION \
-drive format=raw,file=freebsd.img \
-drive format=raw,file=$FREEBSD_MEMSTICK
The first time you do this, continue through and install FreeBSD. FreeBSD’s installation guide may prove useful if required.
Once installed, build your RTEMS executable (an ELF file), for eg. hello.exe
. We need to transfer this executable into freebsd.img
’s filesystem, at either /boot/kernel/kernel
or /boot/kernel.old/kernel
(or elsewhere, if you don’t mind user FreeBSD’s loader
’s prompt to boot your custom kernel).
If your host system supports mounting UFS filesystems as read-write (eg. FreeBSD), go ahead and:
Mount
freebsd.img
as read-writeWithin the filesystem, back the existing FreeBSD kernel up (i.e. effectively
cp -r /boot/kernel /boot/kernel.old
).Place your RTEMS executable at
/boot/kernel/kernel
If your host doesn’t support mounting UFS filesystems (eg. most Linux kernels), do something to the effect of the following.
On the host
# Upload hello.exe anywhere accessible within the host
$ curl --upload-file hello.exe https://transfer.sh/rtems
Then on the guest (FreeBSD), login with root
and
# Back the FreeBSD kernel up
$ cp -r /boot/kernel/ /boot/kernel.old
# Bring networking online if it isn't already
$ dhclient em0
# You may need to add the --no-verify-peer depending on your server
$ fetch https://host.com/path/to/rtems/hello.exe
# Replace default kernel
$ cp hello.exe /boot/kernel/kernel
$ reboot
After rebooting, the RTEMS kernel should run after the UEFI firmware and FreeBSD’s bootloader. The -serial stdio
QEMU flag will let the RTEMS console send its output to the host’s stdio
stream.
Booting via GRUB#
All that is required is for GRUB to be configured to boot the executable through multiboot2. This section simply shows a possible way of achieving this.
We are going to create a single EFI System Partition (ESP) containing the GRUB binary and our executable. First, create the proper file structure for the ESP:
$ mkdir -p RTEMS-GRUB/EFI/BOOT
We are going to need a valid grub.cfg
file. The following example will configure GRUB to search for a file named “rtems” in the root of the partition and boot it with multiboot2 instantly:
set timeout=0
set default=0
search --file --set=root /rtems
menuentry 'RTEMS' {
multiboot2 /rtems
boot
}
With this in place we can generate a GRUB binary containing the grub.cfg
and required modules on EFI/BOOT/BOOTX64.EFI
(the default boot loader file for UEFI systems):
$ grub-mkstandalone --format=x86_64-efi --fonts="" --locales="" --themes="" \
--install-modules="normal search fat multiboot2" \
boot/grub/grub.cfg=grub.cfg -o RTEMS-GRUB/EFI/BOOT/BOOTX64.EFI
And then copy the executable you desire to boot to /rtems
(as specified by our grub.cfg
) in our ESP:
$ cp ${rtems-executable} RTEMS-GRUB/rtems
With all this in place we will use the makefs
tool (which is contained in the x86_64 build set in the RTEMS Source Builder) to create a FAT32 image out of the file structure:
$ makefs -t msdos -s 50m RTEMS-GRUB.img RTEMS-GRUB
And now all that is left is booting the image with QEMU:
$ qemu-system-x86_64 -m 512 -serial stdio --bios $OVMF_LOCATION \
-drive format=raw,file=RTEMS-GRUB.img
Note
The guide in this section uses the makefs tool to create the final FAT32 image out of the ESP file structure. Using makefs is not required as long as you can create a FAT32 image containing the same exact file structure.
8.13.1.3. Using the RTEMS tester#
Both amd64
and amd64efi
contain tester configuration files for using the RTEMS tester tool, but they require user configuration.
The amd64
requires the path to the FreeBSD boot image which will be used by the tester tool (Creating a FreeBSD Boot Image). Meanwhile both amd64
and amd64efi
require the path to OVMF (Building TianoCore’s UEFI firmware, OVMF).
An example of the user configuration file:
[amd64_qemu]
amd64_ovmf_path = {OVMF_PATH}
amd64_freebsd_boot_image_path = {FREEBSD_BOOT_IMAGE_PATH}
[amd64efi_grub_qemu]
amd64_ovmf_path = {OVMF_PATH}
Creating a FreeBSD Boot Image#
Note
You can instead choose to download a working boot image here. For directly using the boot image with QEMU go to Booting in QEMU Using the Boot Image:
To acquire or build the FreeBSD bootloader a FreeBSD machine or VM is required. You can either copy the files already present under /boot
or build them yourself.
To build the bootloader yourself, assuming the FreeBSD source tree is under /usr/src
, head over to /usr/src/stand
and run the following commands:
$ make
$ make install DESTDIR={bootloader-path}
Note
The directories usr/share/man/man3
, usr/share/man/man5
, and usr/share/man/man8
must be created under {bootloader-path}
before running make install
Next create the EFI disk image with the FreeBSD bootloader under EFI/BOOT/BOOTX64.EFI
(the default boot loader file for UEFI systems):
$ mkdir -p efi-image/EFI/BOOT/
$ cp {bootloader-path}/loader.efi efi-image/EFI/BOOT/BOOTX64.EFI
$ makefs -t msdos -s 1m EFI.img efi-image
And then the FreeBSD Root FS disk image:
$ mkdir -p rootfs-image/boot/
$ cp -r {bootloader-path}/defaults rootfs-image/boot/
$ cp -r {bootloader-path}/lua rootfs-image/boot/
The following configuration file will instruct the FreeBSD loader to instantly load the file /rtems
contained in the second disk. It should be created under rootfs-image/boot/loader.conf
beastie_disable="YES"
kernel="/rtems"
currdev="disk1"
autoboot_delay="0"
And then we can convert rootfs-image
to an UFS disk image and use the mkimg
tool to create a singular image with both partitions:
makefs -t ffs -o version=2 ROOTFS.img rootfs-image
mkimg -s gpt -p efi:=EFI.img -p freebsd-ufs:=ROOTFS.img -o FreeBSDBoot.img
Booting in QEMU Using the Boot Image:#
You can use the boot image to run any rtems executable with QEMU as such:
$ mkdir rtems-image
$ cp {rtems-executable} rtems-image/rtems
$ makefs -t ffs -o version=2 rtems.img rtems-image
$ qemu-system-x86_64 -m 1024 -serial stdio --bios {OVMF_LOCATION} \
-drive format=raw,file=FreeBSDBoot.img \
-drive format=raw,file=rtems.img
8.13.1.4. Paging#
During the BSP’s initialization, the paging tables are setup to identity-map the first 512GiB, i.e. virtual addresses are the same as physical addresses for the first 512GiB.
The page structures are set up statically with 1GiB super-pages.
Note
Page-faults are not handled.
Warning
RAM size is not detected dynamically and defaults to 1GiB, if the configuration-time RamSize
parameter is not used.
8.13.1.5. Interrupt Setup#
Interrupt vectors 0
through 32
(i.e. 33 interrupt vectors in total) are setup as “RTEMS interrupts”, which can be hooked through rtems_interrupt_handler_install
.
The Interrupt Descriptor Table supports a total of 256 possible vectors (0 through 255), which leaves a lot of room for “raw interrupts”, which can be hooked through _CPU_ISR_install_raw_handler
.
Since the APIC needs to be used for the clock driver, the PIC is remapped (IRQ0 of the PIC is redirected to vector 32, and so on), and then all interrupts are masked to disable the PIC. In this state, the PIC may _still_ produce spurious interrupts (IRQ7 and IRQ15, redirected to vector 39 and vector 47 respectively).
The clock driver triggers the initialization of the APIC and then the APIC timer.
The I/O APIC is not supported at the moment.
Note
IRQ32 is reserved by default for the APIC timer (see following section).
IRQ33 is reserved by default for interprocessor interrupts if SMP is enabled.
IRQ255 is reserved by default for the APIC’s spurious vector.
Warning
Besides the first 33 vectors (0 through 32), and vector 255 (the APIC spurious vector), no other handlers are attached by default.
8.13.1.6. Clock Driver#
amd64#
The clock driver currently uses the APIC timer. Since the APIC timer runs at the CPU bus frequency, which can’t be detected easily, the PIT is used to calibrate the APIC timer, and then the APIC timer is enabled in periodic mode, with the initial counter setup such that interrupts fire at the same frequency as the clock tick frequency, as requested by CONFIGURE_MICROSECONDS_PER_TICK
.
amd64efi#
The clock driver uses the SetTimer UEFI boot service.
8.13.1.7. Console Driver#
amd64#
The console driver defaults to using the COM1
UART port (at I/O port 0x3F8
), using the NS16550
polled driver.
amd64efi#
The console driver uses the UEFI Simple Text Output Protocol
9. Executables#
This section discusses what an RTEMS executable is and what happens when you execute it in a target. The section discusses how an application executable is created, what happens when an executable is loaded and run, debugging an execiutable, and creating and dynamically loading code.
9.1. RTEMS Executable#
Running executables is the most important part of working with RTEMS, it is after all how you run your application and use the RTEMS kernel services.
An RTEMS executable is embedded in a target and executing an embedded executable has challenges not faced when executing software on a desktop or server computer. A desktop or server operating system kernel provides all the support needed to bring an executable’s code and data into a process’s address space passing control to it and cleaning up when it exits. An embedded target has to provide similar functionality to execute an embedded executable.
An RTEMS Source Builder (RSB) built RTEMS tool chain is used to create RTEMS executables. The tool chain executable creates a fixed position statically linked Extendable Loader Format (ELF) file that contains the RTEMS kernel, standard libraries, third-party libraries and application code. RTEMS executes in a single address space which means it does not support the fork
or exec
system calls so statically linking all the code is the easiest and best way to create an executable.
An RTEMS application is constructed vertically with the RTEMS kernel, BSP support code and drivers close to the hardware, above which sit the RTEMS Application Programming Interfaces (API) for control of threads, mutex and other resources an application may use. Middle-ware services like networking, interpreted languages, and protocol stacks sit between the RTEMS APIs and the application components. The software built into an executable can be see as a vertical software stack.
Fig. 9.1 Vertical Software Stack#
9.2. Building an Application#
RTEMS views any code it is running and using it’s interfaces as an application. RTEMS conforms to a number of international standards such as POSIX and can build and run portable code written in languages such as C, C++ and Ada.
Applications are built from source into ELF object files, third-party packages can be built as libraries or they can be imported as source into an application code base. The application, third-party packages, RTEMS and standard libraries are linked to create the RTEMS executable. The executable is transferred to the target and a bootloader loads it from the non-volatile storage into RAM or the code is executed in place in the non-volatile storage. The target hardware defines what happens.
Fig. 9.2 Building an Application#
The standard and third-party libraries are a collection of object files built using the same set of tools the application source is compiled with. The package collects it’s object files into an archive or library.
RTEMS does not provide a standard application build system. The RTEMS ecosystem provides support so a range of build systems can be used. Applications can be built with make
, autotools
, cmake
, waf
and more. User should select a build system that meets their project, system, corporate or personal needs.
9.2.1. Machine Flags and ABI#
All code in an RTEMS executable must be built with the same machine flags. The machine flags control the instruction set and application binary interface (ABI) the compiler generates. As the executable is statically linked all code must use the same instruction set the hardware is configured to support and all code must conform to the same ABI. Any variation can result in unpredictable behavior such as crashes, failures or lock ups. It is recommend an executable is built with the same or equivalent tool set. Mixing of tool set versions can also result in undefined behavior. The RTEMS tool rtems-execinfo
can audit an RTEMS executable and list the machine flags and compilers used.
RTEMS by default does not support instruction emulation for unsupported instructions. RTEMS applications are normally built from source so binary compatibility is not as important as performance. Instruction emulation is costly to execute and rebuilding the executable with the correct instruction set only needs to be done once.
9.3. Target Execution#
Fixed position statically linked executables have a fixed address in a target’s address space. The location in the address space for code, data and read-only data is fixed. The BSP defines the memory map and it is set by the BSP developer based on the target’s hardware requirements and it’s bootloader.
Targets typically contains a bootloader that is executed after the target’s processor exits reset. A bootloader is specific to a target’s processor and hardware configuration and is responsible for the low level initialization of the hardware resources needed to load and execute an operating system’s kernel. In the case of RTEMS this is the RTEMS executable.
Bootloaders vary in size, complexity and functionality. Some architectures have a number of bootloader stages and others have only minimal support. An example of a high end system is Xilinx’s Zynq processor with three stages. First a mask ROM in the System On Chip (SOC) executes after reset loading a first stage bootloader (FSBL) from an SD card, QSPI flash or NAND flash depending on signals connected to the device. The FSBL loads a second stage bootloader (SSBL) such as U-Boot and this loads the kernel. U-Boot can be configured to load a kernel from a range of media and file system formats as well as over a network using a number of protocols. This structure provides flexibility at the system level to support development environments such as a workshop or laboratory through to tightly control production configurations.
Bootloaders often have custom formats for the executable image they load. The formats can be simple to keep the bootloader simple or complex to support check-sums, encryption or redundancy in case an image becomes corrupted. A bootloader often provides a host tool that creates the required file from the RTEMS executable’s ELF file.
If RTEMS is to run from RAM the bootloader reads the image and loads the code, initialized data and read-only data into the RAM and then jumps to a known entry point. If the code is executed from non-volatile storage the process to write the image into that storage will have extracted the various binary parts and written those to the correct location.
The important point to note is the binary parts of the executable are somehow loaded into the target’s address space ready to execute. The way this done may vary but the out come is always the same, the binary code, data and read-only data is resident in the processor’s address space at the BSP defined addresses.
9.4. BSP Initialization#
The bootloader jumps or calls the RTEMS executable’s entry point, normally a fixed address. The BSP entry point or start up code performs:
Low level processor specific initialization that such as setting control registers so the processor is operating in a mode RTEMS is built for
Cache flushing, clearing and invalidation
Memory management unit (MMU) set up if required
Clear the uninitialized data section
Process a command line if supported by the bootloader
Call
bootcard
which disabled interrupts, saves away a command line if the BSP supports it then call the RTEMS kernel early initialize entry pointrtems_initialize_executive
. This call never returns.
Further BSP initialization happens as part of RTEMS kernel’s System Initialization process. The following handlers are declared and if provided are placed at the beginning of the initialization handler list. The BSP can provides:
bsp_work_area_initialize
This function determines the amount of memory that can be given to RTEMS for the workspace and the C library heap which
malloc
uses. The call typically uses thebsp_work_area_initialize_default
to perform actually perform the initialization.bsp_start
This function is specialized for each architecture and even for some BSPs. It performs the low level initialization RTEMS needs so it can run on the architecture and BSP.
bsp_predriver_hook
This function can be used to initialize hardware drivers depend on such as configuring an interrupt controller. The default version is empty and does nothing.
BSPs all perform similar operations with common functionality and the RTEMS kernel provides common code that can be shared between BSPs. The use of the common code is encouraged for all new BSPs.
9.5. RTEMS Initialization#
The RTEMS kernel initialization is:
Invoke the registered system initialization handlers
Set the system state to up
If the kernel supports SMP request multitasking start. All online cores are transferred to the ready to start multitasking state.
Start threaded multitasking. RTEMS starts multitasking by getting the first thread to run and dispatching it.
C++ static object constructors are called in the context of the first running thread before the thread body is entered.
9.5.1. System Initialization Handlers#
RTEMS supports the automatic registration of services used in applications. This method of initialization automatically configures RTEMS with only the services used in an application. There is no manual configuration of services used and no updating of initialization function tables.
RTEMS uses specialized sections in the ELF executable to perform this task. The system is based on the FreeBSD SYSINT Framework. Ordered initialization is performed before multitasking is started.
The RTEMS Tool rtems-exeinfo
can provide some detail about the registered handlers. The following shows the initialization handlers for the Hello World sample application in the RTEMS kernel’s testsuite:
$ rtems-exeinfo --init arm-rtems7/c/xilinx_zynq_zedboard/testsuites/samples/hello.exe
RTEMS Executable Info 7.5416cfa39dd6
exe: arm-rtems7/c/xilinx_zynq_zedboard/testsuites/samples/hello.exe
Compilation:
Producers: 2
| GNU AS 2.31.1: 14 objects
| GNU C11 7.3.0 20180125 (RTEMS 7, RSB e55769c64cf1a201588565a5662deafe3f1ccdcc, Newlib 103b055035fea328f8bc7826801760fb1c055683): 284 objects
Common flags: 4
| -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard
Init sections: 2
.init_array
0x001047c1 frame_dummy
.rtemsroset
0x00104c05 bsp_work_area_initialize
0x00104c41 bsp_start
0x0010eb45 zynq_debug_console_init
0x0010ec19 rtems_counter_sysinit
0x0010b779 _User_extensions_Handler_initialization
0x0010c66d rtems_initialize_data_structures
0x00107751 _RTEMS_tasks_Manager_initialization
0x0010d4f5 _POSIX_Keys_Manager_initialization
0x0010dd09 _Thread_Create_idle
0x0010cf01 rtems_libio_init
0x001053a5 rtems_filesystem_initialize
0x0010546d _Console_simple_Initialize
0x0010c715 _IO_Initialize_all_drivers
0x001076d5 _RTEMS_tasks_Initialize_user_tasks_body
0x0010cfa9 rtems_libio_post_driver
The section .rtemsroset
lists the handlers called in order. The handlers can be split into the BSP initialization handlers that start the BSP:
bsp_work_area_initialize
bsp_start
zynq_debug_console_init
rtems_counter_sysinit
And the remainder are handlers for services used by the application. The list varies based on the services the application uses.
9.6. Dynamic Loader#
RTEMS supports dynamically loading of executable code and data in the form of object files into a running system where the run-time loaded code can be executed and data accessed
This section describes RTEMS loader, preparing and loading executable code into a running system, the supported architectures and any limitation that may exist with an architecture.
The RTEMS operating system contains a link editor that runs on the target. The link editor supports loading Extendable Linker Format (ELF) relocatable executable object files locating the code and data in the target’s address space as it is loaded. An executable object file’s external references to function identifiers and data object identifiers are resolved and any external symbols can be made available in the global symbol table. The executing performance of dynamically loaded code is similar to the same code statically linked into an executable. This is a core requirement of the RTEMS link editor.
Fig. 9.3 Run Time Loader (libdl)#
The RTEMS operating system’s dynamic loader is not the same as the dynamic shared library support Unix or Windows have. Those operating systems use dynamic loading to share code between processes and this is an important feature in their design. RTEMS is a single address space operating system and that means there is no ability to share code at run-time. As a result code is loaded in a similar manner to static linking removing the need for any overheads sharing code may have.
To load an executable object file it must be resident on a target and accessible by RTEMS’s file system. The executable object file can be a single file or a collection in a library stored using the Unix standard archive format. The RTEMS loader supports the extended GNU format for long file names in archives.
The RTEMS developers do not see dynamically loading of code as a real-time activity. A system should not respond to real-time external events by loading code. The loading of code should happen before a system is considered available and the activity the system is experiencing is low and stable.
The statically linked executable that is loaded and run after reset is called the base image. The base image contains your base application that is used to dynamically load code, a global symbol table, the parts of the RTEMS operating system code used in the base image as well as functions and data from the tool suite libraries and packages you are using. Only the software referenced is used to create the base image. The parts of the libraries not referenced are not part of the executable or present in the global symbol table.
Application software can locate a symbol by name and call the address or reference the data at that address. A function identifier located by a symbol does not have it’s signatures checked, it is the responsibility of the caller to make sure the function is called with the correct arguments. It is the same for data objects, there is no type checking. Symbol versioning is not supported and supporting it does not make sense within the RTEMS operating system. An RTEMS target system is closed to normal users and software needs to be built from the same tool set and header files used to the build the base image.
An executable object file’s text or code has to be built for the target’s architecture it is loaded on and it must be built with the same ABI flags the base image is built with. See Machine Flags and ABI.
9.6.1. System Design#
The use of dynamic loading in a project is a system design decision. Some systems will have strict requirements where loading code into a live system is not allowed while other projects will benefit from the system level flexibility dynamically loading code provides.
Code loaded at run time needs to be resident or accessible to the target via RTEMS’s file system. Targets that have suitable media or a network interface to NFS servers to hold the executable object and library files are best suited.
Dynamically loading code uses more memory than statically linking the same code into the base image. The link editor maintains symbol tables where each symbol is a string, an address, and some additional data. The executable object files resident in memory each have data to manage them, the memory they use, and any dependencies they might have. The link editor is designed to minimize the memory overheads however only statically linked executables have no memory overhead.
The link editor relocates the code and data into RAM fixing it to the load address as it is loaded. A target needs to have suitably configured memory available for the executable object file to reside in. The memory must be able to support read, write and executable type access. Fine control of the memory and it’s modes can be supported using a customer allocator. Examples are systems that have a custom memory map, specialized memory for the execution of code or a requirement for read-only executable sections.
The load address of an executable object file is determined by the load order and the allocator used. The default allocator for the link editor is the system heap which means the location a specific executable object file is loaded at depends on the memory allocated before it is loaded and when in the load order it is loaded. A statically linked executable’s address map is fixed and this is considered important in some systems. A dynamically loaded system can be loaded in a repeatable manner if the load order is the same and the initialization sequence of the system is controlled. A custom allocator may also help.
Management of dynamically loadable object files and libraries adds to the configuration management of the hosts in a project. The loadable files need to be released and tracked in a suitable configuration management process just like the base image is. Executable object files and libraries are specific to a version of RTEMS and cannot be mixed or moved and this needs to be carefully managed. Currently there are no checks an executable object file matches the version of the base image it is being loaded on. These extra configuration controlled items add to the overheads of a project and need to be considered.
Dynamically loadable systems have a number of features that benefit some systems and products. Systems can be built on a base of trusted or golden modules. A number of projects using a common base of hardware can make use of proven modules reducing the testing and qualification overhead for each new release. A tested base image with libraries for common and available boards provides a simple and fast way for new users to trial and use RTEMS.
A project can use dynamic loading during development, shipping statically linked executables in production. Hardware used by a development team can have more memory, extra media for disk drives, or a network interface.
9.6.2. Loader Interface#
Run-time executable object file loading and management is via the standard’s based calls provided by the header file <dlfcn.h>
. The details of the calls follow.
void* dlopen(const char* path, int mode);
The
dlopen()
function makes the symbols (function identifiers and data object identifiers) in the executable object file specified byfile
available to the calling program.The executable object files eligible for this operation are in the ELF format.
The link loader may load embedded dependencies in executable object files. In such cases, a
dlopen()
operation may load those dependencies in addition to the executable object file specified byfile
.A successful
dlopen()
returns ahandle
which the caller may use on subsequent calls todlsym()
,dlinfo()
anddlclose()
.The value of the
handle
should not be interpreted in any way by the caller.Subsequent calls to
dlopen()
for the same executable object file increases the references to it.The
file
argument is used to construct a pathname to the executable object file or archive library of executable object files. If thefile
argument contains a colon (:
) the name of the executable object file in the library follows and this file name may optionally end with@
followed by a number which is the absolute offset in the library file where the executable object file starts. If an executable object file is not detected at the offset the archive library’s file table is searched.If
file
is a null pointer,dlopen()
returns a global symbol table handle. Thishandle
provides access to the global symbols from an ordered set of executable object files consisting of the original base image file, the set of executable object files loaded usingdlopen()
operations with theRTLD_GLOBAL
flag, and any dependencies loaded. As the latter sets of executable object files can change during execution, the set of symbols made available by thishandle
can also change dynamically.Only a single copy of an executable object file is brought into the address space, even if
dlopen()
is invoked multiple times in reference to the executable object file, and even if different pathnames are used to reference the executable object file.Unresolved external symbols do not cause an error to be returned allowing the loading of jointly dependent executable object files.
If
dlopen()
fails, it returns a null pointer, and sets an error condition which may be interrogated withdlerror()
.The
mode
parameter describes howdlopen()
operates uponfile
with respect to the processing of relocations and the scope of visibility of the symbols provided withinfile
. When an executable object file is brought into the address space, it may contain references to symbols whose addresses are not known until the executable object file is loaded.If a loaded executable object file and any dependent executable object files loaded with it contain any initialiser functions, they are called in the order loaded before
dlopen()
returns.The modes
RTLD_LAZY
andRTLD_NOW
do not effect the type of relocation performed, it is same for both modes. All relocations of an executable object file and any dependent executable object files loaded with it are completed before thedlopen()
call returns. The execution performance of the code loaded can be considered deterministic oncedlopen()
has returned.Any executable object file loaded by
dlopen()
can reference global symbols in the base image, any executable object files loaded included in the samedlopen()
invocation, and any executable object files that were loaded in anydlopen()
invocation and which specified theRTLD_GLOBAL
flag. To determine the scope of visibility for the symbols loaded with adlopen()
invocation, themode
parameter should be a bitwise-inclusiveOR
with one of the following values:RTLD_GLOBAL
The executable object file’s symbols are made available for relocation processing of any other executable object file. In addition, symbol lookup using
dlopen(NULL,mode)
and an associateddlsym()
allows executable object files loaded with this mode to be searched.RTLD_LOCAL
The executable object file’s symbols shall not be made available for relocation processing of any other executable object files.
If neither
RTLD_GLOBAL
norRTLD_LOCAL
is specified, the default behavior is unspecified.If
RTLD_GLOBAL
has been specified, the executable object file maintains it’sRTLD_GLOBAL
status regardless of any previous or future specification ofRTLD_LOCAL
, as long as the executable object file remains in the address space.Symbols introduced through calls to
dlopen()
may be used in relocation activities. Symbols that duplicate symbols already defined by the base image or previousdlopen()
calls are treated as an error and the object file is not loaded. Symbols introduced through loading dependent executable object files are ignored or not loaded depending on the method used to build the executable object files.The symbols introduced by
dlopen()
operations and available throughdlsym()
are at a minimum those which are exported as identifiers of global scope by the executable object file. Typically, such identifiers shall be those that were specified in (for example) C source code as havingextern
linkage.
int dlclose(void* handle);
Releases a reference to the executable object file referenced by
handle
. If the reference count drops to0
, the executable object file’s global symbol table is made unavailable. When all references to the global symbols the executable object file provided have been removed the object file is removed from the address space.If the executable object being removed has any termination routines in it they are called.
void* dlsym(void* handle, const char* symbol);
The
dlsym()
function obtains the address of a symbol (a function identifier or a data object identifier) defined in the symbol table identified by the handle argument. The handle argument is a symbol table handle returned from a call todlopen()
(and which has not since been released by a call todlclose()
), and name is the symbol’s name as a character string. The return value fromdlsym()
, cast to a pointer to the type of the named symbol, can be used to call (in the case of a function) or access the contents of (in the case of a data object) the named symbol.The
dlsym()
function searches for the named symbol in the symbol table referenced by handle and returns the address of the code or data location specified by the null-terminated character string symbol. Which libraries and objects are searched depends on thehandle
parameter.Upon successful completion, if name names a function identifier,
dlsym()
returns the address of the function converted from type pointer to function to type pointer tovoid
; otherwise,dlsym()
shall return the address of the data object associated with the data object identifier named by name converted from a pointer to the type of the data object to a pointer tovoid
. Ifhandle
does not refer to a valid symbol table handle or if the symbol named by name cannot be found in the symbol table associated withhandle
,dlsym()
shall return a null pointer.
int dlinfo(void* handle, int request, void* args);
The
dlinfo()
function provides information about dynamically loaded object. The action taken bydlinfo()
and exact meaning and type of the argumentargs
depend on value of therequest
argument provided by the caller.
RTLD_DI_UNRESOLVED
Return
1
in an indexer value pointed to byargs
if the symbol table handle has unresolved relocation records to symbols. If thehandle
is the global symbol table handle orRTLD_SELF
return1
if any unresolved relocation records to symbols are present in any loaded executable object files…
const char *dlerror(void);
The
dlerror()
function returns a null-terminated character string (with no trailing<newline>
) that describes the last error that occurred during dynamic linking processing. If no dynamic linking errors have occurred since the last invocation ofdlerror()
,dlerror()
returnsNULL
. Thus, invokingdlerror()
a second time, immediately following a prior invocation, results inNULL
being returned.
This example opens an object file, checks for any unresolved symbols the object file may have, locates a global symbol in the object file, calls it then closes the object file:
#include <stdbool.h>
#include <stdio.h>
#include <dlfcn.h>
typedef int (*call_sig)(void);
bool load_object (void)
{
void* handle;
call_sig call;
int unresolved;
handle = dlopen ("/code.o", RTLD_NOW | RTLD_GLOBAL);
if (handle == NULL)
{
printf ("dlopen failed: %s\n", dlerror ());
return false;
}
if (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) < 0)
{
printf ("dlinfo failed: %s\n", dlerror ());
dlclose (handle);
return false;
}
if (unresolved != 0)
{
printf ("object.o has unresolved external symbols\n");
dlclose (handle);
return false;
}
call = dlsym (handle, "foo");
if (call == NULL)
{
printf("dlsym failed: symbol 'foo' not found\n");
dlclose (handle);
return false;
}
printf ("'foo()' returns: %i\n", call ());
if (dlclose (handle) <