从个人的角度,总结一下。
1.构建对SDK的整体认识
一个平台,一般都有一个SDK,并搭配有datasheet,也就是对SDK的整体架构的介绍、各个功能模块的介绍。因此,我们可以通过阅读官方的SDK文档,构建对SDK的整体认识。
官方的SDK文档,数量非常多。就涉及选择问题:先读什么,后读什么?
首先,阅读SDK的框架(整体介绍)的文档。第一遍,要略读,不需每一页都精读。理解不了,没有关系。后面我们会回头有针对性地重点阅读。
然后,根据从SDK的框架文档了解的层次或模块关系,有重点的选择阅读子模块或子系统的文档。这个阶段仍然以略读为准。
第一遍以略读为准,有2个目的:
(1)对官方所有SDK文档分类,为以后开发阶段查找资料建立索引;
(2)通过略读,构建一个SDK的框架图,获得SDK的整体认知。
2.阅读SDK代码
如果是MCU之类的单片机系统,那么,首先找到main()函数(或者类似的系统主入口)。然后,识别SDK代码的主线程(或主循环)。尝试使用以下方法:
(A)增加打印调试语句;
(B)屏蔽部分函数(代码);
摸清楚程序的运行逻辑。
如果是rtos之类的OS系统,那么,就复杂多了。下面以相机的SDK为例,展开讨论。
2.1 浅析RTOS应用层消息机制
一般的rtos系统,它的架构分为4层,从上到下依次是:
Application
Middleware
System
Hardware
如果我们做驱动软件开发,下面的内容对我们帮助不大。
如果我们做应用层软件开发,那么需要重点了解Application。
应用系统可以实现为消息驱动(也称为事件驱动)。这意味着所有状态改变和操作都由特定消息驱动。因此,我们需想办法找到rtos应用层的消息枢纽。它负责接收消息,预处理,转发消息。
如果我们曾经做过MFC,那么对于消息机制应该是非常熟悉。MFC是Windows系统的应用框架技术。消息机制也是嵌入式rtos系统的重要组成部分。
下面是消息机制的示意图:
[消息源] --------> [消息枢纽中心] --------> [消息处理者]
下面以“用户操作相机开始录像”实例进行说明。
在这个场景中:
(A)“用户按下按键”会触发“按键中断”,激活“录像键按下消息”;
(B)此消息通过消息循环发送到“消息枢纽中心”;
(C)“消息枢纽中心”转发,发送给当前“消息处理者”(备注:current active object);
(D)“消息处理者”接收到“录像键按下消息”后,先判断相机当前状态,如果是“预览”状态,那么调用“record_start()”函数开始录像。
简而言之,我们可以通过“跟踪某一个消息流”来学习SDK。
上述方法适用于学习以下基本的流程(场景):
(A)按下/释放按键,触发菜单设置;
(B)按下/释放按键,触发录像/拍照/回放等;
2.2 通过调试打印弄明白某个流程
如果我们曾经做过VC/VC++软件调试,那么一定使用过“断点调试”。“断点调试”是查看程序运行细节的利器!
嵌入式软件,如果是在linux上调试一个模块的代码,可以使用gdb工具。但是对于运行在相机内的rtos系统,通常无法直接使用gdb工具。不用担心,我们可以使用最简单但是一样有效的方法——“调试语句”。
在代码的关键函数或代码块里,增加类似下面的打印语句:
printf("-------- [%s-%d] -------- %d --------", __FUNCTION__, __LINE__, result);
编译、烧录firmware。
先把设备的串口接入电脑的串口(或者USB转串口),设备上电,操作,观察串口终端工具(例如:SecureCRT)的打印字符串,可以准确地获知:
(A)程序跑了哪些流程?
(B)某一个函数的返回值result是什么?(或者系统的某个状态值result是什么?)