一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种整车SOA架构下基于SOMEIP协议的数据处理方法和装置与流程

2022-07-02 09:25:54 来源:中国专利 TAG:

一种整车soa架构下基于someip协议的数据处理方法和装置
技术领域
1.本发明属于以太网数据传输技术领域,特别涉及智能驾驶汽车pilot,parking及adas等功能数据在soa架构下基于someip协议的序列化和反序列化方法。


背景技术:

2.当前软件对于智能汽车非常重要,而面向服务架构(soa)这一在互联网行业比较成熟的技术在近几年慢慢地被引入汽车领域,随之而来someip协议也被更多地用于车载以太网通讯。soa是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
3.someip协议规定在传输时要按照一定规则将数据以二进制字节流的形式进行传输,即someip的序列化操作。作为数据的接收方,同样要按照约定好的规则去解析这个二进制数据流,以得到和发送方一致的数据结构,如结构体、数组等类型,这个即是someip的反序列化操作。
4.现有的基于someip的车载以太网通信实现方法主要是genivi项目中的一个开源实现vsomeip。其主要架构如图1所示。
5.vsomeip实现了someip协议以及服务发现两部分功能。如图1所示,vsomeip在两个设备之间建立点对点的连接,在vsomeip的配置文件中对两边设置tcp/udp协议以及相应的端口号,然后通过vsomeip内部逻辑实现service discovery服务发现层通讯。另外,routing manager路由管理器负责管理消息的收发和外部通讯socket的管理,上层的someip协议也通过vsomeip进行实现,应用层通过调用vsomeip协议进行数据的收发,并将数据和内部swc进行通信。但是现有技术中的vsomeip开源代码中并没有对通信数据的序列化和反序列化的实现方法,而这又是数据传输中重要的一环。
6.在智能驾驶汽车中,需要和外部进行以太网通信的数据多种多样。如果每个接口的序列化都要单独实现,将严重影响开发进度。另外当业务需求发生变更时,无法及时完成相应代码的更改,开发效率极低。


技术实现要素:

