热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【转】Android应用程序:(jni方式)控制LED/GPIO

GPIO的英文全称General-PurposeInputOutputPorts,中文意思是通用IO端口。在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路&

GPIO的英文全称General-Purpose Input /Output Ports,中文意思是通用I/O端口。
在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CPU控制,有的需要CPU提供输入信号搜索。并且,许多设备或电路只要求有开/关两种状体就够了,比如LED的亮与灭。对这些设备的控制,使用传统的串口或者并口就显得比较复杂,所以,在嵌入式微处理器上通常提供了一种“通用可编程I/O端口”,也就是GPIO。

一个GPIO端口至少需要两个寄存器,一个做控制用的“通用IO端口控制寄存器”,还有一个是存放数据的“通用I/O端口数据寄存器”。数据寄存器的每一位是和GPIO的硬件引脚对应的,而数据的传递方向是通过控制寄存器设置的,通过控制寄存器可以设置每一位引脚的数据流向。
(GPIO相关的寄存器有,IOPIN、IOSET、IOCLR、IODIR四个寄存器。)



转自20140419:Android应用程序:(jni方式)控制LED/GPIO
可借鉴Android应用层操作GPIO
Android应用程序:(jni方式)控制LED/GPIO

1.新建eclipse项目

这里写图片描述
这里写链接内容
这里写图片描述

2.在led.java中加入public static native int led(int i, int j);

led.java:

package com.example.led; import android.os.Bundle;
import android.app.Activity;
import android.view.Menu; public class LED extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.led); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.led, menu); return true; } "color:#ff6666;">public static native int led(int i, int j);
}

3.编译项目文件,bin目录下会生成led.apk.

4.终端进入项目目录,新建jni目录
这里写图片描述

5.利用javah命令生成头文件,该头文件中包含了符合jni格式的函数名,

javah -classpath bin/classes -d jni com.example.led.LED
这里写图片描述

6.jni目录下新建led.c

此c程序实际上是linux下的LED测试程序,函数入口更换为上面javah生成的函数名,以便java调用.

#include
#include
#include
#include
#include
#include
#include #define LOG_TAG "LED" //android logcat
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__ )
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS_ _) //int main(int argc, char **argv)
jint JNICALL Java_com_example_led_Led_led(JNIEnv *env, jclass thiz, jint led_nu, jint on)
{ int fd; fd &#61; open("/dev/leds0", O_RDWR); if(fd <0) printf("Can&#39;t open /dev/leds!\n"); ioctl(fd, on, led_nu); LOGI("led_nu&#61;%d,state&#61;%d\n", led_nu, on); close(fd); return 0;
}

7.在jni目录下新建Andorid.mk [实际上是为led.c编写makefile]

Android.mk

LOCAL_PATH :&#61; $(call my-dir)
include $(CLEAR_VARS)
LIB_PATH :&#61; $(LOCAL_PATH)/../../libs/armeabi
LOCAL_MODULE :&#61; ledLOCAL_SRC_FILES :&#61; \led.c
LOCAL_C_INCLUDES :&#61; $(MY_ANDROID_SOURCE)/frameworks/base/core/jni/android/graphics \ LOCAL_ARM_MODE :&#61; arminclude $(BUILD_SHARED_LIBRARY)

8.还在写一个Application.mk

APP_PLATFORM :&#61; android-9APP_ABI :&#61; armeabi-v7a

用ndk-build编译生成so库
这里写图片描述

9.回到eclipse中,将生成的so库添加进led.java中

led.java:

package com.example.led; import android.os.Bundle;
import android.app.Activity;
import android.view.Menu; public class LED extends Activity { &#64;Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.led); } &#64;Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.led, menu); return true; } public static native int led(int i, int j); static { System.loadLibrary("LED"); }
}

10.修改布局,在led.xml中为界面添加按钮

res –> layout –> led.xml:

<LinearLayout xmlns:android&#61;"http://schemas.android.com/apk/res/android" xmlns:tools&#61;"http://schemas.android.com/tools" android:layout_width&#61;"fill_parent" android:layout_height&#61;"fill_parent" android:orientation&#61;"vertical" > <ToggleButton android:id&#61;"&#64;&#43;id/btn1" android:layout_width&#61;"140dip" android:layout_height&#61;"wrap_content" android:textOn&#61;"led1 on" android:textOff&#61;"led1 off" android:layout_gravity&#61;"center_horizontal" /> <ToggleButton android:id&#61;"&#64;&#43;id/btn2" android:layout_width&#61;"140dip" android:layout_height&#61;"wrap_content" android:textOn&#61;"led2 on" android:textOff&#61;"led2 off" android:layout_gravity&#61;"center_horizontal" /> <ToggleButton android:id&#61;"&#64;&#43;id/btn3" android:layout_width&#61;"140dip" android:layout_height&#61;"wrap_content" android:textOn&#61;"led3 on" android:textOff&#61;"led3 off" android:layout_gravity&#61;"center_horizontal" /> <ToggleButton android:id&#61;"&#64;&#43;id/btn4" android:layout_width&#61;"140dip" android:layout_height&#61;"wrap_content" android:textOn&#61;"led4 on" android:textOff&#61;"led4 off" android:layout_gravity&#61;"center_horizontal" /> LinearLayout>

