1. 多线程介绍
进程线程概念是操作系统与普通单片机最大的区别,多任务系统可以将系统资源分块,使得不同任务相互独立运行,且在宏观层面观察,多个应用像同一时间运行一样,例如浏览网页的同时,也可以播放音乐,这就是引入进程线程的关键点。
2. 快速上手
如果您初次阅读此文档,请阅读:《入门指南/源码管理及编程介绍/源码工程管理》,按需管理自己工程源码(注:此文档必看,并建议采用【远程挂载管理】方式,否则有代码丢失风险!!!)。
2.1 源码工程下载
先在PC虚拟机定位到nfs服务目录,再在目录中创建存放源码仓库的管理目录:
cd ~/nfsroot mkdir GitHub cd GitHub
再通过git工具,在管理目录内克隆远程仓库(需要设备能对外网进行访问)
git clone https://github.com/EASY-EAI/EASY-EAI-Toolkit-3576.git

注:
* 此处可能会因网络原因造成卡顿,请耐心等待。
* 如果实在要在gitHub网页上下载,也要把整个仓库下载下来,不能单独下载本实例对应的目录。
2.2 开发环境搭建
通过adb shell进入板卡开发环境,如下图所示。
通过以下命令,把nfs目录挂载上nfs服务器。
mount -t nfs -o nolock < nfs server ip >:< nfs path in server > /home/orin-nano/Desktop/nfs/

2.3 例程编译
然后定位到nfs的挂载目录,再在目录中创建存放源码仓库的管理目录:
cd /home/orin-nano/Desktop/nfs/GitHub
进入到对应的例程目录执行编译操作,具体命令如下所示:
cd EASY-EAI-Toolkit-3576/Demos/common-system_opt/ ./build.sh

2.4 例程运行及效果
执行下方命令,运行示例程序:
./Release/test-thread-opt
执行效果如下所示。
API的详细说明,以及API的调用(本例程源码),详细信息见下方说明。
3. 时间操作API说明
3.1 引用方式
EASY EAI api库位于本仓库的easyeai-api目录中。为方便客户在本地工程中直接调用我们的EASY EAI api库,此处列出工程中需要链接的库以及头文件等,方便用户直接添加。
描述 | CMake写法 | Makefile写法 |
api.cmake | ${common_root}/system_opt/api.cmake | 无 |
头文件目录 | ${SYSTEM_OPT_INCLUDE_DIRS} | -I ../../easyeai-api/common/system_opt |
源文件目录 | ${SYSTEM_OPT_SOURCE_DIRS} | ../../easyeai-api/common/system_opt |
库文件目录 | 无 | 无 |
库链接参数 | ${SYSTEM_OPT_LIBS} | 无 |
API源代码路径为EASY-EAI-Toolkit-3576/easyeai-api/common/system_opt/。用户可通过源代码了解接口实现,甚至可对源码进行修改。
3.2 线程任务原型
线程任务原型如下所示,线程任务是程序执行的最小单体,定义如下所示。
typedef void *(*ThreadEntryPtrType)(void *);
3.3 创建线程函数
创建线程函数原型如下所示。
int32_t CreateNormalThread(ThreadEntryPtrType entry, void *para, pthread_t *pid);
原型如下所示。
函数名:CreateNormalThread() | |
头文件 | easyeai-api/common/system_opt/system_opt.h |
输入参数 | entry:线程体执行函数 |
para:传入线程提的参数,用作共享变量 | |
pid:传入新建的pthread_t类型对象 | |
返回值 | 创建失败返回-1 |
创建成功返回0 | |
注意事项 | pid变量用于存放线程系统分配的线程号,如果填NULL会导致程序退出 |
3.4 执行shell命令 - 调用system()
执行shell命令函数原型如下所示。
int32_t exec_cmd_by_system(const char *cmd);
本函数通过调用system()实现,原型如下所示。
函数名:exec_cmd_by_system() | |
头文件 | easyeai-api/common/system_opt/system_opt.h |
输入参数 | *cmd:shell命令 |
返回值 | 对于fork失败,system()函数返回-1。如果exec执行成功,也即command顺利执行完毕,则返回command通过exit或return返回的值。 |
注意事项 |
建议监控一下system()函数的执行完毕后的errno值,争取出错时给出更多有用信息; system()非阻塞方式注意点:’&’转后台,同时将输出重定向。否则变为阻塞方式; |
3.5 执行shell命令 - 调用popen()
执行shell命令函数原型如下所示。
int32_t exec_cmd_by_popen(const char *cmd, char *result);
本函数通过调用popen()实现,可获取执行结果,原型如下所示。
函数名:exec_cmd_by_popen() | |
头文件 | easyeai-api/common/system_opt/system_opt.h |
输入参数 | *cmd:shell命令 |
*result:执行shell命令语句后,返回的结果将存进该段内存中 | |
返回值 | 调用失败返回-1 |
调用成功返回0(result被正确写入) | |
注意事项 |
如果 cmd 执行失败,子进程会把错误信息打印到标准错误输出,父进程就无法获取。 若需要捕获错误信息,可以重定向子进程的错误输出,让错误输出重定向到标准输出(2>&1),这样父进程就可以捕获子进程的错误信息了。 如:exec_cmd_by_popen("ls 2>&1", result); |
4. 线程操作API使用案例
线程操作API使用案例代码路径为:
EASY-EAI-Toolkit-3576/Demos/common-system_opt/test-thread-opt.c,线程创建案例由两部分组成,线程执行主体和创建线程操作。
线程执行主体如下所示。
void *testThreadBody(void *arg) { int *share_para = (int *)arg; while(1) { printf("[tesThread] --- share_para = %dn", *share_para); if(*share_para > 10){ printf("[tesThread] --- exitn"); break; } sleep(1); } pthread_exit(NULL); }
创建线程操作如下所示,pId变量用于存放进程ID,share_para变量是保存输入参数。
pthread_t pId; int share_para = 0; if(0 == CreateNormalThread(testThreadBody, &share_para, &pId)){ while(1){ printf("[mainThread] --- n"); share_para++; sleep(1); } } 审核编辑 黄宇
-
单片机
+关注
关注
6067文章
44992浏览量
650502 -
操作系统
+关注
关注
37文章
7152浏览量
125592 -
源码
+关注
关注
8文章
671浏览量
30334 -
rk3576
+关注
关注
1文章
175浏览量
728
发布评论请先 登录
【米尔RK3576开发板评测】+项目名称【米尔RK3576开发板评测】一个视频和你共同认识一下米尔RK3576开发板
米尔RK3576和RK3588怎么选?-看这篇就够了
【米尔RK3576开发板评测】+项目名称值得购买的米尔RK3576开发板
探索 RK3576 方案:卓越性能与灵活框架,诚邀开发定制合作!
适配多种系统,米尔瑞芯微RK3576核心板解锁多样化应用
RK3576 vs RK3588:为何越来越多的开发者转向RK3576?
Mpp支持RK3576么
RK这2款旗舰芯片RK3588 PK RK3576,谁是最优选
新品体验 | RK3576开发板

米尔RK3576开发板特惠活动!

RK3576单板发布倒计时:RK3399与RK3576对比

RK3588与RK3576区别解析

评论