Now you can run Micro-Kernel Operating System on Raspberry Pi!

RT-Thread Smart Open Source Micro-Kernel Operating System was released last September by RT-Thread Open Source Team. RT-Thread Smart(Aka RT-Smart) is aimed primarily at mid-to-high-end processors with MMU(Memory Management Unit), providing a more competitive operating system-based software platform to benefit the industries in Security( such as IPC Camera), Gateway, Industrial Control, On-board Device, Consumer Electronics and so on.

We’re making the introduction of RT-Thread Smart into several articles intend to give a detailed explanation of RT-Thread Smart from a different perspective, so follow us to make sure you’re in the loop to be updated about new knowledge. Today, let’s get started with RT-Thread Smart Application Programming on Raspberry Pi.

Why Choose Raspberry Pi to Port?

Comparison with Raspberry PI 3 B:

Write an application

There are several ways to write a program on RT-Smart: the traditional RT-Thread scons build method, the Linux-like approach, this article will lead you with Makefile and CMake approach. Get you to a❀ Fancy Hello World program.

Built with scons

examples/scons/main.c File Checklist

1#include <rtthread.h>
2
3void thread_entry(void* parameter)
4{
5 rt_kprintf("hello world\n");
6}
7
8int main(int argc, char** argv)
9{
10 rt_thread_t tid;
11 tid = rt_thread_create("hello", thread_entry, RT_NULL,
12 1024, 20, 20);
13 if (tid)
14 {
15 rt_thread_startup(tid);
16 }
17 rt_thread_mdelay(100);
18
19 return 0;
20}

The corresponding compilation script consists of two, one is a Scanscript and the other is a SContruct.

SConstruct File Checklist:

1import os
2import sys
3
4# UROOT_DIR points to the userapps folder in rt-smart sdk
5UROOT_DIR = os.path.join('..', '..')
6
7# Add the directory of the building.py to the system search path
8sys.path = sys.path + [os.path.join(UROOT_DIR, '..', 'tools')]
9from building import *
10
11# Compile an application
12BuildApplication('scons', 'SConscript', usr_root = UROOT_DIR)

The SConscript file checklist, which is similar to the original RT-Thread component SConscript file:

1from building import *
2
3cwd = GetCurrentDir()
4src = Glob('*.c') + Glob('*.cpp')
5CPPPATH = [cwd]
6
7CPPDEFINES = ['HAVE_CCONFIG_H']
8group = DefineGroup('scons', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
9
10Return('group')

According to the RT-Thread traditional building method, the scons will be executed directly and generating the corresponding executable scons.elf file. **

1~/workspace/rtthread-smart/userapps/examples/scons$ scons 
2scons: Reading SConscript files ...
3scons: done reading SConscript files.
4scons: Building targets ...
5scons: building associated VariantDir targets: build/scons
6CC build/scons/main.o
7LINK scons.elf
8scons: done building targets.

Built with Makefile

main.cpp File Checklist:

1#include <vector>
2#include <iostream>
3
4extern "C" {
5
6int main(int argc, char** argv)
7{
8 int index = 0;
9 std::vector<int> a;
10 for (index = 0; index < 5; index ++)
11 {
12 a.push_back(index);
13 }
14
15 for (std::vector<int>::iterator it=a.begin(); it != a.end(); it++)
16 std::cout << "hello world, index = " << *it << std::endl;
17 return 0;
18}
19
20}

Makefile can be written in such a way:

1# Set up a cross tool chain
2CROSS_COMPILE= arm-linux-musleabi-
3CC= $(CROSS_COMPILE)gcc
4CXX= $(CROSS_COMPILE)g++
5
6# Get the current directory
7PWD := $(shell pwd)
8
9# UROOT_DIR points to the userapps folder in rt-smart sdk
10UROOT_DIR := $(PWD)/../..
11RT_DIR=$(UROOT_DIR)/sdk/rt-thread
12INC_DIR=$(UROOT_DIR)/sdk/include
13LIB_DIR=${UROOT_DIR}/sdk/lib
14
15# Compilation and link parameters
16CFLAGS= -march=armv7-a -marm -msoft-float -D__RTTHREAD__ -Wall -O0 -g -gdwarf-2 -n --static
17CFLAGS+= -I. -I$(RT_DIR)/include -I$(RT_DIR)/components/dfs -I$(RT_DIR)/components/drivers -I$(RT_DIR)/components/finsh -I$(RT_DIR)/components/net -I${INC_DIR}
18
19LDFLAGS= -march=armv7-a -marm -msoft-float -T ${UROOT_DIR}/linker_scripts/arm/cortex-a/link.lds
20LDFLAGS+= -L$(RT_DIR)/lib -L$(LIB_DIR) -Wl,--whole-archive -lrtthread -Wl,--no-whole-archive -n --static -Wl,--start-group -lrtthread -Wl,--end-group
21
22default:
23 $(CXX) $(CFLAGS) -c main.cpp -o main.o
24 $(CXX) $(LDFLAGS) main.o -o main.elf
25
26clean:
27 @rm *.o *.elf
28
29.PHONY: default clean

Generate an executable makefile.elf file by executing a make in the directory. **

Built with CMake

POSIX thread version of the main .c code list

1#include <stdio.h>
2#include <pthread.h>
3
4void *pthread_entry(void* parameter)
5{
6 printf("hello world\n");
7 return NULL;
8}
9
10int main(int argc, char** argv)
11{
12 int ret;
13 void *value;
14 pthread_t pth;
15
16 /* Create a pthread thread to execute hello output*/
17 ret = pthread_create(&pth, NULL, pthread_entry, NULL);
18 printf("ret = %d\n", ret);
19
20 /* Waitting to end */
21 pthread_join(pth, &value);
22
23 return 0;
24}

The corresponding CMakeLists .txt file checklist

1cmake_minimum_required(VERSION 3.5)
2
3project(cmake)
4
5## system configuration
6enable_language(C ASM)
7
8set(CMAKE_SYSTEM_NAME Generic)
9set(CMAKE_SYSTEM_PROCESSOR arm)
10
11if(NOT DEFINED ENV{RTT_EXEC_PATH})
12 message(FATAL_ERROR "not defined environment variable: RTT_EXEC_PATH")
13 message(FATAL_ERROR "Please execute the command: $ source smart_env.sh")
14endif()
15
16set(CONFIG_PREFIX "$ENV{RTT_EXEC_PATH}/arm-linux-musleabi-")
17# UROOT_DIR points to the userapps folder in rt-smart sdk
18set(UROOT_DIR "${PROJECT_SOURCE_DIR}/../..")
19
20set(CMAKE_C_COMPILER "${CONFIG_PREFIX}gcc")
21set(CMAKE_CXX_COMPILER "${CONFIG_PREFIX}g++")
22set(CMAKE_ASM_COMPILER "${CONFIG_PREFIX}gcc")
23set(CMAKE_OBJCOPY "${CONFIG_PREFIX}objcopy")
24set(CMAKE_C_AR "${CONFIG_PREFIX}ar")
25set(CMAKE_SIZE "${CONFIG_PREFIX}size")
26
27set(SDK_DIR "${UROOT_DIR}/sdk")
28set(LINK_SCRIPTS_DIR "${UROOT_DIR}/linker_scripts/arm/cortex-a")
29
30set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -marm -msoft-float -Werror -Wall -O0 -g -gdwarf-2 -n --static")
31set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=armv7-a -marm -msoft-float -x assembler-with-cpp -O0 -g")
32set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -marm -msoft-float -Werror -Wall -Woverloaded-virtual -fno-exceptions -fno-rtti -O0 -g -gdwarf-2 -n --static")
33
34set(SDK_INC
35 "${UROOT_DIR}/include"
36 "${UROOT_DIR}/rt-thread/include"
37 "${UROOT_DIR}/rt-thread/components/dfs"
38 "${UROOT_DIR}/rt-thread/components/drivers"
39 "${UROOT_DIR}/rt-thread/components/finsh"
40 "${UROOT_DIR}/rt-thread/components/net"
41)
42
43# Set the location of the link script
44set(CMAKE_EXE_LINKER_FLAGS "-T ${LINK_SCRIPTS_DIR}/link.lds -static")
45
46## user configuration
47set(APPS_INC
48 "${PROJECT_SOURCE_DIR}"
49 "${SDK_INC}"
50)
51
52set(APPS_SRC
53 "${PROJECT_SOURCE_DIR}/main.c"
54)
55
56set(CMAKE_EXECUTABLE_SUFFIX ".elf")
57
58add_executable(${PROJECT_NAME} ${SDK_SRC} ${APPS_SRC})
59target_include_directories(${PROJECT_NAME} PRIVATE ${APPS_INC})

Create a build folder in this directory

1~/workspace/rtthread-smart/userapps/examples/cmake/build$ cmake ..
2-- The C compiler identification is GNU 7.5.0
3-- The CXX compiler identification is GNU 7.5.0
4-- Check for working C compiler: /usr/bin/cc
5-- Check for working C compiler: /usr/bin/cc -- works
6-- Detecting C compiler ABI info
7-- Detecting C compiler ABI info - done
8-- Detecting C compile features
9-- Detecting C compile features - done
10-- Check for working CXX compiler: /usr/bin/c++
11-- Check for working CXX compiler: /usr/bin/c++ -- works
12-- Detecting CXX compiler ABI info
13-- Detecting CXX compiler ABI info - done
14-- Detecting CXX compile features
15-- Detecting CXX compile features - done
16-- The ASM compiler identification is GNU
17-- Found assembler: /usr/bin/cc
18-- Configuring done
19-- Generating done
20-- Build files have been written to: ~/workspace/rtthread-smart/userapps/examples/cmake/build

Generate the Makefile file and compile it via make.

1~/workspace/rtthread-smart/userapps/examples/cmake/build$ make
2[ 50%] Building C object CMakeFiles/cmake.dir/main.c.o
3[100%] Linking C executable cmake.elf
4[100%] Built target cmake

Run the Application

1 \ | /
2- RT - Thread Smart Operating System
3 / | \ 5.0.0 build May 4 2021
4 2006 - 2020 Copyright by rt-thread team
5lwIP-2.1.2 initialized!
6[I/sal.skt] Socket Abstraction Layer initialize success.
7file system initialization done!
8msh /> cd bin
9msh /bin> scons.elf
10msh /bin> hello world!

The program is executed and can output hello world!

From the above three examples, we can find out some new trending in RT-Smart:

  1. In the user-space is running the RT-Thread traditional API: RT-Thread multi-thread, all the schedule that based with Priority Preemption can be used;
  2. Support the C++ to write the application, as well as stdc++ library;
  3. Support the pthreads in the form of POSIX thread mode to execute, which will be mapped and executed in RT-Thread multithread.

Get Example Codes

https://gitee.com/rtthread/rt-smart-notes/tree/master/examples

Get RT-Smart Source Code

https://github.com/RT-Thread/rt-thread/tree/rt-smart

What’s Next?

  • busybox Porting
  • sdl Graphic Application
  • dropbear & ssh server Application

Any questions while using RT-Smart, feel free to share on RT-Thread Club!

An Open-Source Community-Powered Real-Time Operating System (RTOS) Project! We develop, we DIY, we create, we share, we explore this new IoT World together!