KL25Z Mbed RPC调用

KL25Z Mbed RPC调用

最近的一个项目中需要用到用Python控制MCU板,尝试过自己写一套程序,但是感觉太复杂,偶然间发现mbed项目已经有很多类似的功能了,直接就做好了RPC的功能,并且直接提供相应的Python接口,这个真的是方便多了,于是就玩了一下,虽然中间碰到很多问题,不过最后结果还是很不错的,这里就把实现的过程记录一下。

什么是RPC

百度百科

RPC(Remote Procedure Call)——远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

简单来说就是实现一个可以远程调用的接口,在KL25Z里面没有这么复杂,实际就是通过串口调用MCU中已经有的各种函数,同时还有各种的参数等等。举个简单的例子,MCU的程序中有个可以控制GPIO的函数,那么远程调用就是通过串口选定这个函数,同时提供函数的参数,MCU收到串口来的数据之后,查找相应的函数,执行函数,通过串口返回结果。

如何实现RPC

这个不用太操心,MBED已经提供写好的一个RPC的框架,只需要按照框架中的格式添加相应的函数就可以了, 官网上还有详细的教程

我们需要导入一个示例工程,然后编译下载,MBED支持在线编译,结果直接下载,可以从mbed模拟出来的U盘直接拷贝下载,注意不用按复位键,按住复位键是用来更新K20固件的,更新失败可就没有在线下载的功能喽。拷贝下载完成之后手动复位即可运行程序。

上位机的程序MBED提供的链接已经失效,我这里有个备用的链接可以直接使用,mbedrpc.py,上位机的python程序因为使用的是python2,对python3并不兼容,我这里做了一定的修改,现在可以兼容python3,主要是print和字符串的解析方式的修改,同时去掉了基于Http的远程调用,因为KL25Z压根就不支持HTTP呀。

下位机示例代码:

#include "mbed.h"
#include "mbed_rpc.h"
 
/**
 *  This example program has been updated to use the RPC implementation in the new mbed libraries.
 *  This example demonstrates using RPC over serial
 */
 
//Use the RPC enabled wrapped class  - see RpcClasses.h for more info
RpcDigitalOut myled(LED4,"myled");
 
Serial pc(USBTX, USBRX);
int main() {
    //The mbed RPC classes are now wrapped to create an RPC enabled version - see RpcClasses.h so don't add to base class
    
    // receive commands, and send back the responses
    char buf[256], outbuf[256];
    while(1) {
        pc.gets(buf, 256);
        //Call the static call method on the RPC class
        RPC::call(buf, outbuf); 
        pc.printf("%s\n", outbuf);
    }
}

程序联调

嗯,这一步就是坑比较多的地方,尤其是官网上竟然给了一个坑。

上位机进行联调的时候需要安装pyserial的库,直接pip就好了,参考官网给出的如下的例子:

#!python
python
>>> from mbedRPC import *
>>> serdev = 15 # or '/dev/tty.usbmodem1912' for Mac or '/dev/ttyACM0' for Linux/unix
>>> mbed = SerialRPC(serdev, 9600)
>>> x = DigitalOut(mbed, "LED3") #pass in the name of that object you wish to write to
>>> x.write(1)
>>> x.read()
1
>>>

第一个坑: serdev需要改为COM15,这个可能是python2python3之间的兼容性或者pyserial里面的坑吧。

连好板子之后试了一下上面的程序,发现死活没有反应,万般无奈想导出工程到本地调试,这里要吐槽一下MBED,我本地只有IAR,但是我导出到IAR一直报错,只有keil没有问题,这个。。。。。我只好从keil工程中把RPC相关的代码copy出来自己创建工程,还好,可以正常工作,单步调试发现用这个压根找不到相应的函数或者类呀。

后面仔细分析才发现,这个''LED3"到底是干啥用的呀,MCU怎么去处理这个"LED3"?调试到最后发现压根处理不了好吗,因为他压根就没有注册。MCU里面注册的是"myled"呀,真是巨坑无比呀,上述代码改为:

>>> x = DigitalOut(mbed, "myled") #pass in the name of that object you wish to write to
>>> x.write(1)
>>> x.read()
1
>>>

代码修改之后运行一切正常。

这里再补充一个往RPC库中增加新的函数的文档

好了,就先写这么多,我还要慢慢研究怎么加函数方便一些。

[mbedrpc.py.txt][1]

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

发表新评论