Biu~笔记:高通蓝牙ADK(30)--看不懂的Marshal

Bui~上篇和大家了解了Marshal的基础使用函数,收和发。但是知道这些只能跟踪源代码的数据传输过程。如果要自定义自己的数据去传输的话,是还不行的。所以这篇就带大家了解Marshal的数据是怎么声明定义的。从上篇我们知道,Marshal对数据的处理都靠两个变量type和type_desc,前者是指示这个数据是什么类型,后者是指示这个数据类型具体构成是怎样的。

       type

这个参数用来指示数据的类型是什么,在发送时会根据这个找到对应的type_desc去组装(marshal)数据,在接受时也会根据这个去找到对应type_desc解析(unmarshal)数据,这类参数常用MARSHAL_TYPE_x开头,也有MARSHAL_TYPE(x)这样用的,其实第二种是用连接符连接参数形成第一种形式的名字。

       例如:MARSHAL_TYPE(key_sync_req_t) =  MARSHAL_TYPE_key_sync_req_t

不管哪一种,都不能直接跳到定义的地方,他可能会到这里

       #define EXPAND_AS_ENUMERATION(type) MARSHAL_TYPE(type),

下以key sync的代码为例看看这些已经怎么用的,type的声明都在下图这个枚举中



乍一看这没枚举多少个参数,但在MARSHAL_TYPES_TABLE(EXPAND_AS_ENUMERATION)这个语句里面藏了很多,其实这里用了宏定义嵌套的手法,把一个表中的参数重复利用(偷懒高手Max→_→),要记住这个表,因为第二个变量也用这个表


所以MARSHAL_TYPES_TABLE(EXPAND_AS_ENUMERATION)这一句话的效用就等同于

    MARSHAL_TYPE (key_sync_req_t),\

    MARSHAL_TYPE (key_sync_cfm_t), \

    MARSHAL_TYPE (key_sync_req_bits_t), \

    MARSHAL_TYPE (key_sync_paired_device_req_t),

到这里想必大家都能明白这些type 参数的声明从哪里来了吧。

 

       type_desc

       这是一个数组集,里面每个值都是对type类型数据的描述。


这一看觉得数组也是挺少的,但是同第一个变量一样,MARSHAL_TYPES_TABLE(EXPAND_AS_TYPE_DEFINITION)这个语句也是包了好多个变量在里面,也是多个宏定义嵌套,其中EXPAND_AS_TYPE_DEFINITION是用marshal_type_descriptor_连接type生成的名字,这里注意,这个生成的名字,并不是凭空生成的,上面是枚举,不需要实体,这个是一个数据变量,变量是实体,所以这里生成的名字需要另外有声明定义的地方,这个查代码可以找到。最终这一个语句得到的效用如下

    marshal_type_descriptor_key_sync_req_t,\

    marshal_type_descriptor_key_sync_cfm_t, \

    marshal_type_descriptor_key_sync_req_bits_t, \

    marshal_type_descriptor_key_sync_paired_device_req_t,

       另外这个数组还有另外一个common的table,方法是一样的,只不过这里面的数据类型是常规的类型,很多channel都带有,这里不多解释。

       有个重要的知识点,这里为什么频繁是有嵌套语句去写呢,一是为了让你看不懂,二是为了代码简洁,三是为了好管理不易出错。我们看到这两个变量都用了MARSHAL_TYPES_TABLE去创建一系列的东西,这样创建出来的参数变量的排序是一致的,更何况这两个变量还要一一对应。所以要这样做,以后不管添加、修改或删除,只要在这个MARSHAL_TYPES_TABLE里面改都可保证相关的东西也一并被操作完。

       我们再来解析一下这个数组里面的变量都是怎么做的。这是一个marshal_type_descriptor_t结构体变量,看这个结构体声明就知道很复杂,这是为了兼容各种类型的数据。为了防止开发者的头发掉太多,在marshal_if.h里很贴心的为大家准备了些宏定义短语,方便大家编写想要的数据结构。

       例如:

                 MAKE_MARSHAL_TYPE_DEFINITION_BASIC

                 MAKE_MARSHAL_TYPE_DEFINITION_UNION

                 MAKE_MARSHAL_TYPE_DEFINITION

                 MAKE_MARSHAL_TYPE_DEFINITION_HAS_UNION

                 MAKE_MARSHAL_TYPE_DEFINITION_HAS_DYNAMIC_UNION

                 MAKE_MARSHAL_TYPE_DEFINITION_HAS_DYNAMIC_ARRAY

                 MAKE_MARSHAL_TYPE_DEFINITION_HAS_PTR_TO_DYNAMIC_ARRAY

     还有给member的宏定义

                 MAKE_MARSHAL_MEMBER

                 MAKE_MARSHAL_MEMBER_ARRAY

                 MAKE_MARSHAL_MEMBER_SHARED

                 MAKE_MARSHAL_MEMBER_POINTER

                 MAKE_MARSHAL_MEMBER_ARRAY_OF_POINTERS

