13.2.3 LVGL前台程序功能
提供界面操作:
①增加、设置、删除“点”。
②读、写“点”。
③配置MQTT信息。
④升级传感器。
这些操作,都是通过RPC接口跟后台程序(控制中心)进行交互,它不直接操作硬件。
13.2.4 mqtt_client_app功能
它的功能为:
①通过RPC接口更后台程序(控制中心)进行交互:获得MQTT信息、获得点的信息、读写点。
②跟MQTT Broker通信:发布消息、订阅消息。
③发布消息时:通过RPC接口读取传感器信息。
④订阅消息时:得到消息后,通过RPC接口设置传感器。
13.2.5 modbus_tcp_server功能
模拟一个Modbus TCP传感器,处理后台程序(控制中心)发来的读写请求。
13.3 JSON-RPC示例与情景分析
理解了JSON-RPC的使用,再阅读本项目会容易很多。
使用C语言实现的JSON-RPC代码位于GIT仓库,它依赖于libev库。(您可复制下方链接至浏览器,或扫描二维码查看)
https://github.com/hmng/jsonrpc-c
本节程序在如下目录:
13.3.1 服务器程序启动
服务器程序、客户端程序的源码都在如下文件里:
参考《13.3.5 上机实验》,启动服务器程序后,它的核心代码如下:
152 int RPC_Server_Init(void)
153 {
154 int err;
155
156 err = jrpc_server_init(&my_server, PORT);
157 if (err)
158 {
159 printf("jrpc_server_init err : %d\n", err);
160 }
161
162 jrpc_register_procedure(&my_server, say_hello, "sayHello", NULL );
163 jrpc_register_procedure(&my_server, add, "add", NULL );
164
165 jrpc_server_run(&my_server);
166 jrpc_server_destroy(&my_server);
167
168 return 0;
169 }
第156行,初始化服务器,使用端口“PORT”,它被定义为1234(可以修改)。
第162~163行,注册2个函数:前台程序使用传来参数“sayHello”时会导致say_hello程序被调用;前台程序使用传来参数“add”时会导致add程序被调用。
第165行:循环等待前台程序发来请求,收到请求后处理请求。
13.3.2 客户端程序发出请求
参考《13.3.5 上机实验》,假设执行了如下命令:
$ ./rpc add 3 4
它执行的代码如下:
193 int sum;
194 int fd = RPC_Client_Init();
195
196 if (fd < 0)
197 {
198 printf("RPC_Client_Init err : %d\n", fd);
199 return -1;
200 }
201
202 if (argc == 4 && !strcmp(argv[1], "add"))
203 {
204 int a = (int)strtoul(argv[2], NULL, 0);
205 int b = (int)strtoul(argv[3], NULL, 0);
206 int err = rpc_add(fd, a, b, &sum);
第194行,初始话客户端,就是连接服务器。
第206行:调用rpc_add函数。
rpc_add函数代码如下:
16 int rpc_add(int iSocketClient, int a, int b, int *sum)
17 {
18 char buf[100];
19 int iLen;
20 sprintf(buf, "{\"method\": \"add\", \"params\": [%d,%d], \"id\": \"2\" }", a,
b);
21 iLen = send(iSocketClient, buf, strlen(buf), 0);
22 if (iLen == strlen(buf))
23 {
24 while (1)
25 {
26 iLen = read(iSocketClient, buf, sizeof(buf));
27 buf[iLen] = 0;
28 if (iLen == 1 && (buf[0] == '\r' || buf[0] == '\n'))
29 continue;
30 else
31 break;
32 }
33
34 if (iLen > 0)
35 {
36 cJSON *root = cJSON_Parse(buf);
37 cJSON *result = cJSON_GetObjectItem(root, "result");
38 *sum = result->valueint;
39 cJSON_Delete(root);
40 return 0;
41 }
42 else
43 {
44 printf("read rpc reply err : %d\n", iLen);
45 return -1;
46 }
47 }
48 else
49 {
50 printf("send rpc request err : %d, %s\n", iLen, strerror(errno));
51 return -1;
52 }
53 }
第20行:构造一个JSON字符串,里面有:
①“\"method\":\"add\"”:这表示要调用服务器的add函数
②“\"params\":[%d,%d]”:这表示传递给add函数的参数
③“\"id\":\"2\"”:ID,这不重要。
13.3.3 服务器处理请求
服务器接收到网络数据后,根据里面的“method”值调用add函数。
add函数代码如下:
117 cJSON * add(jrpc_context * ctx, cJSON * params, cJSON *id) {
118 char buf[100];
119 cJSON * a = cJSON_GetArrayItem(params,0);
120 cJSON * b = cJSON_GetArrayItem(params,1);
121 return cJSON_CreateNumber(a->valueint + b->valueint);
122 }
第119~120行:从JSON格式的参数里提取出2个整数。
第121行:求和,然后返回一个JSON格式的数据。
13.3.4 客户端程序解析数据
在《13.3.2 客户端发出请求》的第36~38行代码中,就是解析服务器程序返回的结构体。
13.3.5 上机实验
本节在Ubuntu中做实验。先编译libev库,再编译jsonrpc库,最后编译、执行测试程序json-rpc_test。
假设这3个文件放在同一个目录下:
$ ls
jsonrpc-c_pc.tar.bz2 json-rpc_test.tar.bz2 libev_pc.tar.bz2
1.编译libev库
操作命令如下:
$ tar xjf libev_pc.tar.bz2
$ cd libev_pc/
$ CC=gcc ./configure --prefix=$PWD/tmp
$ make -j 16
$ make install
$ ls tmp/
include lib share
2.编译jsonrpc库
操作命令如下:
$ tar xjf jsonrpc-c_pc.tar.bz2
$ cd jsonrpc-c_pc/
$ autoreconf -i
$ CC=gcc ./configure --prefix=$PWD/tmp
$ make -j 16
$ make install
$ ls tmp/
include lib
3.编译测试程序
操作命令如下:
$ tar xjf json-rpc_test.tar.bz2
$ cd json-rpc_test/
$ make
4.执行程序
操作命令如下:
$ ./rpc server &
[1] 15028
$ ./rpc add 2 6
sum = 8
$ ./rpc hello 100ask
Hello, 100ask
注意:如果要重新运行rpc服务器程序,需要先关闭它,可以执行如下命令:
$ killall rpc
需要产品及方案支持
请扫码登记
如您在使用瑞萨MCU/MPU产品中有任何问题,可识别下方二维码或复制网址到浏览器中打开,进入瑞萨技术论坛寻找答案或获取在线技术支持。
https://community-ja.renesas.com/zh/forums-groups/mcu-mpu/
未完待续
推荐阅读
Modbus RTU客户端及服务器端的编程与实验 - RZ MPU工业控制教程连载(43)
Modbus TCP编程与实验 - RZ MPU工业控制教程连载(44)
LVGL开发入门 - RZ MPU工业控制教程连载(45)
需要产品及方案支持
请扫码登记