【单片机】【UDS】 (单帧与多帧) 数据传输

        对于使用 CAN 的诊断通信系统,每个单帧 (SF)、 第一帧 (FF)、 连续帧 (CF) 或流控 制帧 (FC) 有 8 字节数据场;其中单帧的 CAN_DL≤8 且第一帧的 FF_DL≤4095;下表 中已定义 每个报文的类型。 CAN FD 帧的数据场支持最大 64 个字节,可包含的帧类型有单帧 (SF)、 第一帧 (FF)、 连续帧 (CF) 或流控制帧 (FC)。包含单帧的 CAN_DL>8 和第一帧的 FF_DL>4095。下表已定义每个报文的类型。

(1)单帧传输
       单帧意味着这一帧的数据场部分有效字节数<=8,不足的地方多以0xAA/55/CC等填充;无论单帧还是多帧,每一帧的0号字节的高四位用于区别帧类型(0/1/2/3);对于单帧SingleFrame,0号字节低4位【SF_DL】表示DLC(Data-Length-Control),表示需要读后面多长的数据(即后续有多少有效的数据位);
例:
02 10 03 55 55 55 55 55 -----> 有效数据是10 03
01 10 03 55 55 55 55 55 -----> 有效数据是10


(2)多帧传输
       首帧FF ---- FirstFrame,0号字节高4位固定为1,低4位加上1号字节组成DLC,表示多帧传输的数据长度(如果是22/2R读写数据服务,需要包含SID+DID)
       连续帧CF ---- ContinueFrame,0号字节高4位固定为2,低4位表示包的连续号SN,后面跟数据。SN根据以下规则定义: 首帧的SN值为 0,连续帧的第一帧SN值为1, 每增加一个连续帧,SN值增加1, 流控制帧不影响SN值的计算,当SN值达到15后,下一个连续帧的SN值为0。


       流控帧FC ---- FrameControl,0号字节高4位固定为3,低4位表示流状态参数FS。
FS(流控状态):0,CTS表示继续发送;1,WT表示等待,令发送方停止发送,直到下一个流控帧的到来;2,OVFLW表示溢出,当接收方接收到首帧,判断到FF_DL的长度比接收方缓冲区大时发送,随后发送方终止发送。1号字节表示BS(BlockSize)块大小,即告知发送方允许接下来发多少帧连续帧。当BS=0时,块大小不做限制。2号字节表示STmin(SeparationTimeminimum),规定了连续帧发送的最小时间间隔。

 

       下图为多帧传输机制,适用于 CAN 和 CAN FD 诊断通信系统。多帧传输时,应支持 ISO
15765-2 定义的流控传输方式。

                          

 
       为了确保正确的通信,每个控制器都必须遵守一组定时参数,这些参数在 ISO_15765-2 中
定义,仅适用于 CAN 控制器。支持以下参数集。
 

例:

### UDS协议中的单帧及流控概念工作原理 #### 单帧 (Single Frame, SF)UDS(Unified Diagnostic Services)协议中,单帧用于传输较小的数据量。它仅由一个CAN组成,因此不需要额外的管理机制来分割或重组数据。单帧的特点在于其结构简,能够一次性完成整个消息的传递。 当使用单帧时,N_PCI字段被设置为特定值以表明这是一个完整的[^1]。这种形式适合于那些只需要少量字节即可表达的服务请求或者响应场景下应用。 ```python # 示例:构建一个简单帧消息 sf_identifier = 0x0C # N_PCI for Single Frame data_length = 8 # 数据长度编码到SF_ID中 payload_data = b'\x01\x02\x03' # 实际负载数据 def create_single_frame(sf_id, data_len, payload): frame = bytearray([((sf_id << 4) | ((data_len & 0xF)))]) + payload[:7] return bytes(frame) single_frame_message = create_single_frame(sf_identifier, data_length, payload_data) print(single_frame_message.hex()) ``` #### (Multi-Frames: First Frame and Consecutive Frames) 对于较大的数据集,则需采用方式来进行传输。这包括首(First Frame, FF),用来指示即将发送的大块数据的第一部分及其总大小;随后跟随若干连续(Consecutive Frames, CFs),它们依次携带剩余未传送完毕的部分直至全部送达为止。 - **首**: 首先定义了整体数据包尺寸并提供初始的一些实际载荷信息。 - **连续**: 继续补充前面尚未完全给出的内容直到结束标志出现之前都属于此类别下的项目列表之一项而已啦! 关于超时错误处理方面,在此过程中也显得尤为重要——如果某个阶段未能按时接收到预期类型的下一个分组,则可能触发相应的异常检测逻辑从而中断当前会话流程以便采取进一步措施恢复通信连接正常运作状态等等情况发生时如何妥善应对等问题都需要考虑进去才行哦😊~ ```python # 构建一个序列的例子 ff_identifier = 0x10 # N_PCI for First Frame total_payload_size = 16 # 假设总共要传16个字节的数据 initial_payload_chunk = b'\x01\x02' cf_identifier_base = 0x20 # Base identifier for consecutive frames def create_first_frame(ff_id, total_size, initial_data): size_byte_high = (total_size >> 8) & 0xFF size_byte_low = total_size & 0xFF ff_content = bytearray([ (((ff_id << 4)) | size_byte_high), size_byte_low, ]) + list(initial_data)[:6] return bytes(ff_content) first_frame_msg = create_first_frame(ff_identifier, total_payload_size, initial_payload_chunk) remaining_bytes_to_send = max(total_payload_size - len(initial_payload_chunk), 0) def generate_consecutive_frames(cf_start_id, remaining_data, st_min=0xA): cf_messages = [] current_seq_num = 0 while remaining_data: seq_number = (current_seq_num % 16) next_cf_part = min(len(remaining_data), 7) cf_payload = [(cf_start_id + seq_number)] + list(remaining_data[:next_cf_part]) cf_messages.append(bytes(cf_payload)) remaining_data = remaining_data[next_cf_part:] current_seq_num += 1 time.sleep(st_min / 1000.0) # Respect the minimum separation time as per flow control. return cf_messages consec_frames_msgs = generate_consecutive_frames(cf_identifier_base, b'\x03'*remaining_bytes_to_send) for msg in consec_frames_msgs: print(msg.hex()) ``` #### 流控 (Flow Control Frame, FC) 为了协调双方之间的节奏差异问题引入了所谓的“流量控制”机制。通过这种方式可以让接收端告知发送者自己目前可以接受少新到来的信息元数量以及希望这些后续到达的消息之间保持怎样的时间间隔关系等参数设定规则[^3]^。 具体而言,每当收件箱准备就绪之后就会向寄件方发出这样一个特殊的信号—即所谓‘FC’类型的通知消息里面包含了三个关键组成部分: - `FS` 字段描述的是此刻允许继续推进的数量界限; - `BS` 表明一次最能容纳几个新的CF进来而不至于造成缓冲区溢出风险; - 而最后那个`STmin`则规定了每两个相邻CF间最短等待时限是少毫秒位计算所得的结果数值范围应该落在[0..127]区间之内或者是特殊保留含义代码比如F代表无特别限制条件约束情形之下均可自由调整安排进度计划表执行顺序操作步骤动作行为表现特征特性特点特色等方面内容均有所体现反映出来呢😄~ ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值