11.在led.java中添加监听按键代码(最终的led.java)

package com.example.led; import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ToggleButton;
import android.util.Log;
import android.widget.CompoundButton.OnCheckedChangeListener; public class Led extends Activity { private static final String TAG &#61; "LED"; private ToggleButton button1; private ToggleButton button2; private ToggleButton button3; private ToggleButton button4; &#64;Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.led); Log.w(TAG,"layout"); button1 &#61; (ToggleButton)findViewById(R.id.btn1); button2 &#61; (ToggleButton)findViewById(R.id.btn2); button3 &#61; (ToggleButton)findViewById(R.id.btn3); button4 &#61; (ToggleButton)findViewById(R.id.btn4); Log.w(TAG,"button"); button1.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button1.isChecked()) { Log.w(TAG,"----led1 on"); led(0, 1); } else { Log.w(TAG,"----led1 off"); led(0, 0); } } }); button2.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button2.isChecked()) { Log.w(TAG,"----led2 on"); led(1, 1); } else { Log.w(TAG,"----led2 off"); led(1, 0); } } }); button3.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button3.isChecked()) { Log.w(TAG,"----led3 on"); led(2, 1); } else { Log.w(TAG,"----led3 off"); led(2, 0); } } }); button4.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button4.isChecked()) { Log.w(TAG,"----led4 on"); led(3, 1); } else { Log.w(TAG,"-----led4 off"); led(3, 0); } } }); } public static native int led(int i, int j); static { System.loadLibrary("LED"); } }

12.编译整个项目,在bin目录下生成led.apk, 拷贝到开发板中就可以安装运行了.

注意:安装led.apk前,请先加载led.ko模块,并确认编译模块所用的内核版本和android版本一至.另外,还需要通过串口修改 /dev/leds0 的权限为 777.(chmod 777 /dev/leds0),否则led.c中的open(“/dev/leds0”, o_RDWR)会失败.


推荐阅读
  • 在Kohana 3框架中,实现最优的即时消息显示方法是许多开发者关注的问题。本文将探讨如何高效、优雅地展示flash消息,包括最佳实践和技术细节,以提升用户体验和代码可维护性。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • ButterKnife 是一款用于 Android 开发的注解库,主要用于简化视图和事件绑定。本文详细介绍了 ButterKnife 的基础用法,包括如何通过注解实现字段和方法的绑定,以及在实际项目中的应用示例。此外,文章还提到了截至 2016 年 4 月 29 日,ButterKnife 的最新版本为 8.0.1,为开发者提供了最新的功能和性能优化。 ... [详细]
  • 本文探讨了 Java 中 Pair 类的历史与现状。虽然 Java 标准库中没有内置的 Pair 类,但社区和第三方库提供了多种实现方式,如 Apache Commons 的 Pair 类和 JavaFX 的 javafx.util.Pair 类。这些实现为需要处理成对数据的开发者提供了便利。此外,文章还讨论了为何标准库未包含 Pair 类的原因,以及在现代 Java 开发中使用 Pair 类的最佳实践。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 并发编程入门:初探多任务处理技术
    并发编程入门:探索多任务处理技术并发编程是指在单个处理器上高效地管理多个任务的执行过程。其核心在于通过合理分配和协调任务,提高系统的整体性能。主要应用场景包括:1) 将复杂任务分解为多个子任务,并分配给不同的线程,实现并行处理;2) 通过同步机制确保线程间协调一致,避免资源竞争和数据不一致问题。此外,理解并发编程还涉及锁机制、线程池和异步编程等关键技术。 ... [详细]
  • 在前文探讨了Spring如何为特定的bean选择合适的通知器后,本文将进一步深入分析Spring AOP框架中代理对象的生成机制。具体而言,我们将详细解析如何通过代理技术将通知器(Advisor)中包含的通知(Advice)应用到目标bean上,以实现切面编程的核心功能。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
author-avatar
勉情于你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有