在Android模拟器和Ubuntu上测试Linux驱动

简介:

开发可统计单词个数的Android驱动程序

      在上一篇文章中已经实现了一个简单的Linux驱动程序,该驱动的功能是统计给定字符串中的单词数。并且在最后已经将该Linux驱动的源代码成功编译成动态Linux驱动模块word_count.ko。下一步就是测试该模块。测试的方法很多,最常用的就是直接在Ubuntu  Linux、Android模拟器中测试。当然,这 对于本章实现的Linux驱动是没问题的,但是对于需要直接访问硬件的驱动在Ubuntu Linux上测试就不太方便。在这种情况下就需要在相应的硬件上进行测试。

     对于一个Linux驱动程序,一开始可以在UbuntuLinux上做前期开发和测试。对于访问硬件的部分也可以在Ubuntu Linux用软件进行模拟。当基本开发完成后,就需要在开发板或工程样机上使用真实的硬件进行测试。当然,最后还需要在最终销售的手机上进行测试。最终测 试通过,Linux驱动才能算真正开发完成。在开发Linux驱动的过程中一个重要的步骤就是测试。本节将结合实际的开发流程介绍在不同平台上测试 Linux驱动程序。这些测试平台包括UbuntuLinux、Android模拟器和S3C6410开发板。

一、使用Ubuntu Linux测试Linux驱动

      本节将介绍如何在Ubuntu Linux下测试驱动程序。由于上一节编写的Linux驱动程序通过4个字节从设备文件(/dev/wordcount)返回单词数,所以不能使用cat 命令测试驱动程序(cat命令不会将这4个字节还原成int类型的值显示)。但可以使用如下命令从日志中查看单词数。

# sh build.sh
# echo 'I love you.'   > /dev/wordcount
# dmesg

 执行上面的命令后,如果输出如图6-13所示白框中的信息,说明驱动程序成功统计了单词数。

       虽然使用echo和dmesg命令可以测试Linux驱动程序,但这种方式并不是真正的测试。为了使测试效果更接近真实环境,一般需要编写专门用于测试的 程序。本节将为word_count驱动编写一个专门的测试程序(test_word_count.c)。test_word_count.c通过直接操 作/dev/wordcount设备文件与word_count驱动进行交互。测试程序的代码如下:

