上一篇写了一个oled驱动,那么现在有一个问题:apk要怎么使用这个硬件,这里就需要提供一个硬件服务,apk通过这个服务就可以操作到硬件了。
基于rk3288 Android5.1

Android的硬件访问框架
1、loadLibrary 加载硬件
2、JNIOnload 注册本地方法
分别调用各个硬件的函数来注册本地方法
{
LED
振动器
串口
}
3、SystemServer对每一个硬件:构造Service、addService
4、APP怎么使用?
获得服务:getService
使用服务:执行Service方法
具体步骤:
1、实现JNI和HAL文件
对于oeld,写一个com_android_server_NoyaManager.cpp,注册一个JNI本地方法,在hal_oled.c文件里面调用:open,read,write。

   static const JNINativeMethod methods[] = {{"native_oled_close", "()V", (void *)oled_close},{"native_oled_init", "()I", (void *)oled_init},{"native_oled_clear", "()I", (void *)oled_clear},  {"native_oled_display", "(IILjava/lang/String;)I", (void *)oled_display},       };int register_android_server_NoyaManager(JNIEnv *env){return jniRegisterNativeMethods(env, "com/android/server/noya/NoyaManagerServiceImpl",methods, NELEM(methods));}

2、修改onload.cpp,让他调用com_android_server_NoyaManager.cpp实现的函数

int register_android_server_NoyaManager(JNIEnv *env);

3、修改SystemServer.java:

mSystemServiceManager.startService(”noya_service“);

4、 NoyaManagerServiceImpl.java 、 NoyaManagerService.java:实现本地方法
在NoyaManagerService里面new一个NoyaManagerServiceImpl对象,以后就通过这个对象操作oled

public final class NoyaManagerService extends SystemService {private static final String TAG = "NoyaManagerService";final NoyaManagerServiceImpl mImpl;public NoyaManagerService(Context context) {super(context);mImpl = new NoyaManagerServiceImpl(context);}@Overridepublic void onStart() {Log.i(TAG, "Registering service " + Context.NOYA_SERVICE);publishBinderService(Context.NOYA_SERVICE, mImpl);}@Overridepublic void onBootPhase(int phase) {if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {mImpl.start();}}
}

服务的具体实现类部分

public class NoyaManagerServiceImpl extends INoyaManager.Stub {private static final String TAG = "NoyaManagerServiceImpl";public int oled_init() throws android.os.RemoteException{return native_oled_init(); }public int oled_clear(int page) throws android.os.RemoteException{return native_oled_clear();  }public int oled_display(int page, int col, java.lang.String str) throws android.os.RemoteException{return native_oled_display(page, col, str);     }public void oled_close() throws android.os.RemoteException{native_oled_close();}public static native int native_oled_init();public static native int native_oled_clear();public static native int native_oled_display(int page, int col, java.lang.String str);public static native void native_oled_close();public void start() {Log.i(TAG, "Starting NoyaManager Service");HandlerThread handlerThread = new HandlerThread("NoyaManagerServiceThread");handlerThread.start();}
}

5、INoyaManager.java:接口文件,由INoyaManager.aidl文件提供,自动生成的文件,给APP使用

interface INoyaManager {void reboot(boolean confirm,String reason);int oled_init();int oled_clear(int page);int oled_display(int page, int col, String str);void oled_close();}

6、NoyaManager.java:在里面通过INoyaManager.java的接口调用服务。

public class NoyaManager {private static String TAG = "NoyaManager";INoyaManager mNoyaManager;private Context context;public NoyaManager(Context ctx,INoyaManager noyaManager) {mNoyaManager = noyaManager;context = ctx;}public int oled_init(){int ret = -1;try {ret = mNoyaManager.oled_init();} catch (RemoteException e) {}return ret;}public int oled_clear(int page){int ret = -1;try {ret = mNoyaManager.oled_clear(page);} catch (RemoteException e) {}return ret;}public int oled_display(int page, int col, String str){int ret = -1;try {ret = mNoyaManager.oled_display(page, col, str);} catch (RemoteException e) {}return ret;}public void oled_close(){try {mNoyaManager.oled_close();} catch (RemoteException e) {}}}

使用时:

