Linux 上串口PRC 协议的实现

46 篇文章 6 订阅
22 篇文章 6 订阅

      最近一直在研究如何实高性能Cortex-A 处理器在工业控制,物联网领域的应用。Cortex-A 内核的SOC 芯片通常运行linux OS ,直接支持的硬件接口不多,而且不够灵活。我们倾向采用cortex-M 单片机作为Cortex-A的扩展IO来使用。为了提高软件研发的效率cortex-M 运行Arm 公司的Mbed OS。

那么问题来了,Cortex-M 和Cortex-A 之间如何通信和控制呢?硬件方面我们尝试果Ethernet,SPI 和UART。软件方面采用各种自定义的交换协议。本文介绍如何在USB 串口上实现RPC 协议。

    RPC 的全称是远程过程调用(Remote procedure call),它是一个比较古老的协议。伴随着TCP/IP 协议的出现就出现了。 RPC 是request/response的架构。

   

        现在RPC 协议可以在许多协议上实现,例如HTTP。当然也可以在串口上实现。

信息格式更加倾向于XML和json格式。例如在json rpc 协议中:

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}

<-- {"jsonrpc": "2.0", "result": 19, "id": 1}

    我在另一篇博文《关于jsonrpc》一文中有关于jsonrpc比较详细的介绍。

RPC 在串口上的实现

    在cortex-M 的串口上实现json 格式的PRC 开销比较大,需要进行json 的解析。涉及数据格式转换,传输的时间也占有比较大,所以我们并不倾向使用jsonrpc 来实现cotex-M上的RPC协议,而是采纳了类似MODBUS RTU帧结构的形式来实现

请求(Request)

Address(1 Byte)

method(1 Byte)

length(2 Byte)

parameters(N Byte)

LRC(2 Byte)

响应(Response)

 

Address(1 Byte)

method(1 Byte)

length(2 Byte)

results(N Byte)

LRC(2 Byte)

 address,method 是1 个字节,length 为两个字节,高位在前,低位在后。

 results和parameters 是长度为length 的字节。而LRC是2个字节。

serialRPC 类

 下面是serial PRC类的实现。

linux 端(serialRPC.hpp)

#include "serialPort.hpp"
#include <stdint.h>
class serialRPC 
{
private:
   
	uint8_t _method;
	uint8_t _address;
	uint8_t sbuf[32];
    uint8_t rbuf[32];
	unsigned int calculateCRC16( uint8_t *puchMsg,unsigned int  usDataLen);
public:
    serialRPC();
    bool init(const char * dev);	
    bool callMethod(uint8_t address,uint8_t Method,uint8_t *data,int length );
	bool waitResult(uint8_t * data);
};

serialRPC.cpp

#include "serialRPC.hpp"
#include <iostream>
#define    DEFAULT_BAUD_RATE   9600
 serialPort serial;
      const  uint8_t auchCRCHi[256]={
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40
};
const  uint8_t auchCRCLo[256]={
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
    0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
    0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
    0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
    0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
    0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
    0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
    0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
    0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
    0x40
};
 serialRPC::serialRPC() 
			{
			_method=-1;
			}
 bool serialRPC::init(const char * dev)
 {            cout<<"seerial init:"<< endl;
	         serial.OpenPort(dev);
             cout<<"serial Setup"<< endl;			 
	   return  serial.setup(19200,0,8,1,'N');  
 
			 
 } 
 bool serialRPC::callMethod(uint8_t address,uint8_t method,uint8_t *data,int length )
 {
	  int index,i;
    index=0;
	 _address=address;
     _method=method;
    sbuf[index++]=address;
    sbuf[index++]=method;
    sbuf[index++]=(length>>8)&0xff;
    sbuf[index++]=length&0xff;
	for (i=0;i<length;i++)
		sbuf[index++]=data[i];
    unsigned short resultCRC =  calculateCRC16(sbuf,index); 
    sbuf[index++]=(resultCRC>>8)&0xff;
    sbuf[index++]=resultCRC&0xff; 
	serial.writeBuffer(sbuf, index);
    return true;
 }
 bool serialRPC::waitResult(uint8_t * data)
 {
	   unsigned short resultCRC ,recCRC;
    
    int state,index,i;
	uint16_t len,cnt;
    uint8_t ch;
    bool flag;
     flag=true;
     state=0;
     index=0;
     while(flag)
     { 
         ch=serial.getchar();
        
         switch(state)
         {
             case 0:{
                 if (ch==_address)
                   {state=1;
                   rbuf[index++]=ch;}
                 break;
                 }
            case 1:{
               
              if (ch==_method)
                   {state=2;rbuf[index++]=ch;}
                   else if(ch==(_method+0x80))
                     state=10;
                     else 
                     return 0;
                 break;
                 }
             case 2:{
                    len=ch;
                    rbuf[index++]=ch;
                    state=3;
                    break;
                    } 
			case 3:{
				   len=(len<<8)&0xff00+ch;cnt=len;
				    rbuf[index++]=ch;
					if (cnt>0)
                    state=4;
				else 
					 state=5;
                    break;
			}		
             case 4:{
                    rbuf[index++]=ch;
                    cnt--;
                    if (cnt==0)
                      { 
                      state=5;
                     
                      }
                    break;
                    }
              case 5:{
                     recCRC=ch;
                     state=6;
                     break;
                     } 
              case 6:{
                     recCRC=(recCRC<<8)|ch;
                      resultCRC =  calculateCRC16(rbuf,index);  
                   //  printf("CRC=%02x,%02x\n",recCRC,resultCRC);
                     if (recCRC==resultCRC) {
                         for (i=0;i<len;i++)
                           data[i]=rbuf[4+i];
                         return len;
                         }
                     else return 0;
                     }
               case 10:{
                       len=0;
                       flag=false;
                       break;
                       }                            
             }
         } 
    
        return len;
 }
 unsigned int  serialRPC::calculateCRC16( uint8_t *puchMsg,unsigned int  usDataLen)
{
    unsigned char uchCRCHi,uchCRCLo;
    unsigned char uIndex=0 ;                             /* will index into CRC lookup table */
    unsigned char tempp=0;
    unsigned int CRCHL=0;
    uchCRCHi=0xFF ;                             // high byte of CRC initialized 
    uchCRCLo=0xFF ; 
    tempp=0;                           // low byte of CRC initialized 
    while(usDataLen--)                       // pass through message buffer 
    {
        uIndex=uchCRCHi^*puchMsg++ ; // calculate the CRC high byte         
        tempp++;
        uchCRCHi=uchCRCLo^auchCRCHi[uIndex] ;//01-auchCRCHi[254]:0x81;02-0x01;03-0x80;04-0xC0
        uchCRCLo=auchCRCLo[uIndex] ;               
    }
    CRCHL=uchCRCHi;
    CRCHL=CRCHL<<8;
    CRCHL|=uchCRCLo;        
    return CRCHL;//(uchCRCHi<<8|uchCRCLo) ;//uchCRCHi:0xa1;uchCRCLo:2B
}

