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