7.针对现有技术存在的问题,本发明实现各种数据类型的序列化和反序列化方法,并通过自动化生成脚本生成每个业务数据的类型定义以及序列化和反序列化函数方法,以达到可以根据业务需求的变更快速迭代软件的目的。
8.具体地,本技术所要求保护的一种整车soa架构下基于someip协议的数据处理方法,包括:基于车载网络通信中的通信业务需求发布对应业务数据;根据业务数据的类型判断业务数据需要序列化操作或者反序列化操作;
若判定业务数据需要序列化操作,则生成与所述业务数据对应的序列化函数并对所述业务数据进行序列化操作;若判定业务数据需要反序列化操作,则生成与所述业务数据对应的反序列化函数并对业务数据进行反序列化操作。
9.其中,发布的业务数据需要有详细的接口定义信息,如接口类型、名称、端点标志位、传输标志位等信息,其中端点标志位用于表明该业务数据的执行器是server端还是client端,传输标志位用于表明该业务数据是输出数据还是输入数据,基于接口定义信息判断业务数据内容及各接口需要序列化还是反序列化。
10.其中,所述方法还包括:将所述接口定义信息存放于excel表格中,若所述业务数据包括成员变量,则存放于excel表格中的所述接口定义信息还包括成员变量名称相关信息;使用python语言基于pandas读取excel表格中业务数据接口定义信息;自动生成所有业务数据变量的定义;所述生成与所述业务数据对应的序列化函数包括:通过遍历存有接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的序列化函数;所述生成与所述业务数据对应的反序列化函数包括:通过遍历存有接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的反序列化函数。
11.本发明通过读取业务数据excel表格,自动生成适用于不同数据类型的序列化和反序列化方法,极大缩短了开发的时间,能够快速适应需求变更。通过修改自动化生成脚本即可对所有同类型数据序列化和反序列化方法进行修改或优化,大大提高了代码的可维护性。
12.本发明涉及的数据类型有四种,基本数据类型、结构体、动/静态数组以及字符串,其中结构体和数组的数据成员也有其他类型的可能。
13.具体地,对所述业务数据进行序列化实现方式为:选出作为服务端或客户端需要发送的数据进行序列化,序列化函数的输入需要序列化的应用层数据(例如uint8_t &st)和最小单位为uint8类型的vector,以使得其符合someip协议的字节流。序列化操作包括如下四种情况:(1)对基础类型的数据进行序列化;(2)对结构体类型的数据进行序列化;(3)对数组类型的数据进行序列化;(4)对字符串类型的数据进行序列化。
14.反序列化方法用于解析复杂结构体类型的someip协议的数据流,与序列化方法对应地,反序列化方法包括以下四种情况:(1)对于基础数据类型的反序列化;(2)对于结构体数据类型的反序列化;(3)对于数组类型数据的反序列化;(4)对于字符串的反序列化。
15.同时,本技术还要求保护一种整车soa架构下基于someip协议的数据处理装置,包括:业务数据发布模块,用于基于车载网络通信中的通信业务需求发布对应业务数据;序列化或反序列化函数判断模块,用于判断业务数据需要序列化操作或者反序列化操作;序列化模块,用于在所述业务数据分析模块判定业务数据需要序列化操作时生成对应的序列化函数并对业务数据进行序列化;反序列化模块,用于在所述业务数据分析模块判定业务数据需要反序列化操作时生成对应的反序列化函数并对业务数据进行反序列化。
16.其中,发布的业务数据需要有详细的接口定义信息,如接口类型、名称、端点标志位、传输标志位等信息,其中端点标志位用于表明该业务数据的执行器是server端还是client端,传输标志位用于表明该业务数据是输出数据还是输入数据,基于接口定义信息判断业务数据内容及各接口需要序列化还是反序列化。
17.其中,所述业务数据生成模块还用于将所述接口定义信息存放于excel表格中,若所述业务数据包括成员变量,则存放于excel表格中的所述接口定义信息还包括成员变量名称相关信息,还用于使用python语言基于pandas读取excel表格中业务数据接口定义信息,及自动生成所有业务数据变量的定义;所述序列化模块包括:序列化函数生成模块,用于通过遍历存有所述接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的序列化函数;所述反序列化模块包括:反序列化函数生成模块,用于通过遍历存有所述接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的反序列化函数。
18.本发明通过读取业务数据excel表格,自动生成适用于不同数据类型的序列化和反序列化方法,极大缩短了开发的时间,能够快速适应需求变更。通过修改自动化生成脚本即可对所有同类型数据序列化和反序列化方法进行修改或优化,大大提高了代码的可维护性。
19.本发明涉及的数据类型有四种,包括基本数据类型、结构体、动/静态数组以及字符串,其中结构体和数组的数据成员也有其他类型的可能。
20.具体地,序列化模块实现方式为:选出作为服务端或客户端需要发送的数据进行序列化,序列化函数的输入需要序列化的应用层数据(例如uint8_t &st)和最小单位为uint8类型的vector,以使得其符合someip协议的字节流。序列化模块包括如下四种子模块:(1)基础数据类型的数据序列化子模块(2)结构体数据类型的数据序列化子模块(3)数组数据类型的数据序列化子模块(4)字符串数据类型的数据序列化子模块;反序列化模块用于解析复杂结构体类型的someip协议的数据流,与序列化操作对
应地,反序列化模块包括如下四种子模块:(1)基础数据类型的数据反序列化子模块;(2)结构体数据类型的数据反序列化子模块;(3)数组数据类型的数据反序列化子模块;(4)字符串数据类型的数据反序列化子模块;本发明应用在soa架构下的智能汽车数据通信,其业务数据根据不同服务设计了不同的excel格式的表格,其中包含服务id,instance id等someip服务实现信息,也包含各个ecu控制器的角色,即server/client端、服务中各个接口详细内容以及接口对应的收发关系。为了保证后续代码自动化生成的正确性,避免出现未定义的情况,数据类型应首先定义子类数据类型,再定义父类数据类型。根据各个业务数据类型设计对应的序列化和反序列化方法。
21.本发明基于车载网络通信中的通信业务需求发布对应业务数据;读取业务数据,判断业务数据需要序列化操作或者反序列化操作,自动化生成对应的序列化函数或反序列化函数;若判断业务数据需要序列化操作,则对业务数据进行序列化;若判断业务数据需要反序列化操作,则对业务数据进行反序列化。
22.本发明基于上述方案,达成了以下目的:1,解决了soa架构下vsomeip等基于someip的协议的序列化和反序列化问题;2,根据业务需求的变更自动化生成所需代码,无需因业务需求变更而重新进行编写序列化和反序列化接口代码;3,将基于someip协议的序列化和反序列化过程与基于业务需求的变更自动化生成所需代码的过程统一于智能驾驶汽车中和外部进行以太网通信的过程中,大大缩短开发时间,快速适应变更需求。
附图说明
23.为了更清楚地说明本技术实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单介绍。显而易见地,下面描述中的附图仅用于示意本技术的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图中未提及的技术特征、连接关系乃至方法步骤。
24.图1是现有技术中vsomeip架构图;图2是本发明实施例提供的整车soa架构下基于someip协议的数据处理方法的流程图;图3是本发明实施例提供的自动化生成对应的序列化函数或反序列化函数方法流程图;图4是本发明实施例提供的四种数据类型示意图;图5是本发明实施例提供的整车soa架构下基于someip协议的数据处理装置的结构图;图6是本发明实施例提供的计算机设备的架构图。
具体实施方式
25.为使本技术实施例的目的、技术方案和优点更加清楚,下面将结合本技术实施例中的附图,对本技术实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本技术一部分实施例,而不是全部的实施例。基于本技术中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本技术保护的范围。
26.在本技术实施例中使用的术语是仅仅出于描述特定实施例的目的,而非旨在限制本技术。在本技术实施例和所附权利要求书中所使用的单数形式的“一种”、“所述”和“该”也旨在包括多数形式,除非上下文清楚地表示其他含义,“多种”一般包含至少两种,但是不排除包含至少一种的情况。
27.应当理解,尽管在本技术实施例中可能采用术语第一、第二、第三等来描述目标对象,但这些对象不应限于这些术语。这些术语仅用来将多个对象彼此区分开。例如,在不脱离本技术实施例范围的情况下,第一目标对象也可以被称为第二目标对象,类似地,第二目标对象也可以被称为第一目标对象。
28.取决于语境,如在此所使用的词语“如果”、“若”可以被解释成为“在
……
时”或“当
……
时”或“响应于确定”或“响应于监测”。类似地,取决于语境,短语“如果确定”或“如果监测(陈述的条件或事件)”可以被解释成为“当确定时”或“响应于确定”或“当监测(陈述的条件或事件)时”或“响应于监测(陈述的条件或事件)”。
29.还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的商品或者系统不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种商品或者系统所固有的要素。在没有更多限制的情况下,由语句“包括一个
……”
限定的要素,并不排除在包括所述要素的商品或者系统中还存在另外的相同要素。
30.为了使本发明的目的、技术方案及优点更加清楚明白,以下结合实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
31.实施例一:如图2所示,本技术所要求保护的一种整车soa架构下基于someip协议的数据处理方法,包括:s110,基于车载网络通信中的通信业务需求发布对应业务数据;其中,发布的业务数据需要有详细的接口定义信息,如接口类型、名称、端点标志位、传输标志位等信息,其中端点标志位用于表明该业务数据的执行器是server端还是client端,传输标志位用于表明该业务数据是输出数据还是输入数据。
32.s120,根据业务数据的类型判断业务数据需要序列化操作或者反序列化操作;其中,在本发明的一个实施方式中,基于接口定义信息判断业务数据内容及各接口需要序列化还是反序列化。示例地,车载网络通信中产生了gps位置传感器所产生的一组应用层数据坐标数据,其数据名称为gpscoordinate[],接口类型为整形数组类型,端点标志位为f
terminal
=0,表示数据执行器是client端,f
transform
=0,表示数据为输入中控系统。基于gpscoordinate的上述信息,确定该数据接口需要进行序列化操作。示例地,车载网络通信中产生了gps位置传感器所产生的一组应用坐标数据,其数据名称为gpscoordinate[],接
口类型为二进制字节流,端点标志位为f
terminal
=3,表示数据执行器为服务端,f
transform
=3,表示数据为从中控系统向车载蓝牙连接模块发送。基于gpscoordinate的上述信息,确定该数据接口需要进行反序列化操作。
[0033]
s130,若判定业务数据需要序列化操作,则生成与所述业务数据对应的序列化函数并对所述业务数据进行序列化操作;s140,若判定业务数据需要反序列化操作,则生成与所述业务数据对应的反序列化函数并对业务数据进行反序列化操作。
[0034]
由于业务数据多种多样,数据量大,且变更周期短,如果每个接口变更都需要手动编写序列化或反序列化方法则需要耗费大量的时间。因此代码的自动化生成必不可少。具体地,如图3所示,所述方法包括:s111,将所述接口定义信息存放于excel表格中,若所述业务数据包括成员变量,则存放于excel表格中的所述接口定义信息还包括成员变量名称相关信息;s112,使用python语言基于pandas读取excel表格中业务数据接口定义信息;s113,自动生成所有业务数据变量的定义;所述生成与所述业务数据对应的序列化函数包括:通过遍历存有接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的序列化函数;所述生成与所述业务数据对应的反序列化函数包括:通过遍历存有接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的反序列化函数。
[0035]
本发明通过读取业务数据excel表格,自动生成适用于不同数据类型的序列化和反序列化方法,极大缩短了开发的时间,能够快速适应需求变更。通过修改自动化生成脚本即可对所有同类型数据序列化和反序列化方法进行修改或优化,大大提高了代码的可维护性。
[0036]
本发明涉及的业务数据类型有四种,如图4所示:包括基本数据类型、结构体、动/静态数组以及字符串,其中结构体和数组的数据成员也有其他类型的可能。其中按照someip协议规定,报文前面还需要添加length_field,以统计报文的长度。下面以几个典型例子来说明本发明的方法(本实施例中基础数据类型不考虑length_field)。
[0037]
具体地,对所述业务数据进行序列化操作的实现方式为:选出作为服务端或客户端需要发送的数据进行序列化,序列化函数的输入需要序列化的应用层数据(例如uint8_t &st)和最小单位为uint8类型的vector,以使得其符合someip协议的字节流。序列化操作包括如下四种情况:(1)对基础类型的数据进行序列化:由于单一基础数据类型不存在字节对其的情况,并考虑到基础类型的序列化还要被其他复杂数据类型引用,因此将所有基础类型序列化函数写为一个模板函数。主要方法为将应用层的数据类型进行类型转换为字节流,并根据大小端不同对其进行调整。最后在报文的头部添加someip协议规定的length_field。其中,一个实现方法为:template《typename t》inline uint32_t tobytes(const t &data, vector《uint8_t》 &bytes) {
const unsigned char* ptr = reinterpret_cast《const unsigned char*》(&data);//big endianfor (size_t i = sizeof(t); i 》 0;
ꢀ‑‑
i)bytes.push_back(ptr[i-1]);return sizeof(t);}inline uint32_t serialize(const uint8_t &st, std::vector《uint8_t》 &data) {uint32_t st_size = 0;st_size = tobytes(st, data);return st_size;}在模板函数tobytes中,首先要对传入的数据进行转换为char类型指针的强制类型转换,然后根据规定的大小端不同(实施例中为大端),依次对vector进行push_back。因此在模板函数的最后还需要对模板类型计算size并作为函数的返回值。使用内联函数提高序列化操作函数的效率。
[0038]
(2)对结构体类型的数据进行序列化:对于结构体类型的数据序列化的方法和基础类型方法类似。不同的是,需要判断结构体元素的类型是否为基础类型。如果是基础类型,则直接依次使用基础类型的模板函数即可;如果不是,则需要根据不同的数据类型设计不同的序列化函数。另外,length_field的计算需要通过每一次序列化返回值累加计算后并添加得到。
[0039]
结构体类型的数据中包含复杂类型数据,例如,一个复杂结构体的实施例如下:typedef struct{uint8_t test_1;uint8_t test_2;}test_struct;typedef std::vector《uint8_t》 test_array;typedef struct {uint8_t test_1;test_struct test_2;test_array test_3;std::string test_4;}test_data;其中成员变量有基础类型、结构体、动态数组以及字符串。其余复杂类型的结构体以这个结构体为例,具有变化出更复杂结构体类型的多种可能。
[0040]
上述结构体序列化函数及数据成员序列化子函数如下:inline uint32_t serialize(const test_data &st, std::vector《uint8_t》 &data) {
uint32_t st_size = 0;tobytes(st_size, data);st_size = tobytes(st.test_1, data);st_size = serialize(st.test_2, data);st_size = serialize(st.test_3, data);st_size = serialize(st.test_4, data);addlf(st_size, data);return st_size 4;结构体中数据成员为基础类型的可以直接使用模板函数tobytes,复杂结构体的序列化函数需要专门的定义。例如,对于test_struct test_2,其包含基础类型的变量成员test_struct.test_1及test_struct.test_2,对test_struct test_2进行序列化时,设置序列化子函数,实现序列化。同理,对于test_array test_3及std::string test_4,均设置对应序列化子函数实现序列化。
[0041]
为设定报文的length_field,即报文的长度,另外设计了如下addlf方法。
[0042]
inline void addlf(const uint32_t &length_field, vector《uint8_t》 &bytes) {const unsigned char* ptr = reinterpret_cast《const unsigned char*》(&length_field);for (size_t i = 0 ; i 《 sizeof(uint32_t); i ) {bytes[bytes.size()
ꢀ‑ꢀ
length_field
ꢀ‑ꢀiꢀ‑ꢀ
1] = ptr[i];}}其中此处报文头部长度定义为uint32类型,即在序列化后的报文前四位添加报文长度。函数的输入为前面每一步累加的报文长度st_size,此处根据大小端原则对报文头部进行赋值。
[0043]
进一步地,针对上述test_struct test_2所设置的序列化子函数具体为:inline uint32_t serialize(const test_struct &st, std::vector《uint8_t》 &data) {uint32_t st_size = 0;tobytes(st_size, data);st_size = tobytes(st.test_1, data);st_size = tobytes(st.test_2, data);addlf(st_size, data);return st_size 4;}test_struct类型的序列化子函数的方法和大的结构体方法一样,由于成员变量类型为基础数据类型,因此直接使用模板函数即可。另外还需要通过addlf函数添加报文的长度并返回整个结构体字节流的长度。
[0044]
进一步地,针对上述test_array test_3所设置的序列化子函数具体为:
inline uint32_t serialize(const test_array &st, std::vector《uint8_t》 &data) {uint32_t st_size = 0;tobytes(st_size, data);for(auto element : st){st_size = serialize(element, data);}addlf(st_size, data);return st_size 4;}test_array类型序列化为动态数组的序列化。主要方法是通过for循环遍历数组元素,对每个元素进行序列化,并在最后添加报头并返回长度。
[0045]
进一步地,针对上述std::string test_4所设置的序列化子函数具体为:inline uint32_t serialize(const std::string &str, std::vector《uint8_t》 &data) {uint32_t st_size = 0;tobytes(st_size, data);int utf8_bom[] = {0xef,0xbb,0xbf};int last_byte = 0x00;for (int i : utf8_bom) {data.push_back(i);st_size = 1;}for (unsigned char j : str) {data.push_back(j);st_size = 1;}data.push_back(last_byte);st_size = 1;addlf(st_size, data);return st_size 4;}string类型序列化为字符串的序列化。和其他类型不同的是,字符串类型需要额外添加头部bom值和尾部值。本例字符串采用utf-8编码规则,因此bom = ef bb bf,尾部设为0x00。中间报文内容通过遍历字符串中每个字符组成二进制流。
[0046]
由此,test_data结构体的序列化就完成了。
[0047]
(3)对数组类型的数据进行序列化:数组类型分为定长数组和动态数组,两种类型思路基本相同,都可以通过循环逐一对数组元素进行序列化并累加每一个数组元素的大小。在最后通过添加累加的大小size
赋值到length_field。
[0048]
举例动态数组序列化的方法,其与方法(2)中对test_array test_3的序列化方法类似,主要方法是通过for循环遍历数组元素,对每个元素进行序列化,并在最后添加报头,并添加报尾,并返回长度。
[0049]
(4)对字符串类型的数据进行序列化。
[0050]
字符串的序列化和其他类型序列化有所不同。字符串除了需要添加length_field以外还需要添加头和尾。对于中间报文内容则通过字符按照大小端规则转换成字节流的形式。以最小若规定utf-8编码规则,则需要添加0xef bb bf的头和0x00的尾。但对于中间报文内容序列化就直接遍历字符串每个字符并加入到vector中即可。
[0051]
举例字符串序列化的方法,其与方法(2)中对std::string test_4的序列化方法类似。
[0052]
对于解析复杂结构体类型的someip协议的数据流,本发明设计了一套反序列化方法。
[0053]
(1)对于基础数据类型的反序列化:反序列化函数的输入为需要解析的二进制流和目标地址,并将数据的长度进行输出,为复杂结构体的反序列化函数使用。使用的模板函数totype中将通过指针的方式按照大小端原则进行重组,并通过memcpy内存拷贝的方式获取解析的数据,此函数同时具有强制类型转换的功能,因此不需要额外的类型转换。
[0054]
template《typename t1》inline uint32_t totype(vector《uint8_t》::iterator &it, t1 &data) {uint8_t big_endian_array[sizeof(t1)];uint8_t *ptr = big_endian_array;for(size_t i = sizeof(data) ; i 》 0;
ꢀ‑‑
i) {*ptr = *(it i
ꢀ‑
1);ptr = ptr 1;}memcpy(&data, big_endian_array, sizeof(t1));it = sizeof(t1);return sizeof(t1);}inline uint32_t deserialize(std::vector《uint8_t》 &data, uint8_t &st) {uint32_t st_size;auto it = data.begin();st_size = totype(it, st);return st_size;}和序列化方法不同的是,模板函数totype采用迭代器的方式,因此这里反序列化方法采用从前到后的原则,每一个成员变量反序列化后都删除相应长度的变量,对于基础
数据类型的直接使用模板函数进行反序列化,对于复杂结构体类型的则需要使用专门的方法。
[0055]
inline uint32_t deserialize(std::vector《uint8_t》 &data, test_data &st) {uint32_t st_size = 0;auto it = data.begin();st_size = totype(it, test_1);data.erase(data.begin(), data.begin() st_size);st_size = deserialize(data, test_2);data.erase(data.begin(), data.begin() st_size);st_size = deserialize(data, test_3);data.erase(data.begin(), data.begin() st_size);st_size = deserialize(data, test_4);return st_size;}(2)对于结构体数据类型的反序列化:结构体数据类型的反序列化和序列化方法一样,首先去掉头部length_field,然后再进行反序列化。由于test_struct的成员变量均为uint8_t,因此直接调用函数 deserialize即会重载到对应的反序列化函数中,进而实现结构体的反序列化。
[0056]
inline uint32_t deserialize(std::vector《uint8_t》 &data, test_struct &st) {uint32_t st_size = 0;auto it = data.begin();st_size = totype(it, st_size);data.erase(data.begin(), data.begin() st_size);st_size = deserialize(data, st.test_1);data.erase(data.begin(), data.begin() st_size);st_size = deserialize(data, st.test_2);return st_size;}(3)对于数组类型数据的反序列化:同样需要去掉头部,然后再遍历数组中的每个元素,对其进行反序列化。每进行一次反序列化则需要删除对应的长度,以准确实现下一个元素的反序列化。
[0057]
inline uint32_t deserialize(std::vector《uint8_t》 &data, test_array &st) {uint32_t st_size = 0;auto it = data.begin();st_size = totype(it, st_size);data.erase(data.begin(),data.begin() st_size);
for(auto &i : st) {st_size = deserialize(data, i);data.erase(data.begin(),data.begin() st_size);}}(4)对于字符串的反序列化:首先需要判断头部和尾部是否是按照规定的值。然后通过指针的方式对目标数组进行赋值,最后通过累加各个字符即可得到反序列化后的字符串。
[0058]
inline uint32_t deserialize(std::vector《uint8_t》 &data, std::string &str) {str = "";string utf8_bom = "239187191";string bom = "";string last_byte = "";if (data.size()》4){for(int i = 4; i 《 7; i ) {int buffer = data[i];bom = to_string(buffer);}int buffer = data[data.size()-1];last_byte = to_string(buffer);}if(data.size() == 4){std::cout 《《 "no string data" 《《 std::endl;}else if (bom != utf8_bom || last_byte != "0") {std::cerr 《《 "serialization error: malformed_message" 《《 std::endl;}else {uint32_t length_field;std::vector《uint8_t》::iterator it = data.begin();it = sizeof(length_field) 3;uint8_t big_endian_array[data.size()-8];uint8_t *ptr = big_endian_array;for(int i = 0 ; i 《 data.size()-8; i ) {*ptr = *(it i);ptr ;}for ( int i = 0 ; i 《 data.size()-8; i ) {
str = big_endian_array[i];}}}综上,通过各种类型反序列化重载函数的实现即可得到复杂结构体test_data的反序列化结果。同时也包含了数组和字符串等复杂数据类型的反序列化方法。
[0059]
实施例二参见图5,本技术还要求保护一种整车soa架构下基于someip协议的数据处理装置,其一般性地包括业务数据发布模块10、序列化或反序列化函数判断模块20、序列化模块30和反序列化模块40。
[0060]
所述业务数据发布模块10用于基于车载网络通信中的通信业务需求发布对应业务数据。
[0061]
其中,发布的业务数据需要有详细的接口定义信息,如接口类型、名称、端点标志位、传输标志位等信息,其中端点标志位用于表明该业务数据的执行器是server端还是client端,传输标志位用于表明该业务数据是输出数据还是输入数据。
[0062]
所述序列化或反序列化函数判断模块20用于判断业务数据需要序列化操作或者反序列化操作。
[0063]
所述序列化模块30用于在所述业务数据分析模块判定业务数据需要序列化操作时生成对应的序列化函数并对业务数据进行序列化;所述反序列化模块40用于在所述业务数据分析模块判定业务数据需要反序列化操作时生成对应的反序列化函数并对业务数据进行反序列化。
[0064]
其中,所述业务数据生成模块10还用于将所述接口定义信息存放于excel表格中,若所述业务数据包括成员变量,则存放于excel表格中的所述接口定义信息还包括成员变量名称相关信息,还用于使用python语言基于pandas读取excel表格中业务数据接口定义信息,及自动生成所有业务数据变量的定义。
[0065]
所述序列化模块30包括序列化函数生成模块,用于通过遍历存有所述接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的序列化函数;所述反序列化模块40包括反序列化函数生成模块,用于通过遍历存有所述接口定义信息的列表,判断数据类型为基础类型、结构体、数组或者字符串,使用write函数按照不同的数据类型自动编写适用对应类型的反序列化函数。
[0066]
本发明通过读取业务数据excel表格,自动生成适用于不同数据类型的序列化和反序列化方法,极大缩短了开发的时间,能够快速适应需求变更。通过修改自动化生成脚本即可对所有同类型数据序列化和反序列化方法进行修改或优化,大大提高了代码的可维护性。
[0067]
本发明涉及的数据类型有四种,基本数据类型、结构体、动/静态数组以及字符串,其中结构体和数组的数据成员也有其他类型的可能。
[0068]
具体地,序列化模块实现方式为:选出作为服务端或客户端需要发送的数据进行序列化,序列化函数的输入需要序列化的应用层数据(例如uint8_t &st)和最小单位为
uint8类型的vector,以使得其符合someip协议的字节流。序列化模块包括如下四种子模块:(1)基础数据类型的数据序列化子模块;该子模块在模板函数tobytes中,首先对传入的数据进行转换为char类型指针的强制类型转换,然后根据规定的大小端不同对vector进行push_back,对模板类型计算size并作为函数的返回值;(2)结构体数据类型的数据序列化子模块;该子模块判断结构体元素的类型是否为基础类型,如果是基础类型,则直接依次使用基础类型的模板函数;如果不是,则根据不同的数据类型设计不同的序列化函数;通过每一次序列化返回值累加计算后并添加得到length_field;(3)数组数据类型的数据序列化子模块;该子模块通过循环逐一对数组元素进行序列化并累加每一个数组元素的大小;在最后通过添加累加的大小size赋值到length_field;(4)字符串数据类型的数据序列化子模块;该子模块对于中间报文内容通过字符按照大小端规则转换成字节流的形式;添加0xef bb bf的头和0x00的尾,对于中间报文内容序列化直接遍历字符串每个字符并加入到vector中。
[0069]
反序列化模块,对业务数据进行反序列化,用于解析复杂结构体类型的someip协议的数据流,与序列化操作对应地,解析各数据类型的someip协议的数据流,与序列化方法对应,反序列化方法包括以下四种情况:(1)基础数据类型的反序列化子模块;该子模块反序列化函数的输入为需要解析的二进制流和目标地址,使用的模板函数totype中将通过指针的方式按照大小端原则进行重组,并通过memcpy内存拷贝的方式获取解析的数据;直接使用模板函数进行反序列化;(2)结构体数据类型的反序列化子模块;该子模块首先去掉头部length_field,然后再进行反序列化;模板函数totype采用迭代器的方式,采用从前到后的原则,每一个成员变量反序列化后都删除相应长度的变量,对于基础数据类型的直接使用模板函数进行反序列化,对于复杂结构体类型的则需要使用对应的方法;(3)数组数据类型的反序列化子模块;该子模块对于数组的反序列化,去掉头部,然后再遍历数组中的每个元素,对其进行反序列化;每进行一次反序列化则需要删除对应的长度,以准确实现下一个元素的反序列化;(4)字符串数据类型的反序列化子模块;该子模块对于字符串的反序列化,首先需要判断头部和尾部是否是按照规定的值;然后通过指针的方式对目标数组进行赋值,最后通过累加各个字符即可得到反序列化后的字符串。
[0070]
实施例三对应上述方法,本发明还提供了一种计算机设备,包括:处理器和存储器,存储器上存储有可在处理器上运行的计算机程序,当计算机程序被处理器执行时,执行上述任意一个实施例提供的所述方法的步骤。
[0071]
其中,图6示例性的展示出了计算机设备,包括计算机系统1500,计算机系统1500具体可以包括处理器1510,视频显示适配器1511,磁盘驱动器1512,输入/输出接口1513,网络接口1514,以及存储器1520。上述处理器1510、视频显示适配器1511、磁盘驱动器1512、输入/输出接口1513、网络接口1514,与存储器1520之间可以通过通信总线1530进行通信连
接。
[0072]
其中,处理器1510可以采用通用的cpu(central processing unit,中央处理器)、微处理器、应用专用集成电路(application specific integrated circuit,asic)、或者一个或多个集成电路等方式实现,用于执行相关程序,以实现本发明所提供的技术方案。
[0073]
存储器1520可以采用rom(read only memory,只读存储器)、ram(random access memory,随机存取存储器)、静态存储设备,动态存储设备等形式实现。存储器1520可以存储用于控制电子设备运行的操作系统1521,用于控制电子设备的低级别操作的基本输入输出系统(bios)。另外,还可以存储网页浏览器1523,数据存储管理系统1524,以及图标字体处理系统1525等等。上述图标字体处理系统1525就可以是本发明实施例中具体实现前述各步骤操作的应用程序。总之,在通过软件或者固件来实现本发明所提供的技术方案时,相关的程序代码保存在存储器1520中,并由处理器1510来调用执行。
[0074]
输入/输出接口1513用于连接输入/输出模块,以实现信息输入及输出。输入输出/模块可以作为组件配置在设备中(图中未示出),也可以外接于设备以提供相应功能。其中输入设备可以包括键盘、鼠标、触摸屏、麦克风、各类传感器等,输出设备可以包括显示器、扬声器、振动器、指示灯等。
[0075]
网络接口1514用于连接通信模块(图中未示出),以实现本设备与其他设备的通信交互。其中通信模块可以通过有线方式(例如usb、网线等)实现通信,也可以通过无线方式(例如移动网络、wifi、蓝牙等)实现通信。
[0076]
总线包括一通路,在设备的各个组件(例如处理器1510、视频显示适配器1511、磁盘驱动器1512、输入/输出接口1513、网络接口1514,与存储器1520)之间传输信息。
[0077]
另外,该电子设备还可以从虚拟资源对象领取条件信息数据库中获得具体领取条件的信息,以用于进行条件判断,等等。
[0078]
需要说明的是,尽管上述设备仅示出了处理器1510、视频显示适配器1511、磁盘驱动器1512、输入/输出接口1513、网络接口1514,存储器1520,总线等,但是在具体实施过程中,该设备还可以包括实现正常运行所必需的其他组件。此外,本领域的技术人员可以理解的是,上述设备中也可以仅包含实现本发明方案所必需的组件,而不必包含图中所示的全部组件。
[0079]
实施例四本发明还提供了一种存储介质,计算机可读存储介质内存储有计算机程序,计算机程序被处理器执行时,实现上述任意一个实施例提供的所述方法的步骤。
[0080]
通过以上的实施方式的描述可知,本领域的技术人员可以清楚地了解到本发明可借助软件加必需的通用硬件平台的方式来实现。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品可以存储在存储介质中,如rom/ram、磁碟、光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本发明各个实施例或者实施例的某些部分所述的方法。
[0081]
还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的商品或者系统不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种商品或者系统所固有的要素。在没有更多限制的情
况下,由语句“包括一个
……”
限定的要素,并不排除在包括所述要素的商品或者系统中还存在另外的相同要素。
[0082]
上述说明示出并描述了本发明的若干优选实施例,但如前所述,应当理解本发明并非局限于本文所披露的形式,不应看作是对其他实施例的排除,而可用于各种其他组合、修改和环境,并能够在本文所述发明构想范围内,通过上述教导或相关领域的技术或知识进行改动。而本领域人员所进行的改动和变化不脱离本发明的精神和范围,则都应在本发明所附权利要求的保护范围内。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献