#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
int  main( int  argc, char  *argv[]) 
     int  testdev;                //  打开设备文件(/dev/wordcount)的句柄 
     unsigned char  buf[4];          //  表示单词数的4个字节 
     //  打开设备文件 
     testdev = open( "/dev/wordcount" , O_RDWR); 
     //  如果open函数返回-1,表示打开设备文件失败 
     if  (testdev == -1) 
    
         printf ( "Cann't open file \n" ); 
         return  0; 
    
     //  如果test_word_count后面跟有命令行参数,程序会将第1个参数值当作待统计的字符串 
     //  如果没有命令行参数,则只读取设备文件中的值 
     if  (argc > 1) 
    
         //  向设备文件写入待统计的字符串 
         write(testdev, argv[1], strlen (argv[1])); 
         //  输出待统计的字符串 
         printf ( "string:%s\n" , argv[1]); 
    
     //  读取设备文件中的单词数(4个字节) 
     read(testdev, buf, 4); 
   
     int  n = 0;      //  单词数 
   
     //  将4个字节还原成int类型的值 
     n = (( int ) buf[0]) << 24 | (( int ) buf[1]) << 16 | (( int ) buf[2]) << 8 
             | (( int ) buf[3]); 
         //  分别输出从设备文件获取的4个字节的值 
     printf ( "word byte display:%d,%d,%d,%d\n" , buf[0], buf[1], buf[2], buf[3]); 
     //  输出统计出的单词数 
     printf ( "word count:%d\n" , n); 
     //  关闭设备文件 
     close(testdev); 
     return  0; 

       test_word_count程序可以跟1个命令行参数(多个命令行参数只会使用第1个命令行参数)。如果命令行参数值含有空格,需要使用单引号(')或双引号(")将参数值括起来。可以使用下面的一组命令测试word_count驱动程序。

# gcc test_word_count.c  -o test_word_count  
# test_word_count  
# test_word_count "I love you."  

    执行上面的命令后,如果输出如图6-14所示的信息(假设word_count以前统计过一个含有4个单词的字符串),表示word_count驱动成功测试。

二、在Android模拟器上通过原生(Native)C程序测试Linux驱动

      虽说我们开发的是Linux驱动,但本书主要介绍的是Android版的Linux内核,因此,Linux驱动只在Ubuntu Linux上测试成功还不能保证在Android设备上一定能正常工作,所以必须在Android设备上进行测试。Android设备有很多种类,如安装 了Android的开发板,运行Android系统的手机或平板电脑等。但离我们最近的并不是这些硬件设备,而是Android模拟器。Android模 拟器可以模拟绝大多数真实的环境,所以可以利用Android模拟器测试Linux内核。

      在Android模拟器上测试Linux驱动首先应该想到的,也是最先应该做的就是将word_count.ko驱动模块安装在模拟器上。可能读者使用过 adb shell命令。如果进入Android模拟器的命令提示符为“#”,说明通过命令行方式进入Android模拟器直接就是root权限(命令提示符为 “$”,表示非root权限),因此从理论上可以使用insmod命令将word_count.ko驱动模块直接安装在Android模拟器中。现在我们 来测试一下,看看是否可以将word_count.ko安装在Android模拟器上。现在执行build.sh脚本,并选择“Android模拟器”, 脚本会自动将word_count.ko文件上传到Android模拟器的/data/local目录,并进行安装。如果读者选择的是S3C6410开发 板,在安装word_count.ko时就会输出如下的错误信息,表示编译Linux驱动的Linux内核版本与当前Android模拟器的版本不相同, 无法安装。所以在编译Linux驱动时,必须选择与当前运行的Linux内核版本相同的Linux内核进行编译,否则就无法安装Linux驱动。

insmod:init_module ‘/data/local/word_count.ko’ failed(Function not implemented) 

注意:建议上传文件到Android模拟器或开发板时,将文件放到/data/local目录,系统很多其他的目录,如/system/bin,都 是只读的,除非将word_count.ko文件打包进system.img,否则无法向这些目录写数据,即使有root权限也不行。

     用于Android模拟器的goldfish内核默认不允许动态装载Linux驱动模块,因此需要在编译Linux内核之前执行如下命令配置Linux内核。

# cd ~/kernel/goldfish  
# make menuconfig  

     执行上面的命令后,会出现如图6-15所示的设置界面。按“空格”键将第二项“Enable loadable module support”选中(前面是[*]),然后按“回车”进入子菜单,选中前3项,如图6-16所示。否则Linux驱动模块仍然无法安装和卸载。当退出设 置菜单时保持设置。最后按4.2.3节的方法重新编译Linux内核,


成功编译内核后,Android模拟器可以使用新生成的zImage内核文件动态装载Linux驱动模块。

    现在执行build.sh脚本文件完成对word_count驱动的编译、上传和安装的工作,然后进入Android模拟器的终端,使用echo和dmesg命令可以测试word_count驱动和查看测试结果,方法与上一节相同。

注意:编译可在Android模拟器上运行的Linux驱动模块要使用goldfish内核,使用其他的内核编译word_count.c,安装时会出现如下错误。

insmod: error inserting 'word_count.ko' : -1Invalid module format 

       在Android模拟器上不仅可以使用Linux命令测试驱动,也可以像UbuntuLinux一样使用本地C/C++程序进行测试。可能有的读者 要问,Android不是只能运行由Java编写的APK程序吗?顶多是在APK程序中嵌入NDK代码。还能直接运行普通的Linux程序吗?答案是肯定 的。不过要满足如下两个条件。

1.  Android模拟器、开发板或手机需要有root权限。

2.  可执行文件需要使用交叉编译器进行编译,以便支持ARM处理器。

     现在使用交叉编译器来编译在上一节编写的test_word_count.c文件。为了使编译步骤尽可能简单,我们使用Android.mk设置编译参 数,并使用make命令进行编译。首先在/root/drivers/ch06/word_count目录中建立一个Android.mk文件,并输入如 下的内容。

LOCAL_PATH:= $(call my-dir) 
   
include $(CLEAR_VARS) 
   
# 指定要编译的源代码文件 
   
LOCAL_SRC_FILES:= test_word_count.c 
   
# 指定模块名,也是编译后生成的可执行文件名 
   
LOCAL_MODULE := test_word_count 
   
LOCAL_MODULE_TAGS := optional 
   
include $(BUILD_EXECUTABLE) 

 

Android.mk文件中有如下两个地方需要说明一下。

LOCAL_MODULE_TAGS

表示当前工程(Android.mk文件所在的目录)在什么模式下编译。如果设为optional,表示不考虑模式,也就是说在任何模式下都会编译。该变量可以设置的值有user、userdebug、eng、optional。其中eng是默认值。

1.  user:限制用户对Android系统的访问,适合于发布产品。

2.  userdebug:类似于user模式,但拥有root访问权限,并且可以从日志中获取大量的调试信息。

3.  eng:一般在开发的过程中设置该模式。除了拥有userdebug的全部功能外,还会带有大量的调试工具。

LOCAL_MODULE_TAGS 的值与TARGET_BUILD_VARIANT变量有关。TARGET_BUILD_VARIANT变量用于设置当前的编译模式,可设置的值包括 user、userdebug和eng。如果想改变编译模式,可以在编译Android源代码之前执行如下命令。

# export TARGET_BUILD_VARIANT = user

或使用lunch命令设置编译模式。

# lunch full-eng

      其中full表示建立的目标,除了full目标(为所有的平台建立)外,还有专门为x86建立的full-x86。详细的建立目标执行lunch命令后就会列出。在图4-8已经显示了Android4支持的建立目标的编译模式。读者可以到第4章查看该图。

include $(BUILD_EXECUTABLE)

       BUILD_EXECUTABLE表示建立可执行的文件。可执行文件路径是<Android源代码目录>/ out/target/product/generic/system/bin/test_word_count。如果想编译成动态库(.so)文件,可 以使用include $(BUILD_SHARED_LIBRARY)。动态库的路径是<Android源代码目录>/ out/target/product/generic/system/lib/test_word_count.so。如果想编译成静态库(.a)文 件,可以使用include $(BUILD_STATIC_LIBRARY)。静态库的路径是<Android源代码目录>/ out/target/product/generic/obj/STATIC_LIBRARIES/test_word_count_intermediates/test_word_count.

      为了将test_word_count.c文件编译成可在Android模拟器上运行的可执行程序,可以将word_count目录复制 到<Android源代码目录>的某个子目录,也可以在<Android源代码目录>目录中为word_count目录建立一个 符号链接。为了方便,我们采用如下命令为word_count目录在<Android源代码目录>/development目录建立一个符号 链接(假设Android源代码的目录是/sources/android/android4/development/word_count)。

# ln -s  /root/drivers/ch06/word_count /sources/android/android4/development/word_count

现在进入/sources/android/android4目录,执行下面的命令初始化编译命令。

# source ./build/envsetup.sh

可以使用下面两种方法编译test_word_count.c。

1.     进入/sources/android/android4/development/word_count目录,并执行如下的命令。

# mm

2.     在/sources/android/android4目录下执行如下的命令。

# mmm  development/word_count

     成功编译后可以在<Android源代码目录>/out/target/product/generic/system/bin目录中找到 test_word_count文件。在随书光盘和模拟环境中已经带了编译好的test_word_count程序(包括Emulator版本和 Ubuntu Linux版本),可执行程序一般不需要考虑Linux内核的版本,用交叉编译器编译的支持ARM处理器的程序即可以在Android模拟器上运行,也可 以在S3C6410开发板或其他有root权限的手机中运行。

Emulator版本的路径

随书光盘:<光盘根目录>/sources/ch06/word_count/emulator/test_word_count

模拟环境:/root/drivers/ch06/word_count/emulator/test_word_count

 

Ubuntu Linux版本的路径

随书光盘:<光盘根目录>/sources/ch06/word_count/ubuntu/test_word_count

模拟环境:/root/drivers/ch06/word_count/ubuntu/test_word_count

现在执行下面的命令将test_word_count文件上传到Android模拟器。

# adb push  ./emulator/test_word_count /data/local

然后进入Android模拟器的终端,并执行下面的命令测试word_count驱动(需要先使用chmod命令设置test_word_count的可执行权限)。

# chmod 777 /data/local/test_word_count

# /data/local/test_word_count

# /data/local/test_word_count  'a bb ccc ddd eee'

执行上面的命令后,如果输出的单词个数是5,表示程序测试成功。

使用Android NDK和Java测试Linux驱动

本文节选至《Android深度探索(卷1):HAL与驱动开发》, 接下来几篇文章将详细阐述如何开发ARM架构的Linux驱动,并分别利用android程序、NDK、可执行文件测试Linux驱动。可在ubuntu Linux、Android模拟器和S3C6410开发板(可以选购OK6410-A开发板,需要刷Android)

本文转自银河使者博客园博客,原文链接http://www.cnblogs.com/nokiaguy/archive/2013/03/14/2960408.html如需转载请自行联系原作者


银河使者

相关文章
|
1月前
|
Ubuntu Linux 测试技术
Linux系统之Ubuntu安装cockpit管理工具
【10月更文挑战第13天】Linux系统之Ubuntu安装cockpit管理工具
115 4
Linux系统之Ubuntu安装cockpit管理工具
|
1月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
274 3
|
2月前
|
测试技术 Shell Android开发
Android 性能测试初探 (六)
本节聊聊性能测试的最后一项- 流量,当然我所指的性能测试是针对大部分应用而言的,可能还有部分应用会关注网速、弱网之类的测试,但本系列文章都不去一一探讨了。
54 6
|
2月前
|
JavaScript 测试技术 Android开发
Android 性能测试初探 (四)
本文介绍了GPU在移动端性能测试中的重要性,并详细解释了过度绘制、帧率和帧方差的概念。针对GPU测试,文章列举了三项主要测试内容:界面过度绘制、屏幕滑动帧速率和平滑度。其中,过度绘制测试需遵循特定标准,而帧速率和平滑度测试则可通过软件或硬件方法实现。在软件测试中,使用Systrace插件和高速相机是两种常用手段。对于不同机型,帧率及帧方差的测试标准也需相应调整。
53 5
|
2月前
|
测试技术 Shell Android开发
Android 性能测试初探 (三)
本文承接《Android性能测试初探(二)》,深入探讨CPU与内存测试。介绍了移动端内存测试的重要性及其测试目标,并详细列举了不同状态下应用内存消耗情况的测试项目。此外,还提供了多种内存测试方法,包括使用`procrank`等工具的具体操作步骤。最后,文章也简要提及了CPU测试的相关内容,帮助读者更好地理解Android性能测试的关键要素。
52 5
|
2月前
|
测试技术 Shell 定位技术
Android 性能测试初探 (五)
聊聊大家不常关注的测试项- 功耗
51 3
|
8天前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
37 3
|
1月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
59 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
2月前
|
移动开发 JSON Java
Jmeter实现WebSocket协议的接口测试方法
WebSocket协议是HTML5的一种新协议,实现了浏览器与服务器之间的全双工通信。通过简单的握手动作,双方可直接传输数据。其优势包括极小的头部开销和服务器推送功能。使用JMeter进行WebSocket接口和性能测试时,需安装特定插件并配置相关参数,如服务器地址、端口号等,还可通过CSV文件实现参数化,以满足不同测试需求。
239 7
Jmeter实现WebSocket协议的接口测试方法
|
2月前
|
JSON 移动开发 监控
快速上手|HTTP 接口功能自动化测试
HTTP接口功能测试对于确保Web应用和H5应用的数据正确性至关重要。这类测试主要针对后台HTTP接口,通过构造不同参数输入值并获取JSON格式的输出结果来进行验证。HTTP协议基于TCP连接,包括请求与响应模式。请求由请求行、消息报头和请求正文组成,响应则包含状态行、消息报头及响应正文。常用的请求方法有GET、POST等,而响应状态码如2xx代表成功。测试过程使用Python语言和pycurl模块调用接口,并通过断言机制比对实际与预期结果,确保功能正确性。
248 3
快速上手|HTTP 接口功能自动化测试