看源代码的时候,一般都是从整个代码的入口处开始,TI  BLE 协议栈源码也不例外。它的入口main()函数就是整个程序的入口,由系统上电时自动调用。

它主要做了以下几件事情:

(一)底层硬件初始化配置

(二)创建任务并初始化任务配置

(三)检测并执行有效的任务事件

Main() 函数源码如下:

一:底层硬件初始化设置

75行,设置系统时钟,使能内存缓冲功能。

78行,关中断,刚启动时,系统运行不稳定,一般会首先关中断。

81行,硬件相关的I/O 口配置。

84行,初始化mcu 内部的flash。

92行,开中断,当系统运行到这里的时候,状态已经很稳定,可以将中断打开。

95行,I/O功能配置,及设置按键回调函数指针。

98行,配置省电模式。

二:创建任务并初始化任务配置

89行,最主要的功能就是给创建所有的任务。

三:检测并执行有效的任务事件

102行,此函数是整个程序运行的核心,一旦进入,就循环执行所有的任务,永远不会结束。

下面分别列出这3个部分的主要源代码,并以按键KEY的配置为线索进行分析:

===================================================================

一:底层硬件初始化设置

a.        HalDriverInit() 主要是硬件抽象层初始化,配置PIN脚的工作模式。

比如ADC,UART,KEY,LCD等。

147行,HalKeyInit()是按键I/O配置,下面以此举例说明:

211-223行,将相应的PIN配置为GPIO,输入模式。

226行,初始化按键回调函数指针pHalKeyProcessFunction为NULL。

此回调函数在程序中的作用是,当driver层检测到按键中断后,只需要调用回调函数指针即可,至于函数执行什么功能则完全由用户层自己决定,这样的做的好处是将用户层与driver层分离,提高代码的模块化及可操作特性。

b.        InitBoard( OB_READY ),配置KEY  GPIO的中断功能

126行,HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback)此函数中配置中断使能,设置按键回调函数指针pHalKeyProcessFunction为OnBoard_KeyCallback。

OnBoard_KeyCallback()里面会继续调用函数OnBoard_SendKeys(),其功能是发送按键message给相应的任务。

硬件配置好后,只能说明硬件具备完成相应功能的条件,但是如何让它的功能实现,那就需要创建相应的应用程序来让硬件工作起来,这个程序就叫task,那task是如何创建的呢?

下面接着分析,如何创建task。

二:创建任务并初始化任务配置

前面讲过主函数main()89行osal_init_system(),主要功能是初始化系统设置,其中最重要的一个功能就是创建task,下面是创建task的源代码

122行,申请tasksEvents内存空间

123行,清零tasksEvents内存空间

126行,链路层task初始化

129行,硬件抽象层task初始化

132行,主机控制接口层task初始化

141行,逻辑链路控制及自适应协议层task初始化

144-156行,通用属性配置文件层task初始化

150行,安全管理层task初始化

159行,客户应用层task初始化

每个task 初始化时都会分配一个taskID,而且是从0 递增。

以Hal_Init(taskID++ )为例,从上面代码可以看出来,硬件抽象层的taskID值是1

92行,将task_id形参赋值给Hal_TaskID,故初始化后Hal_TaskID等于1

由于Hal_TaskID是定义为一个全局变量,因此,整个程序中,只要是与Hal_TaskID有关系的事情,都会交给Hal 层的task处理。

同样的道理,SimpleBLECentral_Init(taskID++)中会定义一个simpleBLETaskId,那么所有与simpleBLETaskId有关系的事情,也都会交给应用层任务函数处理。

那各层的任务函数是在哪里定义的呢?

在OSAL_simpleBLECentral.c文件中,定义了一个函数指针数组如下:

87行,Hal_ProcessEvent即为Hal层的任务处理函数指针,它是数组的第2个元素tasksArr[1],也就是说如果程序中要调用Hal层任务,直接写语句“tasksArr[1]();”

函数Hal_ProcessEvent()就会被执行了。

Task虽然被创建好了,但是task是要执行我们给它规定的功能的,那它是在哪里执行的呢?

接下来详细分析task 的执行的问题。

三:检测并执行有效的任务事件

系统中task 的执行,是由事件(evnet)来驱动的,程序会循环检测所有的task,如果发现某个task有新的event未被处理,那么这个task就会被调用。

osal_start_system()是整个程序的核心,里面是一个for死循环,不停调用函数osal_run_system(),它的实际功能就是不停检测是否有event产生,如果有event,就执行对应的task,请看源码:

1105行,定时器查询函数,它会检查所有的定时器,如果某个定时时间到达,就将相应的event 加入到tasksEvents[task_id],这里task_id的值是添加定时器时设置好的,具体请看osal_set_event()函数代码。

1110-1115行,检查所有任务,是否有需要执行的event发生,并记录这个event的索引idx。

1117行,taskCnt 是系统添加的任务个数,也就是tasksArr[]数组中元素的个数。

1123行,保存当前任务的将要执行的所有event。

1124行,清除当前任务的所有event。

1127行,保存当前任务的idx,供系统自己使用。

1128行,根据当前任务索引idx,在指针数组tasksArr[]中寻址当前任务的函数指针,调用当前任务函数,处理其中一个event,处理完毕后,返回还未处理的event。

1132行,将未处理的event恢复给当前任务事件变量保存,等待下一次再处理,直至处理问所有的event。

总结:

本节只是讲解了协议栈的主体框架,协议栈只是一个基础平台,在不同的方案中,就有不同的应用功能,相应的就必须为应用添加不同的task来实现实际的功能。