NoyaManager mNoyaManager = (NoyaManager)mContext.getSystemService("noya_service");
mNoyaManager.oled_init();

权限问题:
对于新增加的设备节点,默认是没有访问权限的,所以必须要添加相应的权限:
在SElinux下,如何获得对一个内核节点的访问权限
android/external/sepolicy/file_contexts 添加

/dev/oled               u:object_r:oled_device:s0

android/external/sepolicy/device.te 添加

 type oled_device, dev_type, mlstrustedobject;

android/external/sepolicy/untrusted_app.te 添加

allow untrusted_app oled_device:chr_file rw_file_perms;

device/rockchip/common/sepolicy/service_contexts 添加

noya_service               u:object_r:system_server_service:s0

system/core/rootdir/ueventd.rc 这个文件修改后需要重新编译,或者只需要修改out/target/produt/xxx/root/ueventd.rc 添加

/dev/oled                 0666   root       root

调试时出现的问题:

shell@firefly:/ # [ 625.582296] type=1400 audit(1293885273.400:14): avc: denied { read write } for pid=1114 comm=“Binder_B” name=“oled” dev=“tmpfs” ino=1270 scontext=u:r:system_server:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
[ 625.582313] drivers/spi/rk_spi_oled_drv.c, oled_ioctl, 139, cmd=0x00100001, arg=0xa93840d8
[ 625.582402] Division by zero in kernel.
[ 625.582426] CPU: 3 PID: 24 Comm: ksoftirqd/3 Tainted: P 3.10.0 #43
[ 625.582467] [] (unwind_backtrace+0x0/0xe0) from [] (show_stack+0x10/0x14)
[ 625.582497] [] (show_stack+0x10/0x14) from [] (Ldiv0+0x8/0x10)
[ 625.582526] [] (Ldiv0+0x8/0x10) from [] (pump_transfers+0x4c/0x690)
[ 625.582555] [] (pump_transfers+0x4c/0x690) from [] (tasklet_action+0x80/0xe0)
[ 625.582580] [] (tasklet_action+0x80/0xe0) from [] (__do_softirq+0x144/0x2b4)
[ 625.582605] [] (__do_softirq+0x144/0x2b4) from [] (run_ksoftirqd+0x30/0x78)
[ 625.582632] [] (run_ksoftirqd+0x30/0x78) from [] (smpboot_thread_fn+0x22c/0x234)
[ 625.582662] [] (smpboot_thread_fn+0x22c/0x234) from [] (kthread+0xa0/0xac)
[ 625.582692] [] (kthread+0xa0/0xac) from [] (ret_from_fork+0x14/0x3c)
[ 625.582709] MRST SPI0: unsupportedfreq: 48000000Hz
spi设备支持的最大频率设置错误,该成datesheet里的典型值即可

JNI文件里的oled_clear的参数没有传进去,后来发现是本地方法定义了无参的函数

JNI文件
{“native_oled_clear”, “()I”, (void *)oled_clear},
改为
{“native_oled_clear”, “(I)I”, (void *)oled_clear},

