公共自行车租赁系统站点控制软件设计与实现第4章下.docx
- 文档编号:5829312
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:14
- 大小:258.30KB
公共自行车租赁系统站点控制软件设计与实现第4章下.docx
《公共自行车租赁系统站点控制软件设计与实现第4章下.docx》由会员分享,可在线阅读,更多相关《公共自行车租赁系统站点控制软件设计与实现第4章下.docx(14页珍藏版)》请在冰豆网上搜索。
公共自行车租赁系统站点控制软件设计与实现第4章下
3.PDU拼接/分离
PDU分离是指在发送方将SDU分割成n个PDU单元,每个PDU单元由1字节头部和7个字节数据域组成,帧头部分包含是否分离标志、是否分段标志以及长度标志组成,用以标志一个PDU单元的基本属性。
在接收端,接收方通过识别PDU的数据帧头,判断该PDU单元在完整SDU数据单元中的位置,并决定是否需要对其进行拼接操作。
采用拼接和分离的目的是提高CAN总线的利用率。
图4.8CAN通信协议结构图
结合SDU和PDU的概念,对本项目中CAN通信进行拆包和组包处理.对于CAN帧来说,不管CAN通信协议数据长度有多少,其格式是固定不变的,数据部分有8个字节。
因此,可以考虑将CAN通信中的一条协议看成总包,CAN帧看作分包,从而在发送端,将CAN协议分为多个CAN帧,而在接收端,需要将多个CAN帧组装成完整CAN协议包。
协议实现如图4.7所示。
图中SDU代指CAN通信协议包,PDU代指8字节CAN帧数据段,每个CAN帧都有唯一ID作为CAN帧的标识,用以标志该CAN帧的出处。
整个SDU数据帧由SDU帧头(1字节)和净荷(0~59字节)组成。
一个SDU帧有可能在发送时被拆分成多个PDU数据帧,在接收时由多个PDU数据帧组合而成。
PDU数据帧由PDU帧头(1字节)和PDU数据帧净荷(0~7字节)组成。
一个PDU帧为底层CAN帧的净荷,最大不超过8个字节。
为了减少开销,提高CAN帧的传输效率,SDU帧的长度由PDU数据帧的头部的Len域进行描述。
PDU数据帧由PDU帧头(1字节)和PDU数据帧净荷(0~7字节)组成,PDU数据帧头如图4.9(a)所示。
(a)PDU数据单元头部结构(b)SDU数据单元头部结构
图4.9PDU和SDU数据单元帧头部结构图
1.Split:
SDU帧分裂包指示。
0表示SDU数据帧未分裂,1表示SDU帧分裂;
(1)未分裂表示此次接收到的CAN帧携带一个完整的SDU,不需要进行重组;
(2)分裂表示此次接收到的CAN数据帧里携带的数据是完整SDU的一部分;
2.Eof:
在Split=1时有效,表示此包是否为分裂SDU帧的最后一个包;
3.Len:
表示SDU帧长度,包含SDU数据帧头长度;
(1)在Split=0时,直接表示SDU帧的长度;
(2)在Split=1时,当Eof=0时,表示SDU帧的总长度,当Eof=1时,表示此次收到的PDU数据单元里PDU数据部分的有效数据长度,即分裂最后一个包的PDU携带的有效数据长度。
SDU数据单元由SDU帧头(1字节)和SDU数据帧净荷(0~59字节)组成,SDU帧头由图4.9(b)所示。
1.Dire:
包请求定义。
0表示站点到锁桩的请求,1表示锁桩到站点的请求。
鉴于通信采用一问一答方式,主叫和响应消息的Dire数据域采用主叫一方的定义。
2.Status:
响应消息时有效。
0表示消息执行失败,1表示消息执行成功。
3.Pro:
协议类型,不同协议类型对应不同的SDU数据帧净荷。
详细描述如表4.3所示。
表4.3SDU帧头协议类型
序号
Protocol
Function
Payload
0
0x00
预留
-
1
0x01
上报设备状态
-
2
0x02
获取设备状态
-
3
0x03
锁桩控制
-
4
0x04
请求鉴权
-
5
0x05
解除锁定
-
6
0x06
更新M1卡状态
-
7
0x07
租车/下架记录
-
8
0x08
还车/上架记录
-
9
0x09
扣款
-
10
0x0A
锁桩配置
-
11
0x0B
锁桩注册
-
12
0x0C
时间同步
-
13
0x0D
网络用户组车
-
14
0x0E
电量控制
-
15
0x0F
还车写卡异常
-
16
0x10
锁桩充电请求
-
17
0x11
锁桩电量上报
-
18
0x12
申请M1卡秘钥
-
针对用户使用高峰时期,突发量大的性能需求,同时,为保证CAN数据不丢包,在设计CAN帧接收时需要考虑使用常用的数据结构对数据进行缓存。
通过研究CAN协议机制,在一条CAN线上的设备发送的CAN帧,具有先发先到的特点,对于锁桩上发的拆分后的CAN帧,也遵从先发先到的原则。
根据这一原则,想到使用队列(FirstInFirstOut,FIFO)数据结构进行数据缓存。
队列是一种先进先出的数据结构,只允许在队列的前端(front)进行删除操作。
而在表的后端(rear)进行插入操作,在实际使用过程中,需要根据需求确定队列的大小,需要进行适当的设置。
确定使用队列进行数据缓存之后,对于需要重组包的SDU帧而言,还需要一个数据结构对接收到的未完全组装的SDU进行缓存。
根据对协议的分析,每个CAN帧具有唯一的ID作为标识。
对于一个设备发出的SDU帧,虽然会分成多个PDU帧,但每个PDU数据单元都具有唯一的ID号作为标识。
同时,每个PDU帧头都存有PDU属性,能够标记该PDU属于哪一个SDU帧。
因此,可以考虑用CAN帧的ID号标记发送的设备,根据PDU的帧头属性进行拼装,这符合Hash表数据结构模型。
Hash表是一种通过查找关键码值(Keyvalue)而访问对应数据的数据结构。
即将数据通过设定关键码值的方式映射到表中的某一位置,并通过访问关键码值来访问记录,从而加快查找的速度[39]。
Hash表以
整个CAN帧的接收部分就可以采用FIFO+Hash进行设计,如图4.10所示。
图4.10FIFO+HASH数据结构图
图4.11CAN总线通信速率与通信距离关系图
当接收到CAN帧时,处理流程首先将接收到的CAN帧进行处理,保留帧数据部分,即PDU帧。
其次,将PDU帧存入FIFO队列进行缓存,根据数据的实际处理速度和数据量,可将FIFO的大小设为2048,并通过设定front指针和rear指针进行FIFO的维护。
在对队列写的同时,也对队列进行读操作,因此,选择将FIFO内的数据根据PDU帧帧头的标志进行优先级分类。
优先级高的PDU帧存入hash_map_1中,优先级低的PDU帧存入hash_map_2中,对应key值为CAN_id。
当PDU帧帧头的split位为1且eof位为0时,表示该PDU帧是分裂帧且不是最后一个,此时将PDU帧存入hash表中等待拼装,否则立即取出进行处理。
针对第三个问题,首先,需要对CAN总线的通信速率和通信距离进行分析,CAN总线通信速率与通信距离关系如图4.11所示。
由图可知,CAN总线通信速率与通信距离成反比关系。
当CAN总线通信速率为5Kbps时,通信距离为10km。
当CAN总线通信速率为1000Kbps时,通信距离<=40m[40]。
考虑到现场实际的实际情况,每一个锁桩占用总线长约2m,CAN总线最大支持110个终端,因此,总线长度<250m。
同时,还需要兼顾最远端通信,保证最远端的数据能够及时到达,因此,将CAN总线的通信速率设为250Kbps。
调用linux中的CAN通信命令:
#definecommand"iplinksetcan0typecanbitrate250000triple-samplingon";
system(command);
此外,由于CAN总线通信存在错误机制,以错误计数器的方式进行错误统计。
当计数值达到255时,该终端会进入总线关闭状态,不再参与总线通信,停止数据接收和发送,只能通过复位恢复。
这将会造成站点控制平台与锁桩通信的全面瘫痪,因此,需要对站点控制平台的CAN通信开启自动恢复机制,调用代码如下:
#definerestart"iplinksetcan0typecanrestart-ms10";
system(restart);
4.6异常情况下数据处理方法设计与实现
通过现场实际情况调研,并结合项目需求分析,需要对异常情况进行处理和分析,保证数据的可靠有效。
4.6.1异常情况下数据处理问题分析
对于异常情况的处理,结合项目需求,主要分为异常情况的检测以及异常情况下数据处理两部分。
异常情况的检测主要分为网络情况检测以及程序运行监测。
异常情况下数据处理主要针对租还车数据的处理,保证数据的可靠有效。
当检测到网络异常后,此时锁桩仍在上报用户信息,就需要对用户信息进行缓存处理,保证信息不丢失,当网络恢复后,及时同步信息。
针对以上问题,首先需要解决的是如何检测异常情况。
异常情况主要分为两点,即网络意外断开以及程序意外终止。
对于第一个问题,首先考虑的方法是采用短连接的方式,即每次发送数据时,尝试使用TCP方式连接一次服务器,连接成功则发送数据,不成功则本地缓存,等待网络恢复后再上传数据。
但由于租还车功能中数据上传频繁,每次租车或还车都会启动一次数据传输流程。
考虑到TCP连接存在三次握手四次挥手机制,因此会造成大量的网络开销。
同时,对于长时间不定时的租还车流程来说,短连接不易实现。
因此针对这一情况,考虑长连接的方式进行数据传输,一次连接成功后,不再进行连接,如果网络中断,则断开连接,等待网络恢复后重新连接。
这样能够有效减少数据的网络开销,同时数据通信的时间也大大缩短。
选用长连接,就会存在网络情况判断问题,通过测试,网络断开有两种情况,即tcp端口断开和物理链路断开。
因此需要对两种端口情况分别进行判断。
对于第二个问题,程序运行情况的检测,虽然在程序设计中,保证了程序的运行时间,但仍然需要对程序设计异常保护措施,保证整个系统的稳定可靠。
考虑到程序本身实现异常保护不易实施,因此,在操作系统中实现对程序的异常保护。
由此,借鉴linux系统中守护进程的概念,对本系统设计一套守护进程。
通过检测程序进程是否存在以及程序的执行状态,判断程序是否正常,出现异常情况时,结束已有进程,并重启程序,保证程序能够异常重启,不影响用户的正常使用[41]。
当出现网络异常时,锁桩仍在上报用户数据,此时需要对数据进行缓存处理。
考虑到单个站点的用户数据量较小,可采用文本格式进行数据存储。
当网络恢复正常后,及时与后台管理系统同步。
4.6.2异常情况下数据处理方法实现
对于网络状态检测,解决的办法是首先需要对物理网络连接进行检测,判断物理链路是否正常,当物理网络正常后,再进行端口连接检测,判断端口是否连接正常。
具体设计流程图4.12所示。
图4.12物理链路状态检测流程图
物理链路检测流程主要针对于在linux环境下,检测物理网络通断,同时判断端口连接状况,如图4.12所示。
流程中,通过建立socket,进而通过IO控制函数ioctl()获取套接字接口地址数据,并根据IFF_RUNNING的值判断物理链路的状态,其中,IFF_RUNNING能够对网线是否被拔出作出判断。
由此判断出物理链路的状态,当物理网络正常后,执行端口检测子流程[42]。
由图4.11可知,当物理连接判断正常后,开始执行端口检测子流程,如图4.13所示。
图中通过QT中的信号和槽机制,连接connect()信号和OnConnected()槽函数。
进而调用connect()函数,判断连接状态,如果连接成功,触发OnConnected()函数,执行函数体功能,连接失败则重新进行连接。
图4.13端口检测子流程图
对于程序异常终止的情况,采用脚本的方式编写守护进程进行异常检测。
通过使用PS指令,检测程序运行的状态和进程号,判断进程是否运行正常,当发现程序异常时立即进行异常处理并重启。
具体流程如图4.14所示。
图4.14守护进程流程图
对数据处理方法如图4.15所示。
当检测出网络异常后,通过修改程序中的标志位,立即将信息的上传方式切换至本地存储模式,即在每次信息通过以太网传输前,需判断标志位状态。
将数据存入文本,并将异常情况记录日志,等待网络恢复后与后台管理系统同步,同时在界面上,提示当前站点网络异常当网络恢复后,判断本地是否存在缓存文件,若存在缓存文件则与后台管理系统及时同步,同步后清除本地缓存文件。
图4.15异常情况下数据处理流程图
4.7用户卡升级设计与实现
用户卡升级作为系统升级中重要的一部分,目的是在一二期系统更新时,为广大用户提供便利的自助卡升级服务。
目前,在山西省某市广大用户手中持有的仍为一期租赁系统中的卡,由于一期系统的用户卡中已加密,只能在之前系统中使用。
因此,为了让用户在不更换卡片的情况下能够继续使用,就必须对用户卡进行升级。
4.7.1用户卡升级问题分析
在用户卡升级功能设计的过程中,需要考虑以下几个关键问题:
1.需要考虑到用户习惯,精简用户操作流程,让用户在使用中,尽量减少用户的操作步骤。
2.针对软件需求中“站点读卡成功率>99.7%”,需要对卡片读取信息流程进行优化,规避硬件可能带来的读卡失败问题。
3.需要有完善的错误规避机制,防止因写卡错误造成用户数据丢失。
针对用户升级设计中提出的问题,首先需要对用户卡的读写原理进行研究。
本课题中升级的卡片为M1卡,该卡属于非接触式集成电路(IntegratedCircuit,IC)卡,其最大特点在于无源特性及免接触式读写。
其主要性能指标如下所示[43]:
1.容量为8K位电可擦可编程只读存储器(ElectricallyErasableProgrammableRead-OnlyMemory,EEPROM)。
2.分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位。
3.每个扇区有独立的一组密码及访问控制。
4.每张卡有唯一序列号,为32位。
5.具有防读写冲突机制,支持多卡操作。
6.无电源,自带天线,内含加密控制逻辑和通讯逻辑电路。
7.数据保存期为10年,可改写10万次,读无限次。
表4.4M1卡存取结构[44]
扇区0
块0
卡片卡号
数据块
0
块1
数据
数据块
1
块2
数据
数据块
2
块3
密码A+存取控制+密码B
控制块
3
扇区1
块0
数据
数据块
4
块1
数据
数据块
5
块2
数据
数据块
6
块3
密码A+存取控制+密码B
控制块
7
扇区2
块0
数据
数据块
8
块1
数据
数据块
9
块2
数据
数据块
10
块3
密码A+存取控制+密码B
控制块
11
………
扇区15
块0
数据
数据块
60
块1
数据
数据块
61
块2
数据
数据块
62
块3
密码A+存取控制+密码B
控制块
63
每张M1卡共分为16个扇区,其中,每个扇区包含4块,每个块单元最多可存储16字节数据[45]。
整张M1卡中的数据块号按照从小到大排序,第0扇区的第一块即块0,最大数据块号为63号。
第零扇区的第一块用于存放卡号,每张卡的卡号唯一,且不可修改。
每个扇区的第0、1块用以存放数据字段,第3块用以存放每个山区的密码及存取控制,可以修改。
因此在使用过程中,为安全起见,可以对所使用的扇区进行加密[43],M1卡具体存取结构如表4.4所示。
在用户卡升级功能中,由于之前的系统中使用了部分扇区,而在本系统中无法使用,因此,本次升级的关键就是重新利用其中未被利用的扇区,并将用户卡写入相应扇区,同时,对于写入的数据进行读取验证,降低写入的错误率。
4.7.2用户卡升级问题解决
结合第三章读卡器通信协议设计,可将升级流程分为三个部分,即验证部分、升级部分以及确认部分。
验证部分具体设计如图4.16所示。
图4.16用户卡升级主流程图
验证部分,负责对用户卡的状态进行验证,通过验证密钥判断是否为已经升级的卡。
升级部分,负责对用户卡的状态进行改写,包括对卡片状态、卡片金额以及密钥改写,从而完成升级工作。
确认部分,将写入卡片的信息重新读出,与后台获取的信息进行比对,确保数据正确。
从图4.16中可以看到,整个串口通讯流程采用一应一答交互方式,即当接收到数据后再执行下一步骤,确保每个步骤成功后才会执行下一步骤。
为保证流程的鲁棒性,加入了以下几个子流程:
1.每次流程开始前,首先将检测当前用户卡是否已升过级,避免用户重复升级,因此加入检测子流程,流程如图4.17所示。
图4.17检测子流程图
2.为保证读卡的准确性及稳定性,每一次对卡通信都进行寻卡操作,因此在每一步开始前加入寻卡子流程,流程如图4.18所示。
3.在完成数据写入操作后,需对信息进行核对,防止乱码造成数据丢失,因此,加入验证子流程,将写入的数据读出后核对,保证数据正确。
寻卡子流程以及验证子流程,具体程如图4.19所示。
图4.18寻卡子流程图
图4.19验证子流程图
4.8本章小结
本章详细介绍站点控制软件的详细设计与实现,结合第三章的软件整体设方案设计,首先对站点控制平台的功能进行设计,进而根据功能模块,对站点控制软件进行通信协议设计,具体包括站点控制平台与后台管理系统、站点控制平台与锁桩、站点控制平台与串口的通信协议。
根据具体数据关系,设计相应的数据库表单。
在完成相关软件设计后,完成具体软件的实现工作,对软件中的关键技术进行详细的设计与实现。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 公共 自行车 租赁 系统 站点 控制 软件设计 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)