Hello World
This example demonstrates the simplest possible application written for CMRX RTOS. By the end of this tutorial, you’ll understand how to create a basic application and integrate it with the CMRX kernel.
What You’ll Learn
- How to create a basic CMRX application
- Understanding processes and threads in CMRX
- How to build and integrate applications with the kernel
- Basic project structure and configuration
Understanding CMRX Applications
In CMRX, all user code is organized into applications (also called processes - these terms mean the same thing). Think of an application as a container that holds:
- Your code (functions)
- Data (variables)
- Threads (execution contexts)
The key advantage is memory isolation: each application gets its own protected memory space that other applications cannot access. This makes your system more robust against bugs and security issues.
Basic Application Code
Here’s the simplest possible CMRX application:
#include <cmrx/application.h>
int app_main(void * data)
{
while (1) {
// Your application code goes here
// This infinite loop keeps the thread running
}
}
OS_APPLICATION_MMIO_RANGE(app, 0, 0)
OS_APPLICATION(app)
OS_THREAD_CREATE(app, app_main, NULL, 64)
What Each Line Does
#include <cmrx/application.h>- Includes the CMRX application frameworkint app_main(void * data)- Your main application function (likemain()in regular C programs)while (1) { }- An infinite loop that keeps the thread aliveOS_APPLICATION_MMIO_RANGE(app, 0, 0)- Defines memory-mapped I/O ranges (none in this example)OS_APPLICATION(app)- Declares an application named “app”OS_THREAD_CREATE(app, app_main, NULL, 64)- Creates a thread that runsapp_main()with the scheduler priority of 64
Building the Application
To build this code, you need to create a CMake configuration. Create a CMakeLists.txt file:
add_application(app app.c)
target_link_libraries(app stdlib)
Important: The name “app” in add_application() must match the name used in OS_APPLICATION(app).
How Memory Isolation Works
CMRX automatically creates isolated memory regions for each application. The rule is simple:
All data in the same static library as the
OS_APPLICATION()macro belongs to that application.
This means you don’t need to manually configure memory partitions - CMRX handles it automatically based on your code organization.
Complete Project Setup
To create a working project, you need three parts:
- Hardware Configuration - Tell CMRX what microcontroller you’re using
- Kernel Integration - Include and configure the CMRX kernel
- Main Entry Point - Create the system startup code
Step 1: Hardware Configuration
For ARM-based microcontrollers, configure CMSIS support:
set(CMSIS_ROOT path/to/cmsis/inside/sdk)
set(DEVICE your_device_name)
set(CMSIS_LINKER_FILE path/to/linker/file)
include(FindCMSIS)
What These Variables Do:
CMSIS_ROOT- Path to CMSIS headers in your SDKDEVICE- Your microcontroller’s part name (check your SDK documentation)CMSIS_LINKER_FILE- Path to the linker script for your device
Step 2: Kernel Integration
Add CMRX to your build:
set(CMRX_ARCH arm)
set(CMRX_HAL cmsis)
include(CMRX)
add_subdirectory(path/to/cmrx)
add_firmware(hello_world main.c)
target_link_libraries(hello_world vendor_sdk)
target_app_applications(hello_world app)
What This Does:
- Configures CMRX for ARM architecture with CMSIS HAL
- Creates a firmware image called “hello_world”
- Links your application to the firmware
Step 3: Main Entry Point
Create a main.c file for system initialization:
#include <RTE_headers.h>
#include CMSIS_device_header
long timing_get_current_cpu_freq(void)
{
return SystemCoreClock;
}
int main(void)
{
// Perform hardware initialization here
// (configure clocks, peripherals, etc.)
timing_provider_setup(1);
os_start(); // Start the CMRX kernel
}
Why This File Exists:
- Hardware setup is easier to do before the kernel starts
- The code runs with full privileges to configure peripherals
- Once
os_start()is called, CMRX takes over and starts your applications
What Happens When You Run This
- Your microcontroller boots and runs
main() - Hardware initialization code executes
os_start()launches the CMRX kernel- The kernel creates your “app” application in isolated memory
- The kernel starts the thread running
app_main() - Your application runs in its infinite loop
Next Steps
This basic example doesn’t do anything visible, but it demonstrates the foundation of CMRX development. To make it useful, you could:
- Add actual code inside the
while(1)loop - Use CMRX APIs to interact with hardware
- Create multiple applications for different tasks
- Add inter-process communication between applications
For more complex examples covering full hardware and SDK integration process, check the CMRX documentation which provides how-to guides for variety of hardware: