Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
rt-smart
当“树莓派”遇上RT-Thread Smart——应用编程入门
发布于 2021-05-12 17:26:09 浏览:2055
订阅该版
[tocm] 我们从现在开始会逐步连载RT-Thread Smart(简称rt-smart,甚至有时会称为smart os)的介绍文章,旨在让大家认识,接触到smart os的方方面面。 这个是本系列的第一篇文章,一些介绍及树莓派上rt-smart的应用编程入门(更多的从应用程序角度入手)。后续还包括在rt-smart上的不同应用程序介绍: - wget & curl移植 - busybox移植 - sdl图形类应用 - dropbear及ssh server应用 ###为什么选择树莓派 树莓派是第一个smart对外提供公开支持的硬件平台?选择树莓派有诸多方面的原因:第一,它可以算是普及度最广的一款ARM Cortex-A硬件开发板,被广泛地应用在一些创新应用,高校教育等方面。第二,自树莓派4B发布以来,芯片核心部分也越来越标准化(相比较之前的树莓派2、3等,携带了标准的GIC中断控制器,有线以太网网口(vs 树莓派3的USB转有线以太网)),从这个再把rt-smart移植扩展到其他A系列处理器也会是很好的参考,例如后续ART-Pi版本ART-Pi smart开发板(ARM Cortex-A7核心,更合适的量产版本)。 ![image.png](https://oss-club.rt-thread.org/uploads/20210512/7303d354a5c5b9385f3e14294c687731.png) 树莓派4B包括了4核的ARM Cortex-A72,1.5GHz的BCM2711芯片,可以执行ARM AArch64位指令,也可以执行ARM AArch32位指令,具备标准化的通用控制器GIC。和树莓派3B+的硬件规格对比情况: ![2.png](https://oss-club.rt-thread.org/uploads/20210512/054e649c0a115eef716dc9f72550c699.png) ###编写应用程序 要在树莓派上运行smart也很简单,直接下载smart的发布版,里面有树莓派4B上对应的移植代码,及一些用户态应用程序。 在smart上写程序,可以有以下几种方式:传统的RT-Thread scons构建方式;类Linux的方式,这里给出了基于Makefile的方式,及基于CMake的方式。下面通过一个 ❀ 花式的Hello World程序来进行介绍。 ###采用scons构建的应用程序 因为RT-Thread原生是采用scons来进行构建的,所以这里也用scons来构建一个应用程序,它会调用RT-Thread的一些API来创建一个线程,并输出"hello world!"。 **examples/scons/main.c文件清单** ``` 1#include
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} ``` 对应的编译脚本,包含两个,一份是SConscript脚本,另外一份是SContruct脚本 **SConstruct文件清单:** ``` 1import os 2import sys 3 4# UROOT_DIR指向rt-smart sdk中的userapps文件夹 5UROOT_DIR = os.path.join('..', '..') 6 7# 把building.py的目录添加到系统搜索路径中 8sys.path = sys.path + [os.path.join(UROOT_DIR, '..', 'tools')] 9from building import * 10 11# 编译一个应用程序 12BuildApplication('scons', 'SConscript', usr_root = UROOT_DIR) ``` SConscript文件清单,和原本的RT-Thread 组件SConscript文件类似: ``` 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') ``` 按照RT-Thread传统的构建方式,直接执行scons,会生成相应的scons.elf可执行文件。 ``` 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. ``` **采用Makefile构建的应用程序** 除了scons构建方式以外,我们也可以使用Makefile方式,以一个C++版本的方式来给出这份例子。 main.cpp文件清单: ``` 1#include
2#include
3 4extern "C" { 5 6int main(int argc, char** argv) 7{ 8 int index = 0; 9 std::vector
a; 10 for (index = 0; index < 5; index ++) 11 { 12 a.push_back(index); 13 } 14 15 for (std::vector
::iterator it=a.begin(); it != a.end(); it++) 16 std::cout << "hello world, index = " << *it << std::endl; 17 return 0; 18} 19 20} ``` 而Makefile的编写可以按照这样的方式编写: ``` 1# 设置交叉工具链 2CROSS_COMPILE= arm-linux-musleabi- 3CC= $(CROSS_COMPILE)gcc 4CXX= $(CROSS_COMPILE)g++ 5 6# 获得当前目录 7PWD := $(shell pwd) 8 9# UROOT_DIR指向rt-smart sdk中的userapps文件夹 10UROOT_DIR := $(PWD)/../.. 11RT_DIR=$(UROOT_DIR)/sdk/rt-thread 12INC_DIR=$(UROOT_DIR)/sdk/include 13LIB_DIR=${UROOT_DIR}/sdk/lib 14 15# 编译及链接时参数 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 ``` 在目录下执行make即可生成makefile.elf可执行文件。 ![3.png](https://oss-club.rt-thread.org/uploads/20210512/9fd55d085d4634361706cf9f2cbb785c.png) ###采用CMake构建的应用程序 针对CMake的版本,我们以pthreads的方式来编写这个pthread多线程版本的hello world:在一个POSIX thread线程中输出”hello world”。 POSIX thread版本的main.c代码清单 ``` 1#include
2#include
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 /* 创建pthread线程来执行后续的hello输出 */ 17 ret = pthread_create(&pth, NULL, pthread_entry, NULL); 18 printf("ret = %d\n", ret); 19 20 /* 等待结束 */ 21 pthread_join(pth, &value); 22 23 return 0; 24} ``` 对应的CMakeLists.txt文件清单 ``` 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指向rt-smart sdk中的userapps文件夹 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# 设置链接脚本位置 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}) ``` 可以在这个目录下创建一个build文件夹,然后通过cmake ``` 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 ``` 来生成Makefile文件,然后通过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 ``` ###运行应用程序 在使用的时候,需要把上面编译好的三个应用程序放置到树莓派用的SD卡上。我们可以使用读卡器在PC上把应用程序复制到SD卡上。然后再插回到树莓派板子上,重新上电。这个时候我们可以在串口上看到RT-Thread Smart的启动界面: ``` 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! ``` **执行程序,可以输出hello world!** 通过上面三个例子,我们看到了在smart上目前支持的数种技术: 1、在用户态以RT-Thread传统API方式运行:RT-Thread的多线程,基于优先级全抢占的调度都可以被使用,具备平滑的延续性; 2、可以支持C++编写应用程序,同时也可以使用stdc++库; 3、可以支持pthreads,以POSIX thread线程的模式执行,它们会被映射到RT-Thread的多线程上执行。 上面的一些代码都放在了gitee的rt-smart notes仓库中: https://gitee.com/rtthread/rt-smart-notes/tree/master/examples **下集预告:** 下集我们将通过经典的Linux方式的configure & make模式来移植wget & cURL程序到rt-smart上,从而可以看到rt-smart对POSIX的兼容能力,敬请期待。
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
RT-Thread小师弟
微信:rtthread2020
文章
291
回答
171
被采纳
33
关注TA
发私信
相关文章
1
rt-smart发布时间
2
rt-smart qemu-vexpress-a9 编译报错
3
rt-smart分支编译rasp4-32bsp报错
4
rt-smart qemu-vexpress-a9 win10编译脚本问题
5
rt-smart qemu-vexpress-a9 linux 下crtl+c
6
rt-smart + pthread 编译报错
7
rt-smart的rt_channel实现问题
8
关于rt-smart的musl-libc
9
RT-Smart Windows 编译 qemu-vexpress-a9 出错
10
用户程序在RT-Smart存在的方式
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部