Tiny4412 LED 硬件服务
1.Android系统中启动框架
2.首先实现驱动程序
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h> #include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h> static int led_gpios[] = {
EXYNOS4212_GPM4(),
EXYNOS4212_GPM4(),
EXYNOS4212_GPM4(),
EXYNOS4212_GPM4(),
}; static int led_open(struct inode *inode, struct file *file)
{
/* 配置GPIO为输出引脚 */
int i;
for (i = ; i < ; i++)
s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT); return ;
} /* app : ioctl(fd, cmd, arg) */
static long led_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
/* 根据传入的参数设置GPIO */
/* cmd : 0-off, 1-on */
/* arg : 0-3, which led */ if ((cmd != ) && (cmd != ))
return -EINVAL; if (arg > )
return -EINVAL; gpio_set_value(led_gpios[arg], !cmd); return ;
} static struct file_operations leds_ops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = led_open,
.unlocked_ioctl = led_ioctl, }; static int major;
static struct class *cls; int leds_init(void)
{
major = register_chrdev(, "leds", &leds_ops); /* 为了让系统udev,mdev给我们创建设备节点 */
/* 创建类, 在类下创建设备 : /sys */
cls = class_create(THIS_MODULE, "leds");
device_create(cls, NULL, MKDEV(major, ), NULL, "leds"); /* /dev/leds */ return ;
} void leds_exit(void)
{
device_destroy(cls, MKDEV(major, ));
class_destroy(cls);
unregister_chrdev(major, "leds");
} module_init(leds_init);
module_exit(leds_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.100ask.net");
放入内核 drivers/char
修改 drivers/char/Makefile,添加:
obj-y += leds_4412.o
重新编译内核
或者将其编译成模块
#Makefile
obj-m := leds_4412.o
KDIR := /home/cent/work/androidL_Tiny4412/linux-3.0.
all:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
.PHONY: clean
clean:
rm -f *.ko *.o *.mod.c *.bak *.order *.symvers *~
执行 make后 用adb push 命令将其上传到开发板的/data/local 目录,adb shell 使用 insmod 命令将驱动模块加载到内核。
3.实现HAL层
//led_hal.h #ifndef ANDROID_LED_INTERFACE_H
#define ANDROID_LED_INTERFACE_H #include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h> #include <hardware/hardware.h> __BEGIN_DECLS struct led_device_t {
struct hw_device_t common; int (*led_open)(struct led_device_t* dev);
int (*led_ctrl)(struct led_device_t* dev, int which, int status);
}; __END_DECLS #endif // ANDROID_LED_INTERFACE_H
//led_hal.c #define LOG_TAG "LedHal" /* 1. 实现一个名为HMI的hw_module_t结构体 */ /* 2. 实现一个open函数, 它返回led_device_t结构体 */ /* 3. 实现led_device_t结构体 */ /* 参考 hardware\libhardware\modules\vibrator\vibrator.c
*/ #include <hardware/vibrator.h>
#include <hardware/hardware.h> #include <cutils/log.h> #include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h> #include <hardware/led_hal.h> #include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <utils/Log.h> static int fd; /** Close this device */
static int led_close(struct hw_device_t* device)
{
close(fd);
return ;
} static int led_open(struct led_device_t* dev)
{
fd = open("/dev/leds", O_RDWR);
ALOGI("led_open : %d", fd);
if (fd >= )
return ;
else
return -;
} static int led_ctrl(struct led_device_t* dev, int which, int status)
{
int ret = ioctl(fd, status, which);
ALOGI("led_ctrl : %d, %d, %d", which, status, ret);
return ret;
} static struct led_device_t led_dev = {
.common = {
.tag = HARDWARE_DEVICE_TAG,
.close = led_close,
},
.led_open = led_open,
.led_ctrl = led_ctrl,
}; static int led_device_open(const struct hw_module_t* module, const char* id,
struct hw_device_t** device)
{
*device = &led_dev;
return ;
} static struct hw_module_methods_t led_module_methods = {
.open = led_device_open,
}; struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.id = "led",
.methods = &led_module_methods,
};
#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := led.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := led_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng include $(BUILD_SHARED_LIBRARY)
//com_android_server_LedService.cpp #define LOG_TAG "LedService" #include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h" #include <utils/misc.h>
#include <utils/Log.h> #include <stdio.h> #include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <hardware/led_hal.h> namespace android
{ static led_device_t* led_device; jint ledOpen(JNIEnv *env, jobject cls)
{
jint err;
hw_module_t* module;
hw_device_t* device; ALOGI("native ledOpen ..."); /* 1. hw_get_module */
err = hw_get_module("led", (hw_module_t const**)&module);
if (err == ) {
/* 2. get device : module->methods->open */
err = module->methods->open(module, NULL, &device);
if (err == ) {
/* 3. call led_open */
led_device = (led_device_t *)device;
return led_device->led_open(led_device);
} else {
return -;
}
} return -;
} void ledClose(JNIEnv *env, jobject cls)
{
//ALOGI("native ledClose ...");
//close(fd);
} jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
ALOGI("native ledCtrl %d, %d", which, status);
return led_device->led_ctrl(led_device, which, status);
} static const JNINativeMethod methods[] = {
{"native_ledOpen", "()I", (void *)ledOpen},
{"native_ledClose", "()V", (void *)ledClose},
{"native_ledCtrl", "(II)I", (void *)ledCtrl},
}; int register_android_server_LedService(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "com/android/server/LedService",
methods, NELEM(methods));
} }
放到Android源码frameworks/base/services/core/jni/com_android_server_LedService.cpp位置
修改frameworks/base/services/core/jni/onload.cpp
添加:
int register_android_server_Watchdog(JNIEnv* env);
+int register_android_server_LedService(JNIEnv *env);
register_android_server_VibratorService(env);
+register_android_server_LedService(env);
package android.os; /** {@hide} */
interface ILedService
{
int ledCtrl(int which, int status);
}
把 ILedService.aidl 放入 frameworks/base/core/java/android/os
package com.android.server;
import android.os.ILedService; public class LedService extends ILedService.Stub {
private static final String TAG = "LedService"; /* call native c function to access hardware */
public int ledCtrl(int which, int status) throws android.os.RemoteException
{
return native_ledCtrl(which, status);
} public LedService() {
native_ledOpen();
} public static native int native_ledOpen();
public static native void native_ledClose();
public static native int native_ledCtrl(int which, int status);
}
frameworks/base/services/java/com/android/server/SystemServer.java中注册LedService
Slog.i(TAG, "Vibrator Service");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
+Slog.i(TAG, "Led Service");
+ServiceManager.addService("led", new LedService());
package cc.icen.leddemo; import android.os.RemoteException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;
import android.os.ILedService;
import android.os.ServiceManager;
import android.util.Log; public class MainActivity extends Activity { private boolean ledon = false;
private Button button = null;
private CheckBox checkBoxLed1 = null;
private CheckBox checkBoxLed2 = null;
private CheckBox checkBoxLed3 = null;
private CheckBox checkBoxLed4 = null;
private ILedService iLedService = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.BUTTON); iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));
if(iLedService == null)
Log.d("tian","iLedService is null!!!!"); checkBoxLed1 = (CheckBox)findViewById(R.id.LED1);
checkBoxLed2 = (CheckBox)findViewById(R.id.LED2);
checkBoxLed3 = (CheckBox)findViewById(R.id.LED3);
checkBoxLed4 = (CheckBox)findViewById(R.id.LED4); button.setOnClickListener(new MyButtonListener()); } class MyButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
ledon = !ledon;
if (ledon) {
button.setText("ALL OFF");
checkBoxLed1.setChecked(true);
checkBoxLed2.setChecked(true);
checkBoxLed3.setChecked(true);
checkBoxLed4.setChecked(true); try {
for (int i = 0; i < 4; i++)
iLedService.ledCtrl(i, 1);
} catch (RemoteException e) {
e.printStackTrace();
}
}
else {
button.setText("ALL ON");
checkBoxLed1.setChecked(false);
checkBoxLed2.setChecked(false);
checkBoxLed3.setChecked(false);
checkBoxLed4.setChecked(false); try {
for (int i = 0; i < 4; i++)
iLedService.ledCtrl(i, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
} public void onCheckboxClicked(View view) {
// Is the view now checked?
boolean checked = ((CheckBox) view).isChecked(); try {
// Check which checkbox was clicked
switch(view.getId()) {
case R.id.LED1:
if (checked) {
// Put some meat on the sandwich
Log.d("tian","1");
//Toast.makeText(getApplicationContext(), "LED1 on", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(0, 1);
Log.d("tian","2");
}
else {
// Remove the meat
//Toast.makeText(getApplicationContext(), "LED1 off", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(0, 0);
}
break;
case R.id.LED2:
if (checked) {
// Put some meat on the sandwich
//Toast.makeText(getApplicationContext(), "LED2 on", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(1, 1);
}
else {
// Remove the meat
//Toast.makeText(getApplicationContext(), "LED2 off", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(1, 0);
}
break; case R.id.LED3:
if (checked) {
// Put some meat on the sandwich
//Toast.makeText(getApplicationContext(), "LED3 on", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(2, 1);
}
else {
// Remove the meat
//Toast.makeText(getApplicationContext(), "LED3 off", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(2, 0);
}
break; case R.id.LED4:
if (checked) {
// Put some meat on the sandwich
//Toast.makeText(getApplicationContext(), "LED4 on", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(3, 1);
}
else {
// Remove the meat
//Toast.makeText(getApplicationContext(), "LED4 off", Toast.LENGTH_SHORT).show();
iLedService.ledCtrl(3, 0);
}
break;
// TODO: Veggie sandwich
}
} catch (RemoteException e) {
e.printStackTrace();
}
} }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:orientation="vertical"
> <Button
android:id="@+id/BUTTON"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
/> <CheckBox
android:id="@+id/LED1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:onClick="onCheckboxClicked"
/> <CheckBox
android:id="@+id/LED2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:onClick="onCheckboxClicked"
/> <CheckBox
android:id="@+id/LED3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:onClick="onCheckboxClicked"
/> <CheckBox
android:id="@+id/LED4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:onClick="onCheckboxClicked"
/> </LinearLayout>
#Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) # Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files) # Name of the APK to build
LOCAL_PACKAGE_NAME := LEDDemo # Tell it to build an APK
include $(BUILD_PACKAGE)
android应用如何访问C库
安卓应用是由java编写的,而在android底层,如安卓底层的硬件驱动程序,都是由C/C++编写的,那应用层java是必须通过某种手段才能使用底层提供的硬件资源。毫无疑问,在java看要调用底层C实现的代码,中间必须要有一层接口,那就是JNI。本例要实现的就是JAVA如何访问底层C库。
假设JAVA应用需要实现的功能是控制底层硬件LED设备,包括开,关及控制操作。需要实现下述流程:
1 实现一个JAVA硬件控制类,声明本地的Native方法(操作硬件的接口),并使用static模块加载C的动态库。实现代码如下
public class HardControl{
//声明本地的Native方法
public static native int ledCtrl(int which, int status);
public static native int ledOpen();
public static native void ledClose(); //我们要在这个java程序里面加载C库,定义一个static模块
static {
//用System方法来加载C库
try { //添加捕获异常代码的快捷键为:ctrl+alt+T(前提先用鼠标选中需要捕获的代码)
System.loadLibrary("hardcontrol"); //参数为C库的库名
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意,加载C库的方法为System.loadLibrary.
#include <jni.h>
#include <stdio.h>
#include <stdlib.h> #include <android/log.h> /* liblog */ jint ledOpen(JNIEnv *env, jobject cls)
{ __android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native_ledOpen"); //调用这句就可以打印了。 return ;
} void ledClose(JNIEnv *env, jobject cls)
{
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native_ledClose"); //调用这句就可以打印了。 } void ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native_ledCtrl:%d %d", which, status); //调用这句就可以打印了。 return ;
} static const JNINativeMethod methods[] = {
{"ledOpen", "()I", (void *)ledOpen}, //() inside empty=> no params, 'I' means: return type is int
{"ledClose", "()V", (void *)ledClose},//() inside empty=> no params, 'V' means: return type is void
{"ledCtrl", "(II)I", (void *)ledCtrl}, //()inside two I => means two params, types is int, ouside () is 'I' ==> return type is int }; /* System.LoadLibrary */
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;
if((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) {
return JNI_ERR;; //jni version not supported
} //find the class that realize the local native method: *.java, here is HardControl
//PS:here need to indification the package & class name.
// "." --> "/"
cls = (*env)->FindClass(env, "com/example/zhm/hardlibrary/HardControl");
if( cls == NULL )
{
return JNI_ERR;
} //find the class then register their methods . Java's method <==correspond with ==> C's method
if((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[])) < ) // 3: means there are 3 funcs in methods.
{ } }
Tiny4412 LED 硬件服务的更多相关文章
- LED硬件访问服务(2)——JNI/HAL
一.系统编程 1.SystemServer.java类中提供了main()方法,说明它是以一个进程的方式存在的,启动后直接执行其run() 2.注册服务ServiceManager.addServic ...
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口(老罗学习笔记4)
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...
- Android 从硬件到应用程序:一步一步爬上去 5 -- 在Frameworks蒂姆层硬件服务
Android Frameworks层提供硬件服务,Android系统APP能够调用这些硬件服务,而硬件则完全控制.实现应有的功能.上一页下一页.为了这一个frameworks高层的应用java接口硬 ...
- Android 从硬件到应用程序:一步一步爬上去 6 -- 我写的APP测试框架层硬件服务(终点)
创Android Applicationproject:采用Eclipse的Android插入ADT创Androidproject,project名字Gpio,创建完成后,project文件夹pack ...
- nios II--实验2——led硬件部分
Led 硬件开发 新建原理图 1.打开Quartus II 11.0,新建一个工程,File -> New Project Wizard…,忽略Introduction,之间单击 Next> ...
- 在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务(老罗学习笔记6)
一:Eclipse下 1.创建工程: ---- 2.创建后目录 3.添加java函数 4.在src下创建package,在package下创建file 5.res---layout下创建xml文件,命 ...
- 添加service到SystemService硬件服务
添加service到SystemService: 添加硬件服务. 创建时间:2015年3月9日(星期一) 晚上11:07 | 分类:硬件驱动Android | 天气: 修改时间:2015年3月10日( ...
- 为Android系统内置Java应用程序测试Application Frameworks层的硬件服务
我们在Android系统增加硬件服务的目的是为了让应用层的APP能够通过Java接口来访问硬件服务.那么, APP如何通过Java接口来访问Application Frameworks层提供的硬件服务 ...
- 为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接 口.实现这两者的目的是为了向更上一层提供硬件访问接口,即 ...
随机推荐
- SM30维护视图创建【转】
在SAP中,经常需要自定义数据库表.而且可能需要人工维护数据库表中的数据,可以通过SM30进行维护数据:但是SM30事务的权限太大,不适宜将SM30直接分配:因此,可以通过给维护表分配事 ...
- CodeBackUP_node_find_serial
/*************************************************************** ** Find the serial number Node ** R ...
- LeetCode:贪婪算法
LeetCode:贪婪算法 贪婪算法基础 我 717. 1-bit and 2-bit Characters class Solution { public boolean isOneBitChara ...
- hid_info函数分析
昨天博文<linux下无线鼠标驱动执行流程>中有一行输出信息很让我迷惑,如下所示: [ :1D57: Mouse [HID Wireless Mouse HID Wireless Mous ...
- linux 下载rpm包到本地,createrepo:创建本地YUM源
如何下载rpm包到本地 设置yum安装时,保留rpm包. 1.编辑 /etc/yum.conf 将keepcache的值设置为1; 这样就可以将yum安装时的rpm包保存在 /var/cache/yu ...
- 常用连续型分布介绍及R语言实现
常用连续型分布介绍及R语言实现 R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大. R语言作为统计学一门语言,一直在小众领域闪耀着光芒.直到大数 ...
- vps 虚拟机 云服务器
vps :wxmp 03服务器 虚拟主机: 万网免费主机 云服务器:wxmp阿里云
- 一个基于特征向量的近似网页去重算法——term用SVM人工提取训练,基于term的特征向量,倒排索引查询相似文档,同时利用cos计算相似度
摘 要 在搜索引擎的检索结果页面中,用户经常会得到内容相似的重复页面,它们中大多是由于网站之间转载造成的.为提高检索效率和用户满意度,提出一种基于特征向量的大规模中文近似网页检测算法DDW(Det ...
- Vue从接口请求数据
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
- javascript按位操作符操作以及用途
所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数.正数的补码是自己本身,负数的补码是取反后加一,所以经过操作运算后的值是补码形式. 描述 按位与( AN ...