基于spi接口的oled屏Android服务框架相关推荐

  1. STM32基于SPI接口的OLED数据显示

    文章目录 一.SPI简介 1.1 什么是SPI 1.2 SPI原理 1.3 SPI的连接方式 1.4 协议层 二.OLED 2.1 OLED原理 2.2 点阵编码原理与显示 三.OLED显示实验 3. ...

  2. STM32开发基于SPI接口的OLED数据显示

    文章目录 一.SPI简介 二.0.96inch SPI OLED 介绍 三.实验内容及结果 1. 任务要求 2. 准备工作 3. 演示如下 四.参考 一.SPI简介 SPI,是英语Serial Per ...

  3. 基于SPI接口的OLED数据显示

    文章目录 一.实验目的 二.准备工作 三.理论基础 1.0.96OLED简介 2.接线说明 四.实验步骤 1.显示自己的学号和姓名 2.显示AHT20的温度和湿度 3.上下或左右的滑动显示长字符 一. ...

  4. 基于SPI方式实现OLED屏显

    文章目录 一.SPI简介 1.1物理层 1.2协议层 二.OLED 2.1定义 2.2优势 2.3模块工作模式选择 2.4模块特点 三.实验过程 3.1实验准备 3.2硬件连接 3.3程序烧录 3.3 ...

  5. 基于SPI通信方式的OLED显示

    基于SPI通信方式的OLED显示 文章目录 基于SPI通信方式的OLED显示 1.SPI简介 2.OLED屏幕介绍 3.OLED显示屏显示数据 4.总结 5.参考文献 1.SPI简介 SPI 协议是由 ...

  6. 【嵌入式】MCU(HC32F460)+SPI接口LCD液晶屏ILI9341 移植emWin记录1----点亮LCD屏

    目录 一 SPI屏的接线 二 SPI屏驱动初始化 三 SPI屏点亮 四 附录 一 SPI屏的接线 SPI屏的特点在于接线简单,只需要四根SPI线以及几个GPIO口即可驱动工作,但是由于非并口的,所以当 ...

  7. FPGA实现的SPI协议(二)----基于SPI接口的FLASH芯片M25P16的使用

    写在前面 SPI协议系列文章: FPGA实现的SPI协议(一)----SPI驱动 FPGA实现的SPI协议(二)----基于SPI接口的FLASH芯片M25P16的使用 在上篇文章,简要介绍了SPI协 ...

  8. STM32Mini基于SPI接口的0.96寸OLED屏数据显示

    文章目录 一.实验资料准备 1.下载工程包 2.引脚接法 3.字模软件准备 4.了解SPI(串行外设接口) (1)SPI的定义 (2)SPI的连接方式 (3)SPI的通讯过程 5.了解OLED屏的滚屏 ...

  9. STM32通过SPI协议驱动OLED屏

    坚持就是胜利 一.SPI协议介绍 01 简介 02 SPI物理层 03 SPI基本通讯过程 二.OLED显示器介绍 01 简介 02 接口定义 03 与STM32接线图 三.汉字取模软件介绍 01 下 ...

最新文章

  1. antd 验证 动态 required_3分钟短文:十年窖藏,Laravel告诉你表单验证的正确姿势
  2. mybatis一级缓存命中条件
  3. UVA 10453—— Make Palindrome
  4. 【汇编语言】汇编语言如何编程,如何避免出错
  5. 求数组中数对的最大值
  6. java web 应用技术与案例教程_《Java Web应用开发技术与案例教程》怎么样_目录_pdf在线阅读 - 课课家教育...
  7. 修改mediapipe中绘制pose的三维坐标函数,将PLT格式转成CV2格式,实时显示
  8. 等差素数列 蓝桥杯 python
  9. 怎样开始买基金---我的基金购买体验[转]
  10. 卡斯卡迪亚社区建设者奖:2017年获胜者公布
  11. SOLO代码踩过的各种坑
  12. BJDCTF_2nd PWN复盘
  13. linux 卸载windows系统服务,如何卸载windows系统
  14. 企业视频远程办公会议通话系统EasyRTC在Windows2012部署运行出现“计算机中丢失VCRUNTIME140.dll”如何解决?
  15. 论文笔记 Object-Aware Instance Labeling for Weakly Supervised Object Detection - ICCV 2019
  16. 服务器端和客户端互发消息,Socket编程实现简单的服务器与客户端互发消息
  17. TensorFlow入门教程(30)车牌识别之整合EAST+DenseNet进行车牌识别(六)
  18. 图像增强(拉普拉斯锐化增强)
  19. 世界上最大的计算机硬盘,全球我最大 忆捷A600 2TB移动硬盘评测
  20. End-to-end people detection in crowded scenes

热门文章

  1. 专有网络VPC (产品简介,使用限制)
  2. 笔记本 ASUS A3E 改用Windows Server 2003 的几个问题
  3. iso3651_小而强大 11款5K内笔记本真实性能比拼
  4. java面试题:Redis常见面试题(实际面试有被问到)
  5. STM32F1系列超声波测距程序
  6. python 计算结果 nan_python中的nan是什么意思
  7. 老牌硬件钱包Trezor用户遭钓鱼攻击,攻击者或已窃取大量账户信息
  8. 浅析如何衡量程序员的生产效率
  9. c语言线程怎么退出,如何用C语言实现多线程
  10. 拆解一个居家隔离监测的无线门磁