DA1458x BASS 初始化 -- Battery Service 分析(三)
来源:互联网 发布:亮剑 都梁 知乎 编辑:程序博客网 时间:2024/05/22 06:32
Overview
BASS 分为两部分。一部分为Profile,另一部分为Application。
同样初始化也是分为两部分,一部分是BASS Profile初始化,另一部分是 BASS Application初始化。
BASS APP 初始化
在BASS Application不是单独的一个任务,它是APP_TASK这个任务中的一个APP。
类似的还有app_diss、app_findme、app_proxr、app_sec、app_custs等。可见\sdk\app_modules\src目录
这些APP是系统自带的,可以通过宏控开启或者关闭。
从初始化的过程就可以看出来,当系统初始化时,将会调用void default_app_on_init(void)
函数。
void default_app_on_init(void){#if BLE_PROX_REPORTER app_proxr_init();#endif#if BLE_FINDME_LOCATOR app_findl_init();#endif#if BLE_BAS_SERVER app_batt_init();#endif#if BLE_DIS_SERVER app_dis_init();#endif#if BLE_SPOTA_RECEIVER app_spotar_init();#endif // Initialize service access write permissions for all the included profiles prf_init_srv_perm(); // Set sleep mode arch_set_sleep_mode(app_default_sleep_mode);}
从中我们不难看出app_batt_init();就是在这时被调用的。
app_batt_init()
app_batt_init()函数主要是调用battery_get_lv();
函数,得到开机时的电池电量。并没有什么实质上完成 battery service的初始化。
void app_batt_init(void){ // called from app.c::app_init() when chip boots#ifdef USED_BATTERY_TYPE cur_batt_level = battery_get_lvl(USED_BATTERY_TYPE);#else cur_batt_level = battery_get_lvl(BATT_CR2032);#endif}
app_bass_create_db()
真正的初始化(DataBase初始化)是由app_bass_create_db()
函数完成。
我们来看一下TASK_APP中关于DataBase初始化的过程。
从图中我们可以看到user_prf_funcs[k++].db_create_func();
这个函数就是callback app_bass_create_db()的家伙。
调用app_bass_create_db()函数之后,它就结束退出了。
而根源上这都是gapm_cmp_evt_handler函数的一个case。
gapm_cmp_evt_handler这个函数是一个比较底层的处理函数,我们不会去改动它。
当执行GAPM_SET_DEV_CONFIG这个case时就会去Create 各种DB。当然他只是开了一个头,很快就结束了。
后续通过内核消息,在TASK_APP中各个APP互相调用,最终会完成所有的DB的初始化。
注册app_bass_create_db()函数
我们来看下如何注册app_bass_create_db()函数的。同时一同注册还有一个很重要的函数app_bass_enable(),这个函数下面也会讲。
这两个函数是一起被注册到TASK_APP。具体见下面的结构体数组。
该结构体数组被定义在app.c文件中。
const struct prf_func_callbacks prf_funcs[] ={ #if BLE_PROX_REPORTER {TASK_PROXR, app_proxr_create_db, app_proxr_enable}, #endif #if BLE_BAS_SERVER {TASK_BASS, app_bass_create_db, app_bass_enable}, #endif #if BLE_FINDME_TARGET {TASK_FINDT, NULL, app_findt_enable}, #endif #if BLE_FINDME_LOCATOR {TASK_FINDL, NULL, app_findl_enable}, #endif #if BLE_DIS_SERVER {TASK_DISS, app_diss_create_db, app_diss_enable}, #endif #if BLE_SPOTA_RECEIVER {TASK_SPOTAR, app_spotar_create_db, app_spotar_enable}, #endif {TASK_NONE, NULL, NULL}, // DO NOT MOVE. Must always be last};
prf_funcs这个数组被谁调用呢?下面的函数揭晓答案:
/** **************************************************************************************** * @brief Initialize the database for all the included profiles. * @return true if succeeded, else false **************************************************************************************** */static bool app_db_init_next(void){ static uint8_t i __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY; static uint8_t k __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY; // initialise the databases for all the included profiles while( user_prf_funcs[k].task_id != TASK_NONE ) { if ( user_prf_funcs[k].db_create_func != NULL ) { user_prf_funcs[k++].db_create_func(); return false; } else k++; } // initialise the databases for all the included profiles while( prf_funcs[i].task_id != TASK_NONE ) { if (( prf_funcs[i].db_create_func != NULL ) && (!app_task_in_user_app(prf_funcs[i].task_id))) //case that the this task has an entry in the user_prf as well { prf_funcs[i++].db_create_func(); return false; } else i++; } #if BLE_CUSTOM_SERVER { static uint8_t j __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY; while( cust_prf_funcs[j].task_id != TASK_NONE ) { if( cust_prf_funcs[j].db_create_func != NULL ) { cust_prf_funcs[j++].db_create_func(); return false; } else j++; } j = 0; } #endif k = 0; i = 0; return true;}
是不是俄儿妹贼应,像prf_funcs这么吊的还有两个。
user_prf_funcs、prf_funcs、cust_prf_funcs这三个从名字就可以很清晰的看出是依照书序一次调用和初始化的。
prf_funcs初始化的是DISS、BASS、FINDME、PORX、SPOTA这几个。CUST自然是由cust_prf_funcs来搞,其余的就是USER。
prf_funcs调用完就退出了,那是怎么循环完毕的呢?这就是我们下面研究的问题。各位看官请看下节。
APP DataBase初始化流程
上个小节中,我们看到app_db_init_next函数调用了一个callback就退出了,例如prf_funcs,那么他是怎么把所有APP Database全部初始化完的呢?
我们可以先看下app_db_init_next函数定义的两个奇怪的i和k
static uint8_t i __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY; static uint8_t k __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY;
这两个变量不仅是静态的局部变量还是存放在retention_mem_area0端的。启动时会被初始化为0。
所以,函数中的循环遍历不是一次完成的而是这个函数被反复调用后完成的。
我们先看下图,这是我总结的以app_bass为例的database初始化流程图。
- DA1458x BASS 初始化 -- Battery Service 分析(三)
- DA1458x BASS 初始化 -- Battery Service 分析(二)
- DA1458x BASS Database的组成结构 -- Battery Service 分析(一)
- DA1458x DISS Database的组成结构 -- Device Information Service 分析(一)
- Android Battery 开发(三) BatteryService
- battery service 修改 52832
- Service Manger的初始化分析
- Nginx源代码分析之初始化(三)
- iGH EtherCAT初始化流程分析(三)
- Android Battery 分析
- Android Battery 分析
- Android Battery 分析
- Android Battery 分析
- Battery驱动及framework架构分析(android4.2)
- 原理分析之三:初始化(配置文件读取和解析)
- Tor源码分析三 -- 客户端执行流程(初始化)
- Cordova CLI源码分析(三)——初始化
- 原理分析之三:初始化(配置文件读取和解析)
- 工程变更-ECN,ECO,ECR,ECA
- jquery怎么根据id获取元素值
- 在Windows系统下搭建ELK日志分析平台
- Angular4 动态修改样式
- 使用keepalived实现双机热备
- DA1458x BASS 初始化 -- Battery Service 分析(三)
- llvm install
- 汽车经销商集团财务必修课:如何做好多品牌、多店的财务管理?
- Git常用命令总结
- python *args 和**kwargs的用法
- openpose 问题汇总
- aside标签
- 在不root手机的情况下读取Data目录下的文件
- 对深搜的理解问题——