总体框图
一、编写一个app
1、创建一个工程
2、在开发板上运行
3、增加按钮
(1) 实现垂直排布
<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">
(2)增加按钮
<Button
android:id="@+id/Button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ALL ON"/>
4、增加复选框
<CheckBox
android:id="@+id/LED1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="LED1"
android:onClick="onCheckboxClicked"/>
<CheckBox
android:id="@+id/LED2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="LED2"
android:onClick="onCheckboxClicked"/>
<CheckBox
android:id="@+id/LED3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="LED3"
android:onClick="onCheckboxClicked"/>
<CheckBox
android:id="@+id/LED4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="LED4"
android:onClick="onCheckboxClicked"/>
5、实现按钮监听功能
private Button button = null;
class MyButtonListener implements View.OnClickListener{
public void onClick(View v){
ledon = !ledon;
if(ledon) {
button.setText("ALL ON");
checkBoxLed1.setChecked(true);
checkBoxLed2.setChecked(true);
checkBoxLed3.setChecked(true);
checkBoxLed4.setChecked(true);
for(int i=0;i<4;i++){
HardControl.ledCtrl(i,1);
}
}
else{
button.setText("ALL OFF");
checkBoxLed1.setChecked(false);
checkBoxLed2.setChecked(false);
checkBoxLed3.setChecked(false);
checkBoxLed4.setChecked(false);
for(int i=0;i<4;i++){
HardControl.ledCtrl(i,0);
}
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HardControl.ledOpen();
button = (Button)findViewById(R.id.Button);
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());
}
6、实现复选框点击功能
private CheckBox checkBoxLed1 = null;
private CheckBox checkBoxLed2 = null;
private CheckBox checkBoxLed3 = null;
private CheckBox checkBoxLed4 = null;
public void onCheckboxClicked(View view) {
// Is the view now checked?
boolean checked = ((CheckBox) view).isChecked();
// Check which checkbox was clicked
switch(view.getId()) {
case R.id.LED1:
if (checked){
Toast.makeText(getApplicationContext(),"LED1
ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(0, 1);
}
// Put some meat on the sandwich
else{
Toast.makeText(getApplicationContext(),"LED1
OFF",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(0, 0);
}
// Remove the meat
break;
case R.id.LED2:
if (checked){
Toast.makeText(getApplicationContext(),"LED2
ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(1, 1);
}
// Cheese me
else{
Toast.makeText(getApplicationContext(),"LED2
ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(1, 0);
}
// I'm lactose intolerant
break;
// TODO: Veggie sandwich
case R.id.LED3:
if (checked){
Toast.makeText(getApplicationContext(),"LED3
ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(2, 1);
}
// Put some meat on the sandwich
else{
Toast.makeText(getApplicationContext(),"LED3
OFF",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(2, 0);
}
// Remove the meat
break;
case R.id.LED4:
if (checked){
Toast.makeText(getApplicationContext(),"LED4
ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(3, 1);
}
// Cheese me
else{
Toast.makeText(getApplicationContext(),"LED4
ON",Toast.LENGTH_SHORT).show();
HardControl.ledCtrl(3, 0);
}
// I'm lactose intolerant
break;
// TODO: Veggie sandwich
}
}
checkBoxLed1 = (CheckBox)findViewById(R.id.LED1);
checkBoxLed2 = (CheckBox)findViewById(R.id.LED2);
checkBoxLed3 = (CheckBox)findViewById(R.id.LED3);
checkBoxLed4 = (CheckBox)findViewById(R.id.LED4);
二、访问c库
1、编写声明c函数的java文件
package com.example.yxp.hardlibrary;
public class HardControl {
public static native int ledCtrl(int which, int status);
public static native int ledOpen();
public static native void ledClose();
static {
try {
System.loadLibrary("hardcontrol");
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、编写c文件实现函数功能
#include <jni.h> /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */
#include <stdio.h>
#include <android/log.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#if 0
typedef struct {
char *name; /* Java里调用的函数名 */
char *signature; /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
void *fnPtr; /* C语言实现的本地函数 */
} JNINativeMethod;
#endif
static jint fd;
jint ledOpen(JNIEnv *env, jobject cls)
{
fd = open("/dev/leds",O_RDWR);
if(fd >= 0)
return 0;
else
return 1;
__android_log_print(ANDROID_LOG_DEBUG, "MyApplication3", "native add ledOpen");
return 0;
}
void ledClose(JNIEnv *env, jobject cls)
{
__android_log_print(ANDROID_LOG_DEBUG, "MyApplication3", "native add ledClose");
close(fd);
}
jint ledCtrl(JNIEnv *env, jobject cls,jint which,jint status )
{
int ret = ioctl(fd,status ,which );
__android_log_print(ANDROID_LOG_DEBUG, "MyApplication3", "native add: %d %d",which,status );
return ret;
}
static const JNINativeMethod methods[] = {
{"ledOpen", "()I", (void *)ledOpen},
{"ledClose", "()V", (void *)ledClose},
{"ledCtrl", "(II)I", (void *)ledCtrl},
};
/* 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/yxp/hardlibrary/HardControl");
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;
}
3、把c文件编译成so文件
arm-linux-gcc -fPIC -shared hardcontrol.c -o libhardcontrol.so -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -nostdlib /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/libc.so -I /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/include /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/liblog.so
4、在app/libs下建armeabi子目录,放入so文件
三、实现LED驱动
1、放入内核 drivers/char
#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>
#include <linux/leds.h>
static struct class *cls;
static struct class_device *firstdrv_class_dev;
static int led_gpios[] = {
EXYNOS4212_GPM4(0),
EXYNOS4212_GPM4(1),
EXYNOS4212_GPM4(2),
EXYNOS4212_GPM4(3),
};
static int led_open(struct inode *inode, struct file *file)
{
int i;
for(i=0;i<4;i++)
s3c_gpio_cfgpin(led_gpios[i],S3C_GPIO_OUTPUT);
return 0;
}
static long led_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
if((cmd != 0 )&& (cmd !=1))
return -EINVAL;
if(arg > 4)
return -EINVAL;
gpio_set_value(led_gpios[arg],!cmd);
return 0;
}
static struct file_operations leds_ops = {
.owner = THIS_MODULE,
.open = led_open,
.unlocked_ioctl = led_ioctl,
};
int major;
static int leds_init(void)
{
major = register_chrdev(0, "leds", &leds_ops);
/*为了让系统给我们创造节点*/
/*创建类,在类下创建设备*/
cls = class_create(THIS_MODULE, "leds");
firstdrv_class_dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "leds"); /* /dev/xyz */
return 0;
}
static void leds_exit(void)
{
unregister_chrdev(major, "leds"); // 卸载
device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
}
module_init(leds_init);
module_exit(leds_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.100ask.net");
2、修改 drivers/char/Makefile,添加:obj-y += leds_4412.o
3、重新编译内核