mbed 端

serialRPC.h

#include "mbed.h"
#include "USBSerial.h"
class serialRPC
{
    public :
    serialRPC();
    bool connect();
    uint8_t waitCall(uint8_t *data);
     bool sendResult(uint8_t *data,int length);
    private:
      USBSerial serial;
      int _method;
      int _address;
      uint8_t sbuf[32];
      uint8_t rbuf[32];
      void readBuffer(uint8_t * buf,int length);
      void writeBuffer(uint8_t * buf,int length);
      unsigned int  calculateCRC16( uint8_t *puchMsg,unsigned int  usDataLen);
    };
    

serialRPC.cpp(mbed OS)

#include "serialRPC.h"
#define   DEFAULT_BAUD_RATE   115200
    const  char auchCRCHi[256]={
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40
};
const  char auchCRCLo[256]={
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
    0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
    0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
    0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
    0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
    0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
    0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
    0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
    0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
    0x40
};

serialRPC::serialRPC() 
:serial(false,0x1f00,0x2012,0x0001) 
{   
   
    serial.init();
    _address=0x00;
}
bool serialRPC::connect()
{
   serial.connect();
   serial. wait_ready();
    return true;
    }
uint8_t  serialRPC::waitCall(uint8_t *data)
{  
      unsigned short resultCRC ,recCRC,len,cnt;    
    int state,index,i;
    uint8_t ch;
    bool flag;
     flag=true;
     state=0;
     index=0;
     while(flag)
     { 
     while(! serial.readable()){};
      ch=serial.getc();
        printf("0x%2.2X ",ch);
         switch(state)
         {
             case 0:{
                    _address=ch;
                if (_address==0x00)
                 {  
                  state=1;
                   rbuf[index++]=ch; 
                   }
                 break;
                 }
            case 1:{                            
                   _method=ch;
                   state=2;
                   rbuf[index++]=ch;                  
                 break;
                 }
             case 2:{
                    len=ch;
                    rbuf[index++]=ch;
                    state=3;
                    break;
                    }
             case 3:{
                    len=(len<<8)&0xff00|ch;
                    rbuf[index++]=ch;
                    if (len>0)
                    {
                        cnt=len;
                        state=4;
                      } else state=5;
                     break; 
                    }        
             case 4:{
                    rbuf[index++]=ch;
                    cnt--;
                    if (cnt==0)
                      { 
                      state=5;
                     
                      }
                    break;
                    }
              case 5:{
                     recCRC=ch;
                     state=6;
                     break;
                     } 
              case 6:{
                     recCRC=(recCRC<<8)|ch;
                      resultCRC =  calculateCRC16(rbuf,index);  
                     printf("CRC=0x%2.2X 0x%2.2X\n",recCRC,resultCRC);
                     if (recCRC==resultCRC) {
                         for (i=0;i<len;i++)
                           data[i]=rbuf[4+i];                         
                         return _method;
                         }
                     else return 0;
                     }                          
             }
         } 
  
        return _method;
    }
