Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
原创征文
RPC远程调用
rt-thread 移植 eRPC 系列(三) 之 Porting
发布于 2022-08-24 11:29:27 浏览:1361
订阅该版
[tocm] ## 前言 经过前边几篇文章,我们已经熟知了 eRPC ,也熟知怎么使用 eRPC ,也熟练掌握了扩展新的平台环境。但是,这远远不够。 目前,eRPC 已经在多种系统上实现。包括无系统裸机、FreeRTOS、ZEPHYR、Mbed OS、THREADX、Linux、Win。**但是,缺少 rt-thread !** 今天笔者就正式讲解怎么添加 rt-thread 系统接口。 不了解 eRPC 的请移步文章结尾的链接,先熟悉一下 eRPC。 ### 下载源码 打开 eRPC 仓库 [EmbeddedRPC/erpc](https://oss-club.rt-thread.org/uploads/20220824/da39a3ee5e6b4b0d3255bfef95601890afd80709.png) ![](https://oss-club.rt-thread.org/uploads/20220824/13c9db74ce7e0b3c7bbe955530ce83df8836a66f.png) ### config 第一步、添加多线程模型选项。打开 "erpc_c/config/erpc_config.h" 。添加定义 `#define ERPC_THREADS_RTTHREAD (7U) //!< RTTHREAD` ### 多线程 porting 进入 "erpc_c/port" 目录下,打开并编辑 "erpc_c/port/erpc_threading.h"。 这个文件定义了三个类 `Thread` `Mutex` `Semaphore` 。分别定义了 erpc 使用的线程类、锁以及信号量。 ##### 添加头文件包含 ``` #elif ERPC_THREADS_IS(RTTHREAD) #include "rtthread.h" #include "rthw.h" ``` ##### 实现 `getThreadId` ``` #elif ERPC_THREADS_IS(RTTHREAD) return reinterpret_cast
(m_thread); ``` ##### 实现 `getCurrentThreadId` ``` #elif ERPC_THREADS_IS(RTTHREAD) return reinterpret_cast
(rt_thread_self()); ``` ##### 定义成员变量 ``` #elif ERPC_THREADS_IS(RTTHREAD) rt_thread_t m_thread; /*!< Underlying Thread instance */ Thread *m_next; /*!< Pointer to next Thread. */ static Thread *s_first; /*!< Pointer to first Thread. */ ``` ##### 添加线程入口成员函数 ``` #elif ERPC_THREADS_IS(RTTHREAD) /*! * @brief This function execute threadEntryPoint function. * * @param[in] arg Thread to execute. */ static void threadEntryPointStub(void *arg); ``` ##### 修改 Mutex Semaphore 成员类型 ``` #elif ERPC_THREADS_IS(RTTHREAD) rt_mutex_t m_mutex; ``` ``` #elif ERPC_THREADS_IS(RTTHREAD) rt_sem_t m_sem; /*!< Semaphore. */ ``` ### 添加 erpc_port_rtthread.cpp 文件 主要文件内容如下: ``` #include "erpc_port.h" #include
extern "C" { #include "rtthread.h" }; using namespace std; void *operator new(std::size_t count, const std::nothrow_t &tag) THROW { (void)tag; void *p = erpc_malloc(count); return p; } void *operator new[](std::size_t count, const std::nothrow_t &tag) THROW { (void)tag; void *p = erpc_malloc(count); return p; } void *erpc_malloc(size_t size) { void *p = rt_malloc(size); return p; } void erpc_free(void *ptr) { rt_free(ptr); } /* Provide function for pure virtual call to avoid huge demangling code being linked in ARM GCC */ #if ((defined(__GNUC__)) && (defined(__arm__))) extern "C" RT_WEAK void __cxa_pure_virtual(void) { for (;;) { }; } #endif ``` > 注:有两种 new delete 重装被笔者删掉了。因为它们和 "cxx_crt.cpp" 中的定义重复了。添加 `RT_WEAK` 声明也可以,但是这个文件本来就是可修改的,直接删掉就好了。 ### 添加 erpc_threading_rtthread.cpp 此文件是 "erpc_c/port/erpc_threading.h" 头文件中三个类 `Thread` `Mutex` `Semaphore` 的定义实现。把所有的类成员函数实现一遍。主要有 ``` void Thread::start(void *arg) Thread *Thread::getCurrentThread(void) void Thread::sleep(uint32_t usecs) void Thread::threadEntryPointStub(void *arg) bool Mutex::lock(void) bool Mutex::unlock(void) void Semaphore::put(void) bool Semaphore::get(uint32_t timeoutUsecs) ``` 等等。代码太长了就不全贴出来了。 ### 配置 erpc 再次打开 "erpc_c/config/erpc_config.h",首先打开 `ERPC_THREADS` 宏定义 `#define ERPC_THREADS (ERPC_THREADS_RTTHREAD)`。 然后,禁用嵌套调用和嵌套调用检测。笔者不想用这个特性,禁用掉。 其它的配置项可以自由发挥了。 ### 添加 SConscript 文件 新建 "erpc_c/SConscript" 文件,并编辑如下内容 ``` import os from building import * cwd = GetCurrentDir() src = Glob('infra/erpc_basic_codec.cpp') src += Glob('infra/erpc_client_manager.cpp') src += Glob('infra/erpc_crc16.cpp') src += Glob('infra/erpc_framed_transport.cpp') src += Glob('infra/erpc_message_buffer.cpp') src += Glob('infra/erpc_message_loggers.cpp') src += Glob('infra/erpc_pre_post_action.cpp') src += Glob('infra/erpc_server.cpp') src += Glob('infra/erpc_simple_server.cpp') src += Glob('port/erpc_port_rtthread.cpp') src += Glob('port/erpc_serial.cpp') src += Glob('port/erpc_threading_rtthread.cpp') src += Glob('setup/erpc_client_setup.cpp') src += Glob('setup/erpc_setup_mbf_dynamic.cpp') src += Glob('setup/erpc_setup_mbf_static.cpp') src += Glob('setup/erpc_server_setup.cpp') src += Glob('setup/erpc_setup_serial.cpp') src += Glob('setup/erpc_setup_tcp.cpp') src += Glob('transports/erpc_inter_thread_buffer_transport.cpp') src += Glob('transports/erpc_serial_transport.cpp') src += Glob('transports/erpc_tcp_transport.cpp') CPPPATH = [cwd + '/config'] CPPPATH += [cwd + '/infra'] CPPPATH += [cwd + '/port'] CPPPATH += [cwd + '/setup'] CPPPATH += [cwd + '/transports'] LOCAL_CCFLAGS = ' -std=c++11' group = DefineGroup('erpc', src, depend = [''], CPPPATH = CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS) Return('group') ``` ### 添加到项目 把 erpc_c 文件夹拷贝到项目根目录下,比如某 RT-Studio 项目根目录下,同步 scons 配置至项目。 ![sync-scons.png](https://oss-club.rt-thread.org/uploads/20240102/5e804e11cc881d4eac5103c15d3b1ef9.png) ![project-erpc.png](https://oss-club.rt-thread.org/uploads/20240102/f8c7467a97335d362e30db8a689a5142.png) ### 跑一下之前的 demo 首先看一下测试板上的 ip 地址是多少,然后修改 PC 端的 client 程序,把其中的 ip 地址改成测试板 ip 。重新编译 client 程序,运行 client 程序。 ``` erpc_transport_t transport = erpc_transport_tcp_init("192.168.2.56", 5555, false); ``` 下图,左边是新唐 NUC972 开发板运行的终端,右边是 PC 端的 CYGWIN 终端环境。我们实现了从 PC 端到 rt-thread 系统端的 rpc 远程调用过程! ![](https://oss-club.rt-thread.org/uploads/20220824/2e7f678321ca36c574de0af8c300eb4bdc8e379f.png) ![](https://oss-club.rt-thread.org/uploads/20220824/0d5078e51a046dd4063ddf638d9b142a6cd9fcd2.gif) ## 结束语 这么简单就实现了?当然不是,移植过程远远不够。本篇只完成了 port 下的接口。 还缺一个 Transport ,我们下篇见。 ***相关文章*** [rt-thread 移植 eRPC 系列(一) 之 简介](https://club.rt-thread.org/ask/article/3acf471c19f2595f.html) [rt-thread 移植 eRPC 系列(二) 之 演示](https://club.rt-thread.org/ask/article/7b9ed79f35c8e568.html)
3
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
出出啊
恃人不如自恃,人之为己者不如己之自为也
文章
43
回答
1517
被采纳
342
关注TA
发私信
相关文章
1
请问RT-Thread有RPC方案吗?
2
rt-thread 支持eRPC吗
推荐文章
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
UART
WIZnet_W5500
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
次被采纳
张世争
807
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部