高通985处理器(高通8676)

作者:庄泽斌写一个文档,总结一下在msm8916平台上移植一个自己写的简单字符设备驱动的全过程。这个小项目的主要功能是开发一个简单的APP,通过JNI调用位于内

作者:庄泽斌

高通985处理器(高通8676)

写一个文档,总结一下在msm8916平台上移植一个自己写的简单字符设备驱动的全过程。这个小项目的主要功能是开发一个简单的APP,通过JNI调用位于内核的字符设备驱动。

一、APP的设计,开发平台Android Studio

主要文件有以下三个文件:

MainActivity.java文件内容如下:

包com . example . administrator . myled;导入Android . NFC . tag;导入Android . support . V7 . app . app compat activity;导入Android . OS . bundle;导入Android . util . log;导入Android . view . view;导入Android . widget . button;导入Android . widget . toast;导入com . zba Huang . led . low level . led native;公共类MainActivity扩展AppCompatActivity实现视图。onclick listener { private final static String TAG = & # 34;zbzhuang & # 34;按钮btn _ led _ on按钮btn _ led _ offLedNative myled@ Override protected void onCreate(Bundle savedInstanceState){ super . onCreate(savedInstanceState);setContentView(r . layout . activity _ main);initUI();myled = new led native();myled . opendev();Log.d(标签,& # 34;应用程序:打开开发& # 34;);} private void initUI(){ BTN _ led _ on =(Button)findViewById(r . id . BTN _ led _ on);BTN _ led _ on . setonclicklistener(this);BTN _ led _ off =(Button)findViewById(r . id . BTN _ led _ off);BTN _ led _ off . setonclicklistener(this);} @ Override public void onClick(View v){ switch(v . getid()){ case r . id . BTN _ led _ on:toast . make text(main activity . this,& # 34;拉灯-& gt;",吐司。LENGTH_SHORT)。show();Log.d(标签,& # 34;app:LED亮& # 34;);myled . Devon();打破;case r . id . BTN _ led _ off:toast . make text(main activity . this,& # 34;关灯-& gt;",吐司。LENGTH_SHORT)。show();Log.d(标签,& # 34;app:LED关闭& # 34;);myled . devoff();打破;默认:break} } @覆盖受保护的void on destroy(){ super . on destroy();myled . closedev();Log.d(标签,& # 34;应用程序:关闭开发& # 34;);} } } led native . Java文件的内容如下:

这个文件中声明的方法是在jni中实现的。特殊关键字的使用表明这种方法在JNI实施。

包com . zba Huang . led . low level;/** *由管理员于2017/3/29 0029创建。*/public class led native { static { system . loadlibrary(& # 34;led _ jni & # 34);} public native int openDev();public native int devOn();public native int devOff();public native int closeDev();}包com . zbahuang . led . low level;/** *由管理员于2017/3/29 0029创建。*/public class led native { static { system . loadlibrary(& # 34;led _ jni & # 34);} public native int openDev();public native int devOn();public native int devOff();public native int closeDev();}activity_main.xml文件的内容如下:

& lt?xml版本= & # 34;1.0"编码= & # 34;utf-8 & # 34;?& gt& ltAndroid . support . constraint . constraint layout xmlns:Android = & # 34;http://schemas.android.com/apk/res/android" xmlns:app = & # 34;http://schemas.android.com/apk/res-auto" xmlns:tools = & # 34;http://schemas.android.com/tools"安卓:layout _ width = & # 34match _ parent & # 34Android:layout _ height = & # 34;match _ parent & # 34工具:上下文= & # 34;com . example . administrator . myled . main activity & # 34;& gt& ltrelative layout Android:layout _ width = & # 34;394dp & # 34Android:layout _ height = & # 34;520dp & # 34工具:layout _ editor _ absoluteX = & # 34-5dp & # 34;tools:layout _ editor _ absolute y = & # 34;-10dp & # 34;& gt& lt按钮Android:id = & # 34;@+id/BTN _ led _ on & # 34;Android:layout _ width = & # 34;wrap _ content & # 34Android:layout _ height = & # 34;wrap _ content & # 34Android:layout _ alignParentStart = & # 34;真& # 34;Android:layout _ alignParentTop = & # 34;真& # 34;Android:layout _ margin start = & # 34;56dp & # 34Android:layout _ margin top = & # 34;109dp & # 34Android:text = & # 34;拉灯& # 34;/& gt;& lt按钮Android:id = & # 34;@+id/BTN _ led _ off & # 34;Android:layout _ width = & # 34;wrap _ content & # 34Android:layout _ height = & # 34;wrap _ content & # 34Android:layout _ align baseline = & # 34;@+id/BTN _ led _ on & # 34;Android:layout _ align bottom = & # 34;@+id/BTN _ led _ on & # 34;Android:layout _ margin start = & # 34;81dp & # 34Android:layout _ toEndOf = & # 34;@+id/BTN _ led _ on & # 34;Android:text = & # 34;关上灯& # 34;/& gt;& lt/relative layout & gt;& lt/Android . support . constraint . constraint layout & gt;JNI文件:

led_jni.cpp

# include & ltsys/types . h & gt;# include & ltsys/stat . h & gt;# include & ltfcntl.h & gt# include & ltunistd.h & gt# include & lt错误号& gt# include & ltstring.h & gt#定义LOG _ TAG & # 34zbzhuang & # 34# include & ltutils/log . h & gt;#包括& # 34;jni.h & # 34静态jint fdstatic jint open_led(JNIEnv *env,jobobject thiz){ a logd(& # 34;JNI:-% s-& # 34;,_ _ FUNCTION _ _);FD = open(& # 34;/dev/led 1 & # 34;,O _ RDWR);if(FD & lt;0){ a logd(& # 34;JNI:打开错误:% s \ n & # 34,strerror(errno));return-1;}返回0;}static jint led_on(JNIEnv *env,job object thiz){ a logd(& # 34;JNI:-% s-& # 34;,_ _ FUNCTION _ _);jint retjint on = 1;ret = write(fd,&on,4);if(ret & lt;0){ a logd(& # 34;JNI:注销错误:% s \ n & # 34,strerror(errno));return-1;}返回0;}static jint led_off(JNIEnv *env,job object thiz){ a logd(& # 34;JNI:-% s-& # 34;,_ _ FUNCTION _ _);jint retjint off = 0;ret = write(fd,&off,4);if(ret & lt;0){ a logd(& # 34;JNI:注销错误:% s \ n & # 34,strerror(errno));return-1;}返回0;} static jint close _ led(JNIEnv * env,job object thiz){ a logd(& # 34;JNI:-% s-& # 34;,_ _ FUNCTION _ _);关闭(FD);返回0;} const jnitivemethod led _ JNI _ methods[]= { { & # 34;openDev & # 34,"()我& # 34;,(void *)open_led},{ & # 34;德文郡& # 34;,"()我& # 34;、(void *)led_on}、{ & # 34;德沃夫& # 34;,"()我& # 34;、(void *)led_off}、{ & # 34;closeDev & # 34,"()我& # 34;,(void *)close_led},};金特JNI_OnLoad(JavaVM * vm,void * reserved){ JNIEnv * env = NULL;jint reta logd(& # 34;% s[% s:% d]JNI:-^_&-\ n & # 34;、__func__、__FILE__、_ _ LINE _ _);ret = VM-& gt;GetEnv((void * *)&env,JNI _版本_ 1 _ 4);如果(ret!= JNI _ OK){ ALOGE(& # 34;JNI:VM-& gt;GetEnv错误& # 34;);return-1;} jclass clz = env-& gt;find class(& # 34;com/zba Huang/led/low level/led native & # 34;);if(clz = = NULL){ ALOGE(& # 34;% s[% s:% d]JNI:env-& gt;FindClass错误& # 34;、__func__、__FILE__、_ _ LINE _ _);return-1;} ret = env-& gt;RegisterNatives(clz,led_jni_methods,sizeof(led _ JNI _ methods)/sizeof(led _ JNI _ methods[0]);if(ret & lt;0){ ALOGE(& # 34;% s[% s:% d]JNI:env-& gt;RegisterNatives错误\ n & # 34、__func__、__FILE__、_ _ LINE _ _);return-1;}返回JNI _版本_ 1 _ 4;}Android.mk

LOCAL _ PATH:= $(call my-dir)include $(CLEAR _ VARS)LOCAL _ MODULE _ TAGS:= option allocal _ MODULE:= lib led _ JNI . cpplocal _ SHARED _ LIBRARIES:= \ libutils liblogLOCAL _ C _ INCLUDES+= \执行$(JNI _ h _ include)include $(build _ SHARED _ library)后:mmmmmytest/led _ JNI/,会生成一个动态库并放入out/target/product/MSM 8911

把这个库推送到平板电脑上,就可以通过这个库调用驱动了。

内核的驱动文件:kernel/drivers/input/misc/led . c

/*1.头文件*/# include;val,buf,count);if(ret & gt;0){ printk(KERN _ ERR & # 34;zb庄###从用户复制失败!\ n & # 34);返回ret} if(s5pv _ led _ dev-& gt;Val) {/*点亮LED *//* GPC 0dat | = ((0x1表示如果分配不成功,则休眠*/s5pv _ LED _ dev = kmalloc(sizeof(structed LED _ device),GFP _ kernel);如果(!s5pv _ led _ dev){ printk(KERN _ ERR & # 34;zbzhuang对malloc没有记忆!\ n & # 34);ret =-eno mem;goto out _ err _ 1;} /*3.construct cdev structure */setup _ led _ cdev();/*4.创建设备文件*/* * param 1:struct class * * param 2:parent class,一般为null * * param 3:dev _ t-->表示一个设备号,是一个无符号的32位整数* *其中高12位为主设备号,低20位为从设备号* *如何操作设备号:MKDEV(major,minor)根据主设备号和从设备号组成一个设备号*/s5pv _ led _ dev-& gt;led _ class = class _ create(THIS _ MODULE,& # 34;led _ class & # 34);if(IS _ ERR(s5pv _ led _ dev-& gt;{ printk(KERN _ ERR & # 34;led_class的zb庄class_create()失败\ n & # 34);ret =-EINVAL;goto out _ err _ 2;} s5pv _ led _ dev-& gt;led _ device = device _ create(s5pv _ led _ dev-& gt;led_class,NULL,MKDEV(led_major,0),NULL,& # 34;led1 & # 34);//创建设备文件/dev/led1f(is _ err(s5pv _ led _ dev-->;led _ device)){ printk(KERN _ ERR & # 34;led_device的zb庄device_create失败\ n & # 34);ret =-eno dev;goto out _ err _ 3;}返回0;out _ err _ 3:class _ destroy(s5pv _ led _ dev-& gt;led _ class);out _ err _ 2:cdev _ del(s5pv _ led _ dev-& gt;led _ cdev);kfree(s5pv _ led _ dev);out _ err _ 1:unregister _ chr dev _ region(MKDEV(led _ major,0),1);返回ret}/*3.实现模块卸载函数*/static void _ _ exit led _ exit(void){ unregister _ chrdev _ region(mkdev(led _ major,0),1);device _ destroy(s5pv _ led _ dev-& gt;led_class,MKDEV(led_major,0));class _ destroy(s5pv _ led _ dev-& gt;led _ class);cdev _ del(s5pv _ led _ dev-& gt;led _ cdev);kfree(s5pv _ led _ dev);}/*4.模块许可声明*/模块_初始化(led _ init);模块_出口(led _出口);模块许可证(& # 34;GPL & # 34);修改kconfig和makefile,并添加:

生成文件

kconfig:

修改此文件以将驱动程序编译到内核中:kernel/arch/arm 64/configs/MSM _ def config和msm-perf_deconfig。

之后使用adb工具将重新编译的boot.imge镜像重新烧录就可以了啊。然后用adb工具重新刻录重新编译的boot.imge镜像。

查看日志的输出以验证结果:

Android studio查看日志结果:

Adb查看日志结果:

从app到jni再到内核,整个调用过程是成功的。

如果打开设备出现故障,只需在system/core/rootdir/uevent.rc中添加设备节点的权限777即可。

觉得好,就给我一点支持。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/399101.html

发表回复

登录后才能评论