我们从现在开始会逐步连载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核心,更合适的量产版本)。
树莓派4b包括了4核的arm cortex-a72,1.5ghz的bcm2711芯片,可以执行arm aarch64位指令,也可以执行arm aarch32位指令,具备标准化的通用控制器gic。和树莓派3b+的硬件规格对比情况:
编写应用程序
要在树莓派上运行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 《rtthread.h》
2
3void thread_entry(void* parameter)
4{
5 rt_kprintf(“hello world
”);
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 《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的编写可以按照这样的方式编写:
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可执行文件。
采用cmake构建的应用程序
针对cmake的版本,我们以pthreads的方式来编写这个pthread多线程版本的hello world:在一个posix thread线程中输出”hello world”。
posix thread版本的main.c代码清单
1#include 《stdio.h》
2#include 《pthread.h》
3
4void *pthread_entry(void* parameter)
5{
6 printf(“hello world
”);
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
”, 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的多线程上执行。
原文标题:当“树莓派”遇上rt-thread smart——应用编程入门
文章出处:【微信公众号:rtthread物联网操作系统】欢迎添加关注!文章转载请注明出处。
5G在智慧家庭中能不能产生裂变的效果
三星S7拍照实测 是否能秒iPhone6S
2017中国·新材料资本技术春季峰会隆重举行-1000余名产业精英聚首
上海加速双千兆宽带城市 3年内实现千兆用户达到百万级
边缘计算是什么
树莓派上rt-smart的应用编程入门
家禽肠道疾病治疗
电流互感器二次为什么不能开路
Percepto Robotics宣布Sparrow无人机机器视觉算法
让文献检索进入AI模式
信步科技SV1a-H2716P嵌入式主板介绍
卡塔尔航空日本航空和南方航空已成功入围马来西亚航空股份
数据中心将迎来新一轮发展,将走向技术创新的制高点
“国补”引出行业新星植保无人机
三星“迅速跟进”苹果的AirPower充电垫,上演再次“借鉴”
35W双C口PD快充适配器方案
工业机器人谨防扎堆低端化 高端产业应避免陷入低端化泥潭
了解 AV 复杂性
关于NLP任务的所有GNN相关技术介绍
SiC相对于传统Si的优势如何