bool   serialRPC::sendResult(uint8_t *data,int length)
{
  unsigned short resultCRC;
  int index,i;
  index=0;
     sbuf[index++]=_address;
     sbuf[index++]=_method;
     sbuf[index++]= (length>>8)&0xff;
      sbuf[index++]= length&0xff;
    for (i=0;i<length;i++)
     sbuf[index++]=data[i];
     resultCRC =  calculateCRC16(rbuf,index);  
     sbuf[index++]=(resultCRC>>8)&0xff;
     sbuf[index++]=resultCRC &0xff;
     writeBuffer(sbuf,index);
      return true;
    }
 void serialRPC::readBuffer(uint8_t * buf,int length)
{
    int i;
    for (i=0;i<length;i++)
     {
        while(!serial.readable()){};
        buf[i]=serial._getc();
        
         }
}
void serialRPC::writeBuffer(uint8_t * buf,int length)
{
    int i;
    for (i=0;i<length;i++)
     {
        while(!serial.writeable()){};
       serial._putc(buf[i]);
         }
}   
unsigned int  serialRPC::calculateCRC16( uint8_t *puchMsg,unsigned int  usDataLen)
{
    unsigned char uchCRCHi,uchCRCLo;
    unsigned char uIndex=0 ;                             /* will index into CRC lookup table */
    unsigned char tempp=0;
    unsigned int CRCHL=0;
    uchCRCHi=0xFF ;                             // high byte of CRC initialized 
    uchCRCLo=0xFF ; 
    tempp=0;                           // low byte of CRC initialized 
    while(usDataLen--)                       // pass through message buffer 
    {
        uIndex=uchCRCHi^*puchMsg++ ; // calculate the CRC high byte         
        tempp++;
        uchCRCHi=uchCRCLo^auchCRCHi[uIndex] ;//01-auchCRCHi[254]:0x81;02-0x01;03-0x80;04-0xC0
        uchCRCLo=auchCRCLo[uIndex] ;               
    }
    CRCHL=uchCRCHi;
    CRCHL=CRCHL<<8;
    CRCHL|=uchCRCLo;        
   return CRCHL;//(uchCRCHi<<8|uchCRCLo) ;//uchCRCHi:0xa1;uchCRCLo:2B
}   

测试程序

该测试软件由linux 程序调用mbed OS 上的flipflop 程序,控制LED1 灯翻转。

Mbed  端

#include "mbed.h"
#include "serialRPC.h"
#include "method.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
uint8_t buf[32];
serialRPC rpc;
int main()
{ 
uint8_t Method;
uint8_t val;
 led1=1;
 led2=1;
  printf("RPC over Serial Test\n");
  rpc.connect();
  printf("connected\n");
    while (true) {
     Method=rpc.waitCall(buf);
     switch (Method)
     {
       case DegitalOut_Write:{
           switch(buf[0])
           {
            case 1:{led1=buf[1];break;}
            case 2:{led2=buf[1];break;}
            }
            buf[0]=OK;
            rpc.sendResult(buf,1);
            break;
            }
       case DegitalOut_Read:{
               switch(buf[0])
           {
            case 1:{val=led1;break;}
            case 2:{val=led2;break;}
            }
            buf[0]=val;
            rpc.sendResult(buf,1);
            break;
            } 
       case DegitalOut_Filpflop:{
             switch(buf[0])
           {
            case 1:{led1=!led1;break;}
            case 2:{led2=!led2;break;}
            }
            buf[0]=OK;
          rpc.sendResult(buf,1);
            break;
            }  
        }
     }   
}

linux 端(serialRPCTest)

#include "serialRPC.hpp"
#include <iostream>
#include <iomanip>
#define DigitalOut_Write  	   0
#define DigitalOut_Read    	   1
#define DigitalOut_Filpflop    2  
  serialRPC interface;
class DigitalOut
{   private:
    
	  int _gpio;
	  bool _value;
	  uint8_t buf[32];
	public:
	   DigitalOut(int gpio)
	   {
		  _gpio= gpio;
		  
	   }

	   void write(bool value)	
	   {   
	       buf[0]=_gpio;
		   buf[1]=value;
		   interface.callMethod(0,DigitalOut_Write,buf,2);
		   interface.waitResult(buf);
		   _value=value;
	   }
	   bool read ()
	   {
		    buf[0]=_gpio;
		   interface.callMethod(0,DigitalOut_Read,buf,1);
		    interface.waitResult(buf);
		   return _value;
	   }
	 char  flipflops()
	  {    cout<<"Send Flipflop"<< endl;
		   buf[0]=_gpio;
		   interface.callMethod(0,DigitalOut_Filpflop,buf,1);		   
		   interface.waitResult(buf);
		   cout <<"result:0x"<< std::setfill('0') << std::setw(2);
		   cout<<hex<<(unsigned int)buf[0]<<endl;
		  _value=!_value;
		  return buf[0];
	  }
};
int main()
{
 DigitalOut LED(1);
 cout<<"serialRPC Test"<<endl;
  interface.init("/dev/ttyS36");
  while (true)
  {
	 LED.flipflops();
	
	   sleep(1);
  }
}

实现 LED 闪烁,也可以写成:

  

bool val;

  val=!LED.read();
   LED.write(val);

但是交互的数据多了一点。所以我设计了一个Flipflop。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值