Android底层驱动开发记录:01_JNI
最近项目中需要用到了Android底层的开发,正好疫情居家所以又把韦老师的老教程第四期Android教程翻出来学习学习,手边也没有合适的板子,找了一块AIO-3288C的板子接了一块HDMI的屏来用。本来之前一直做单片机的,因此学起来还比较吃力,所以这里做一些记录,以备以后查看。
1. java学习,基本上跟着走了一遍,无波澜。C++因为会一点点就暂时跳过了,不行回来再补吧。
2. AIO-3288C环境搭建,最好是有一台真机 4G以上内存,硬盘至少100G,我这虚拟机空间有限编译不能通过,最后拿出很久之前买的腾讯云,Ubuntu18+2G内存+设置虚拟16G内存+100G硬盘,这个配置是偏低的但勉强用能编译SDK能通过。环境搭建上主要是open-7-jdk比较麻烦,可以参考我另一篇文章。最后达成结果就是,固件能完成RK3288C刷机,能Android studio联调app;mobaxterm ssh sftp获取云服务器资源调试源码(试图在腾讯云上装samba来着,很麻烦,放弃了);串口可以打印RK3288C启动日志;使用Android studio自带的adb设置一下环境变量用来adb调试RK3288C。
3. 开始敲代码吧。
(1)做一个APP,3288真机仿真一下,没难度,跟着做就好了。
package com.example.app_0001_leddemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import com.example.hardlibrary.*;public class MainActivity extends AppCompatActivity {private boolean ioonoff=false;private Button button=null;private CheckBox checkBox_io1=null;private CheckBox checkBox_io2=null;private CheckBox checkBox_io3=null;private CheckBox checkBox_io4=null;public void onCheckboxClicked(View view) {boolean checked= ((CheckBox)view).isChecked();switch (view.getId()){case R.id.checkbox_io1:if(checked){Toast.makeText(getApplicationContext(), "checkbox1 on ",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(0,1);}else {Toast.makeText(getApplicationContext(), "checkbox1 off",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(0,0);}break;case R.id.checkbox_io2:if(checked){Toast.makeText(getApplicationContext(), "checkbox2 on ",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(1,1);}else {Toast.makeText(getApplicationContext(), "checkbox2 off",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(1,0);}break;case R.id.checkbox_io3:if(checked){Toast.makeText(getApplicationContext(), "checkbox3 on ",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(2,1);}else {Toast.makeText(getApplicationContext(), "checkbox3 off",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(2,0);}break;case R.id.checkbox_io4:if(checked){Toast.makeText(getApplicationContext(), "checkbox4 on ",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(3,1);}else {Toast.makeText(getApplicationContext(), "checkbox4 off",Toast.LENGTH_SHORT).show();HardCtrl.ioCtrl(3,0);}break;}}class MyButtonListener implements View.OnClickListener{@Overridepublic void onClick(View v) {//HardCtrl hardCtrl = new HardCtrl();ioonoff = !ioonoff;if(ioonoff==true){button.setText("ALL OFF");checkBox_io1.setChecked(true);checkBox_io2.setChecked(true);checkBox_io3.setChecked(true);checkBox_io4.setChecked(true);for(int i=0;i<4;i++)HardCtrl.ioCtrl(i,1);}else {button.setText("ALL ON");checkBox_io1.setChecked(false);checkBox_io2.setChecked(false);checkBox_io3.setChecked(false);checkBox_io4.setChecked(false);for(int i=0;i<4;i++)HardCtrl.ioCtrl(i,0);}}}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);HardCtrl.ioOpen();button = (Button)findViewById(R.id.bottom_id1);checkBox_io1 = (CheckBox)findViewById(R.id.checkbox_io1);checkBox_io2 = (CheckBox)findViewById(R.id.checkbox_io2);checkBox_io3 = (CheckBox)findViewById(R.id.checkbox_io3);checkBox_io4 = (CheckBox)findViewById(R.id.checkbox_io4);button.setOnClickListener(new MyButtonListener());
// button.setOnClickListener(new View.OnClickListener() {
// public void onClick(View v) {
// // Code here executes on main thread after user presses button
//
// ioonoff = !ioonoff;
// if(ioonoff==true){
// button.setText("ALL ON");
// }else {
// button.setText("ALL OFF");
// }
// }
// });}
}
(2)app加载jni部分,也没什么难度。
package com.example.hardlibrary;public class HardCtrl{public static native int ioCtrl(int which,int status);public static native int ioOpen();public static native void ioClose();static {try {System.loadLibrary("hardctrl");} catch (Exception e) {e.printStackTrace();}}
}
(3)JNI部分,这部分稍微麻烦一些。完成c代码编写是第一步,第二步在我的腾讯云(TXY)上安装arm-linux-gcc 4.3.2(其他的交叉编译工具好像是有些问题搞这个),并编译jni c代码命令如下,
arm-linux-gcc -fPIC -shared hardctrl.c -o libhardctrl.so -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -nostdlib /home/ubuntu/firefly_rk3288_android5.1/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/libc.so -I /home/ubuntu/firefly_rk3288_android5.1/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/include/ /home/ubuntu/firefly_rk3288_android5.1/prebuilts/ndk/9/platforms/android-14/arch-arm/usr/lib/liblog.so
没有-nostdlib 编译可以通过但调试会奔溃,因为libc的依赖库不对,可以用ldd xxx.so 查看库依赖。第三步编译好的so库放在app目录下app/libs中。第四步配置Android studio的app工程libs的路径,主要是sourceSets 和debug,好了可以调试仿真了。
sourceSets {main {jniLibs.srcDirs = ['libs']}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}debug {ndk {abiFilters "armeabi","x86"}}}
此时, 只是app上能点击IO开关了,还没有深入到硬件呢。下面是jni主要的代码。
static const JNINativeMethod methods[] = {{"ioOpen", "()I", (void *)ioopen},{"ioClose", "()V", (void *)ioclose},{"ioCtrl", "(II)I", (void *)ioctrl},
};/* System.loadLibrary */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{JNIEnv *env;jclass cls;if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {return JNI_ERR; /* JNI version not supported */}cls = (*env)->FindClass(env, "com/example/hardlibrary/HardCtrl");if (cls == NULL) {return JNI_ERR;}/* 2. map java hello <-->c c_hello */if ((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])) < 0)return JNI_ERR;return JNI_VERSION_1_4;
}
(4)RK3288c开发板IO驱动编写,这个麻烦就大一些了。 按照其官网维基并结合正点教程完成了驱动。但jni open这个驱动却出现问题,纠其原因是该驱动 权限不足,导致jni open不了,这里找到两个办法解决,
① adb root,chmod 777 /dev/xxx 重启后无效
②可以在ueventd.rc中赋权比如:system/core/rootdir/ueventd.rc,
/dev/tty* | 0777 | root | system |
设备节点 | 修改权限 | 该节点的用户 | 所属的组 |
修改完成后,使用make bootimage 编译命令 会更新ramdisk.img,boot.img, ueventd.rc
这一阶段的测试就到这里,源码在这里:https://download.csdn.net/download/bwolf1986/85473568?spm=1001.2014.3001.5501
Android底层驱动开发记录:01_JNI相关推荐
- 实现Android底层驱动开发并裁剪定制Android操作系统
毕业论文 题 目实现Android底层驱动开发并裁剪定制Android操作系统 学 院电子信息与电气工程学院 姓 名牛xxx民 专 业电子信息科学与技术 学 号2012xxxxxx ...
- Android底层驱动开发 -驱动配置篇
Android底层驱动开发 -驱动配置篇## 所需要的硬件及软件资源 一块Android开发板(我用的是Firefly-AIO-3288J) 开发板的系统源码 一台运行Linux系统的主机(虚拟机也行 ...
- Android 底层驱动开发步骤——linux内核层、HAL层、JNI层
1.Linux驱动实现 2.Linux内核驱动测试 3.Android HAL层实现 4.Aidl实现 5.Service java实现 6.Service jni 实现 7.注册service和jn ...
- Android底层驱动开发(四)
目录 一.Android源码编译 编译原理 编译组成 原生Android编译 二.Makefile文件 三.Android.mk文件
- Android底层驱动开发(十一)
目录 一.WiFi开发流程 二.计算机网络 (一)HTTP报文格式 (二)TCP报文格式
- 免费分享:5本安卓开发经典书籍,Android 7编程入门经典(第4版),Android底层驱动分析和移植,底层驱动分析和移植
1.Android 7编程入门经典(第4版) 使用Android Studio 2 PDF 下载 下载地址: http://www.askwinds.com/r-c/down-info-02/579 ...
- Linux GPIO键盘驱动开发记录_OMAPL138
Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...
- 嵌入式入门学习笔记4:[转]什么是嵌入式底层驱动开发和嵌入式底层软件开发...
我们知道嵌入式操作系统(Embedded System)是指以应用为中心.以计算机技术为基础,软件硬件可裁剪.适应应用系统对功能.可靠性.成本.体积.功耗严格要求的专用计算机系统.嵌入式开发分两种,一 ...
- linux底层驱动内核,Linux底层驱动开发需要学习哪些内容
Linux底层驱动开发需要学习哪些内容想必这是很多学习Linux的朋友十分头疼的问题,今天就让我来告诉大家我们到底该学习哪些内容呢? 1. 要会一些硬件知识,比如Arm接口编程 2. 学会写简单的ma ...
最新文章
- OpenCV代码提取:遍历指定目录下指定文件的实现
- 使用Apache Tiles3.x构建界面布局(一)
- js base64 编码解码
- Oracle获取LOB长度的两种方法效率对比
- 均线带角度的指标_选股指标:均线角度并列向上,量能倍增飞扬趋势明显,短线操作可考虑...
- 微信小程序实战开发视频
- python爬虫之路--准备环境
- Mysql学习总结(62)——MySQL连接com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link问题
- 根据深度优先算法(DFS)和标记数组求全排列
- sql与mysql数据对接_SQL Server 对接MySQL 数据库
- Asterisk G729编码支持
- linux 加入域 命令,Linux 加入域的最终完整版修改
- linux挂载iso5后如何安装,CentOS系统怎样挂载光盘镜像ISO文件
- for(int num:nums)
- 阿里云telnet 3306端口失败
- bgproperties属性
- Lory Carousel滑块具有CSS动画和触摸支持
- 周末作业-循环练习题(2)
- CSGO DIY-小地图修改
- java/php/net/python学生社团管理系统设计
热门文章
- 关于FME的Beijing54及Xian80坐标系
- 程序员必会的十步快速学习法(附书单)
- java毕业设计企业人事信息管理mybatis+源码+调试部署+系统+数据库+lw
- 科视Christie HS系列激光投影机为江苏园博园的夜晚增添亮丽风景线
- ICOM IC-F26 使用MDC信令“蛙叫”及SQL设置
- 初识Java调用百度API实现图像识别
- android 自动更新 覆盖安装后 自动启动的问题
- 蓝牙WiFi 智能手机无线打印全攻略
- 速读《现代软件工程----构建之法》有感
- android面试(个人)简历