真的好贴心的呢,不知道我在组建的时候会不会有选择困难症。



       这里实在太多选择了,我们还是挑两个最为常用的来说说吧,还是以key_sync的功能为例,这里有个marshal_type_descriptor_key_sync_req_bits_t这样的数据类型描述



里面就只用了MAKE_MARSHAL_TYPE_DEFINITION_BASIC这个来描述数据,这样声明就是表示这个数据是长度固定为sizeof(key_sync_req_bits_t)的数据,发送接收都按这个长度来,没别的要求。注意,这样做只适用于固定长度的数据,不可以变动数据长度。另外这样定义的数据既可以是单个字节也可以是数组,还可以是结构体,只要解析的时候用回key_sync_req_bits_t去解析和知道数据构成就可以了。(MAKE_MARSHAL_TYPE_DEFINITION_BASIC括号里面的参数其实是数据类型就好了,我不知道为什么这里加了个sizeof,因为宏定义里面就已经是有个sizeof了,这一步是多余的,还可能会出错)

       那如果数据长度是多变的,是不固定的,就不能用上面这个方法,这里就要说说member的应用,这个member可以简单的理解为结构体的成员,但这个成员是可以为union,也可以为动态数组等等,这里以marshal_type_descriptor_key_sync_cfm_t为例(这个例子的结构体也是定长,也适用上面那种情况,但这里主要是介绍member的写法)

其实这里就是把key_sync_cfm_t这个结构体描述了一下



先描述这个结构体有那些成员,通过MAKE_MARSHAL_MEMBER一一描述出来,然后通过MAKE_MARSHAL_TYPE_DEFINITION把整一个结构体描述一下。


如果结构体成员变量有什么特殊要求就需要用别的宏定义进行声明,具体要用什么,还是得大家看看上面说的那些宏定义的解析((#^.^#)或者来找我)

       另外为了匹配有些数据的特殊性,例如有些数据传输时需要实时数据,在通过marshal走一圈后,数据可能就变了。这时,同样在marshal_type_descriptor_t里就有一个callback的函数指针,在marshal准备就绪的时候,可以通过这个callback进行实时发送和接收。

       好了,了解完以上知识,应该可以自己去添加自定义的channel及数据吧,以上是本期博文的全部内容,如有疑问就别在博文下方评论留言了,有什么疑问或想了解的当面和我说(如果你知道我是谁的话ヽ( ̄▽ ̄)و),我会尽量安排上(o´ω`o)و。谢谢大家浏览,我们下期再见。








        又到了一年一度的不重要时刻,不知不觉新ADK系列也出了30篇了,感谢大家一直以来的支持和认可,回首这一年来,就感觉过了一年一样。哎呀,时间过得真快,还没好好享受有头发的日子。接下来的时间,小编要戴上假发去发廊洗洗头先,今年的博文就先出到这里啦,小编需要继续找一些常用难搞的东西研究下才能出后面的博文(这个偷懒的借口还可以吧)。但也欢迎大家提出自己想要了解的,只要是能力范围内都可。

另外有些博文看不懂也可以告知一下,因为小编的语文水平的确很一般,没描述清楚的,我会想办法再重新整理一遍。就像之前BLE广播的博文一样,我会用视频动画的方式讲解一遍。

要是还不懂,那你回去好好学学语文,肯定不是我的问题(╬◣д◢)  (〃´皿`)q  (╬ ̄皿 ̄)=○


         好了,提前祝大家新年快乐(就是想疯狂暗示你,到过年之前都没有新博文,而且还很敷衍,没点气氛,图也不给一个的祝福语,像极了被迫营业)

 

 

          简单是长期努力的结果,而不是起点

                                                              —— 不是我说的


 

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论

中断是PO的检测工作,我也无能为力啊
3056 5144有BUG, 32以上的pio,不会有中断上来 ,3046没问题, BIU BIU解答一下鸭