通过本节讲解,添加一个task的基本步骤如下:

1.        在HAL层配置任务要用到的I/O 的属性(如果不涉及I/O操作,则可省略此步骤)

2.        在数组tasksArr[]中添加任务(task)处理函数

3.        在函数osalInitTasks()中初始化任务task

根据上面的步骤我们可以很容易创建一个task。但是,如果程序中没有产生task的事件(event),task永远都不会运行。

这就有一个新的问题:event在什么情况下产生?它又是如何产生?

我们将在【事件和消息工作机制】一节中详细分解。

TI BLE协议栈软件框架分析的更多相关文章

  1. BLE协议栈及传统蓝牙协议栈对比图

    1. BLE协议栈的层次图如下: 主机控制接口层: 为主机和控制器之间提供标准通信接口 逻辑链路控制及自适应协议层: 为上层提供数据封装服务 安全管理层: 定义配对和密钥分配方式,为协议栈其他层与另一 ...

  2. openwrt: Makefile 框架分析

    openwrt: Makefile 框架分析 原文链接:blog.chinaunix.net/uid-26675482-id-4704952.html 本篇的主要目的是想通过分析Makefile,了解 ...

  3. VS2010/MFC编程入门之四(MFC应用程序框架分析)

    VS2010/MFC编程入门之四(MFC应用程序框架分析)-软件开发-鸡啄米 http://www.jizhuomi.com/software/145.html   上一讲鸡啄米讲的是VS2010应用 ...

  4. DM8168 DVRRDK软件框架研究

    转载注明:http://blog.csdn.net/guo8113/article/details/41120491 Netra(DM8168)处理器是个多核处理器,每一个核之间相互独立却又相互关联, ...

  5. 深入浅出低功耗蓝牙(BLE)协议栈

    深入浅出低功耗蓝牙(BLE)协议栈 BLE协议栈为什么要分层?怎么理解蓝牙"连接"?如果蓝牙协议只有ATT没有GATT会发生什么? 协议栈框架 一般而言,我们把某个协议的实现代码称 ...

  6. linux驱动基础系列--linux spi驱动框架分析

    前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...

  7. 深入浅出讲解低功耗蓝牙(BLE)协议栈

    详解BLE连接建立过程https://www.cnblogs.com/iini/p/8972635.html 详解BLE 空中包格式—兼BLE Link layer协议解析https://www.cn ...

  8. 蓝牙BLE: 蓝牙(BLE)协议栈

    蓝牙协议是通信协议的一种,一般而言,我们把某个协议的实现代码称为协议栈(protocol stack),BLE协议栈就是实现低功耗蓝牙协议的代码,理解和掌握BLE协议是实现BLE协议栈的前提.当前的蓝 ...

  9. 软件性能测试分析与调优实践之路-Web中间件的性能分析与调优总结

    本文主要阐述软件性能测试中的一些调优思想和技术,节选自作者新书<软件性能测试分析与调优实践之路>部分章节归纳. 在国内互联网公司中,Web中间件用的最多的就是Apache和Nginx这两款 ...

随机推荐

  1. Android 横屏切换竖屏Activity的生命周期(转)

    曾经遇到过一个面试题,让你写出横屏切换竖屏Activity的生命周期.现在给大家分析一下他切换时具体的生命周期是怎么样的:  1.新建一个Activity,并把各个生命周期打印出来  2.运行Acti ...

  2. POJ2942 Knights of the Round Table(点双连通分量 + 二分图染色)

    题目大概说要让n个骑士坐成一圈,这一圈的人数要是奇数且大于2,此外有些骑士之间有仇恨不能坐在一起,问有多少个骑士不能入座. 双连通图上任意两点间都有两条不重复点的路径,即一个环.那么,把骑士看做点,相 ...

  3. Codeforces 653D Delivery Bears(最大流)

    题目大概说有一张n个点m条边的简单有向图,每条边只能允许一定总量的货物通过.要让x只熊从1点到n点运送货物,每只熊都要运送且运送的货物重量都一样,求该重量的最大值. 二分重量判断是否成立. 如果已知重 ...

  4. WPF中ComboBox用法

    The ComboBox control is in many ways like the ListBox control, but takes up a lot less space, becaus ...

  5. CDOJ 435 (SCOI 2011) 糖果 Label:差分约束系统

    糖果 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 131072/131072KB (Java/Others) Submit Stat ...

  6. POJ-A Simple Problem with Integers

    Description 给出了一个序列,你需要处理如下两种询问. "C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000). " ...

  7. 《深入浅出Windows Phone 8.1 应用开发》基于Runtime框架全新升级版

    <深入浅出Windows Phone 8.1 应用开发>使用WP8.1 Runtime框架最新的API重写了上一本<深入浅出Windows Phone 8应用开发>大部分的的内 ...

  8. 手机web站点和手机app 技术选型的困惑于思考

    今年一直在关注移动端技术的发展,自己也用博客园的rss接口玩了半年,关于技术选型的困惑和大家说说 一 趋势 随着手机硬件不断的升级,外加4g牌照的发放,不出2年时间移动端web站点和手机app一定会进 ...

  9. URAL 1031. Railway Tickets(spfa)

    题目链接 不知为何会在dp里呢...INF取小了,2Y. #include <cstring> #include <cstdio> #include <string> ...

  10. IOS 蓝牙相关-基础知识(1)

    蓝牙常见名称和缩写 MFI ======= make for ipad ,iphone, itouch 专们为苹果设备制作的设备 BLE ==== buletouch low energy,蓝牙4.0 ...