《7000应用开发技巧:模拟设备驱动(Mocking).docx》由会员分享,可在线阅读,更多相关《7000应用开发技巧:模拟设备驱动(Mocking).docx(3页珍藏版)》请在第一文库网上搜索。
1、7000应用开发技巧:模拟设备驱动(MoCking)Nei1Johnson-首席顾问-XtremeEDASohei1Sa1ehian-助理研究员-卡尔加里大学模拟(MOCking)是嵌入式系统开中用于单元测试和测试驱动的一种技术。模拟的好处在于通过删除不相关的从属代码,它允许开发者很容易地隔离和单元测试其中一部分代码。在嵌入式系统中,这些从属代码可能被当作由设备驱动和硬件运行的功能集合而存在。在这篇博客中,我们将讨论关于模拟设备驱动和硬件以及使用Goog1eTest和Goog1eMock来测试应用程序代码。在我们的例子中,目标硬件是Zynq-7000SOC的ZecIBoard。之所以挑选Zed
2、bOarc1是因为它有大量拥窟和很多简便可用的参考设计。不过其不足是,一板难求!一由于需求量大,这块开发板的运送时间超过2个月。不过目标硬件送达延迟对嵌入式开发者来说是个普遍问题。没有目标硬件,嵌入式开发者通常只有两种选择:a)等待,或b)在没有硬件的情况下开发并测试高质量应用我们的选择是不等待:-)我们的应用是一个视频演示平台。在这个平台上,ZynqSoC中ARMCorte-A9MPCoreCPU上运行的软件创建一系列视频帧,将它们通过由XiIinXIP核组建的硬件流水线传输到HDM1视频输出。我们的目的就是通过模拟设备驱动来写入和测试整个应用程序。然后,当收到ZedBoard后,我们就可以
3、用真正的设备驱动来重新部署我们的应用了。模拟设备驱动功能我们选择一个对我们单元测试很好的粒度(granu1arity)水平,因此我们能够从一系列很小的步骤开始建立和测试我们的应用程序,每一步测试完毕后再进行下一步。例如,软件功能是用xiic.中的XiiJDynInit()函数对目标硬件I2C控制器基地址进行适当的初始化。为了模拟像Xiic-DynInitO这样的设备驱动程序,我们的应用包含赛灵思设备驱动头文件xiij1.h,正如你通常做的一样。然后我们新建我们自己的该函数实现的存根来代行从IibXi1a中链接真正的设备驱动代码。这存根始于空的实现体,由此我们可以流水清除Makefi1e然后bu
4、i1d,确保编译器和链接器都没问题(大多数有经验的开发者也许不会有这个习惯,但是这是个开始阶段,我们觉得有帮助)。下一步是在存根下插入真正的功能,我可以使用这些功能来模拟设备驱动的功能。这就是要用到GOOgIeMOCk。Goog1eMock是一个C+框架,我们用它来模拟C函数(实际上Goog1eMOCk只是个C+框架,对C+不熟悉的开发者不必为此担心。所有的事都会由单内衬(OneTiner)的宏和函数完成,所以你会感到在没C+知识下创建和使用模拟也很容易)。我们选择模拟Goog1eMock中的一些设备驱动,叫做XdriverMocko在XdriVerMoCk中,有我们感兴趣的每个函数的声明。例
5、如XiiJDyn1nit(),我们使用MoCKMETH0D1,用来定义一个输入变量的函数。(类似拓,也有M0CK_METH0D2,MoCK_METH0D3之类的来声明有任意个输入变量的函数。)MOCK.METHOD宏定义亍很多一般特性使得编写单元测试和测试相互作用变得非常容易。更多好处还在后面。c1assXdriverMock(pub1ic:MK-METHOD1(XIiceDyn1nitrint(u32););externXdriverMock*InitXdri-JrFrcV*),externXdriverMockdestroy.VqrMoC?);作为我们XdriVerMoCk的一部分,我们也
6、有叫做getXdriverMock()和C1estroyXdriverMock()的全局函数分别来实例化和析构这个mock对象。如果你熟悉C+,getXdriverMock()和C1estroyXdriverMock()函数很像是构造函数和析构函数;它们构造一个XdriVerMoCk的实例用于测试,然后析构作为碎片收集。在具体实现的文件里这些方法看上去如下:*inc1udemXdriverMock.hmXdriverMock*XdMock0;XdriverMockgetXdriverMock()(i(XdMOCk0)XdMocknewXdriverMock();returnxdMock;)Xd
7、riverMockdestroyXdriverMock()(de1etexdMock;xdMock0;这个难题的最后一块就是调用Goo1geMock来填充XiiJDynInit()函数的存根应用0如下所示:有了这个,我们就成功地用GOogIeMOCk代替了真正设备驱动的功能。对单元测试来说,我们现在有了对设备驱动功能完整的控制,也摆脱了对硬件的依赖。记住我们的首要任务是验证分配给I2C控制器的基地址,现在我们可以开始编写验证应用程序正常工作的单元测试了。测试你的第一个功能为了用我们新的设备驱动模拟器开始编写测试,我们首先需要建立Goog1eTest线束,这相对简单,涉及新建测试单元实例,叫做IiCCtrI的类和XdriverMock的一个副本。如果你的测试单元是纯粹的C函数而不是像我们这样的C+类,当然你就只要直接调用C函数,不必管该类实例了。c1assIicCtr1Test:pub1ictesting:Test(pub1ic:IicCtr1*iicCtr1;XdriverMock*xdMock;IicCtr1Test()(iicCtr1newIicCtr1();xdMockgetXdriverMock();)-IicCtr1Test()(destroyXdrIverMock();1.