## 协议设计 ### 指令通讯 1. 指令发送方法:
采用send-ack模式,即主机发送指令后,等待目标设备的ack确认,确认后才认为指令发送成功。 2. notify-noreply模式:
接口:
```c u32 erpc_sand(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len) ``` 描述:
主机对目标设备发送一条指令,并不期待回复。其本质就是发送一次指令。 ![](./picture/1.jpg) 3. notify-reply模式:
接口:
```c //主机: u32 erpc_send_wait_reply(u8 hw, u8 dest_id, u16 port, u8 *data, u16 len, u8 *reply_data, u16 *reply_len, u32 timeout); //目标设备: u32 erpc_replay(u8 hw, u8 dest_id, u16 port, u8 *data_out, u16 len); ``` 描述:
本质由2条指令组成。
主机发送req指令,从机直接回复。主机开始等待从机指令。
从机处理完成后,向主机发送rep指令,并附带回复数据。
主机收到rep指令后,开始等待rep指令的ack确认。
![](./picture/2.jpg) 4. 指令工作在单线程模式下:
指令发送后,等待ack确认,直到确认后才认为指令发送成功。如果确认超时,则认为指令发送失败。 可以在上述的接口中发现 cmd 并不定义为cmd,而是用了port的称呼。port的取值范围为0~65535,可以用来表示不同的指令。
4. 多device通讯方法:
每个port工作是单线程的,这就意味着,如果有多个device需要同时发送指令,则需要多线程或多进程。也就意味着需要定义不同的port号,来区分不同的线程,哪怕他是相同的指令。
例如:节点0x03中挂在了3个电机,需要这3个电机同时运动,此时理论上指令是相同的,但是device不同的。通讯库没有做device id的区分。为此需要将port号划分为cmd + device id的形式。cmd相同的指令,device id不同,这样就可以实现多device通讯。
u16(port) = u8(cmd) + u8(device_id);
这样一个cmd号需要链接到多个port上。此时的cmd可叫做cmd组 ![](./picture/3.jpg)