QT210开发板android应用程序控制led灯[android应用程序控制硬件]
来源:互联网 发布:mysql order by count 编辑:程序博客网 时间:2024/05/22 11:42
QT210 开发板 LED应用程序
目的: 编写一个android应用程序来控制开发板上led灯的亮与灭.
编译环境: Ubuntu12.04
Android系统: android4.0 (linux3.0.8)
一.驱动
1. 查看原理图,QT210开发板上led D5, D6, D7, D8 对应引脚为EINT0, EINT1, EINT2, EINT3.
Tigerboard-II底板.pdf
2. 根据底板上的EINT引脚,在核心板上找到与之相对应的引脚,最终对应到了GPIO的GPH0_0, GPH0_1, GPH0_2, GPH0_3
QT210V2核心板.pdf:
3. 接下来在三星 S5PV210芯片手册上找到相应寄存器.控制led灯实际就是控制相应寄存器.
S5PV210_EVT1_Usermanual_20100218.pdf
4. 编写驱动文件led.c
#include <linux/module.h> #include <linux/kernel.h> //#include <linux/io.h> #include <asm/irq.h>#include <asm/io.h>#include <linux/fs.h> #include <asm/uaccess.h> #include <linux/miscdevice.h> #include <linux/pci.h> #include <linux/ioctl.h> #include <linux/init.h> #include <linux/delay.h> #define DEVICE_NAME "leds" //设备名(/dev/leds) #define LED_MAJOR 240 unsigned long *gph0con = NULL;unsigned long *gph0dat = NULL;int major; static int led_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { printk(KERN_ALERT"\ncmd = %d arg = %d \n", cmd, arg); switch(cmd) { case 0: printk(KERN_ALERT"led%d off\n", arg); switch(arg) { case 0: *gph0dat &= ~0x01; break; case 1: *gph0dat &= ~0x02; break; case 2: *gph0dat &= ~0x04; break; case 3: *gph0dat &= ~0x08; break; default: break; } break; case 1: printk(KERN_ALERT"led%d on\n", arg); switch(arg) { case 0: *gph0dat |= 0x01; break; case 1: *gph0dat |= 0x02; break; case 2: *gph0dat |= 0x04; break; case 3: *gph0dat |= 0x08; break; default: break; } break; case 11: printk(KERN_ALERT"led all on\n"); *gph0dat |= 0xf; break; case 10: printk(KERN_ALERT"led all off\n"); *gph0dat &= ~0xf; break; default: break; } return 0; } struct file_operations led_fops={ .owner = THIS_MODULE, .unlocked_ioctl = led_ioctl, }; static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, //动态设备号 .name = DEVICE_NAME, .fops = &led_fops, }; static int __init led_init(void) { int rc;gph0con = (unsigned long *)ioremap(0xE0200C00, 16);gph0dat = (unsigned long *)ioremap(0xE0200C04, 8);*gph0con &= ~0xffff;*gph0con |= 0x1111;*gph0dat &= ~0xf; rc = misc_register(&misc); if(rc<0) { printk(KERN_ALERT"register %s char dev error\n","leds"); return -1; } else printk(KERN_ALERT" lcd module OK!\n"); return 0; } static void __exit led_exit(void) { unregister_chrdev(LED_MAJOR, "leds"); printk(KERN_ALERT"module exit\n"); } module_init(led_init); module_exit(led_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("cw");
5. 编写led.c的Makefile. 这里将led驱动编译成模块的方式.
注意: 编写Makefile时,行的开头只能用Tab,不能用空格.
KERNELDIR :=/home/share/210/android4.0/4.0/qt210_ics_kernel3.0.8 PWD :=$(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install obj-m:=led.o clean: rm -rf *.o *~core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
6. 编译
编译成功后生成led.ko模块.
7. 将led.ko 拷贝到开发板上,半加载.加载之后会在/dev/目录下生成leds这个设备.
二. Android应用程序
1. 新建一个Android应用程序
2. 打开 src/LedActivity.java,
添加public static native int led_ioctl(int i, int j);
添加一个接口是为了利用java来生成jni的头文件.
src/LedActivity.java:
package com.example.led; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class LedActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_led); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.led, menu); return true; } public static native int led_ioctl(int i, int j); }
3. 编译整个android项目,将整个Led项目文件拷贝到ubuntu上.
新建一个jni目录
4. 利用java文件自动生成jni头文件.
javah -classpath bin/classes -d jni com.example.led.LedActivity
5. jni目录下编写led.c 即led测试程序led.c.
Led/jni/led.c:
#include <jni.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <android/log.h> #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_LedActivity_led_1ioctl(JNIEnv *env, jclass thiz, jint led_nu, jint on) { int fd; fd = open("/dev/leds", O_RDWR); if(fd < 0) printf("Can't open /dev/leds!\n"); ioctl(fd, on, led_nu); LOGI("led_nu=%d,state=%d\n", led_nu, on); close(fd); return 0; }
6. jni目录下编写Android.mk
Led/jni/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := Led_ctrl LOCAL_SRC_FILES := led.c LOCAL_LDLIBS := -llog LOCAL_C_INCLUDES := $(MY_ANDROID_SOURCE)/frameworks/base/core/jni/android/graphics \ $(MY_ANDROID_SOURCE)/external/skia/include/core \ $(MY_ANDROID_SOURCE)/external/skia/include/images \ $(MY_ANDROID_SOURCE)/frameworks/base/include \ $(MY_ANDROID_SOURCE)/system/core/include include $(BUILD_SHARED_LIBRARY)
7. Led目录下运行ndk-bluild, 将led.c文件编译成so库文件.
前提是你已经安装了android-ndk 工具(http://blog.csdn.net/colwer/article/details/8944166)
8. 将生成的libLed_ctrl.so拷贝到eclipse下Led应用程序中的libs/armeabi目录(如果没有armeabi目录需手动创建一个)
9. 在应用程序布局文件中加入4个开关按钮,对应四个led开关,也可以再添加一个总开关来同时控制四个led.
res/layout/activity_led.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".LedActivity" > <ToggleButton android:id="@+id/btn1" android:layout_width="140dip" android:layout_height="wrap_content" android:textOn="led1 on" android:textOff="led1 off" android:layout_gravity="center_horizontal" /> <ToggleButton android:id="@+id/btn2" android:layout_width="140dip" android:layout_height="wrap_content" android:textOn="led2 on" android:textOff="led2 off" android:layout_gravity="center_horizontal" /> <ToggleButton android:id="@+id/btn3" android:layout_width="140dip" android:layout_height="wrap_content" android:textOn="led3 on" android:textOff="led3 off" android:layout_gravity="center_horizontal" /> <ToggleButton android:id="@+id/btn4" android:layout_width="140dip" android:layout_height="wrap_content" android:textOn="led4 on" android:textOff="led4 off" android:layout_gravity="center_horizontal" /> </LinearLayout>
10. 编写java文件.
src/LedActivity.java:
package com.example.led;import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.View;import android.widget.Button;import android.widget.ToggleButton;public class LedActivity extends Activity {private static final String TAG = "LED"; private ToggleButton button1; private ToggleButton button2; private ToggleButton button3; private ToggleButton button4;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_led);button1 = (ToggleButton)findViewById(R.id.btn1); button2 = (ToggleButton)findViewById(R.id.btn2); button3 = (ToggleButton)findViewById(R.id.btn3); button4 = (ToggleButton)findViewById(R.id.btn4); button1.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button1.isChecked()) led_ioctl(0, 1); //led1 on else led_ioctl(0, 0); //led1 off } }); button2.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button2.isChecked()) led_ioctl(1, 1); //led2 on else led_ioctl(1, 0); //led2 off } }); button3.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button3.isChecked()) led_ioctl(2, 1); //led3 on else led_ioctl(2, 0); //led3 off } }); button4.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { if (button4.isChecked()) led_ioctl(3, 1); //led4 on else led_ioctl(3, 0); //led4 off } }); }@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.led, menu);return true;}public static native int led_ioctl(int i, int j);static{System.loadLibrary("Led_ctrl");// libs/armeabi/libLed_ctrl.so}}
编译生成Led.apk,并安装到开发板上.
至此,整个工作已经完成,开发板上打开应用程序就可以控制led了.但有几点需要注意
1. 开发板上D5这个灯已经被占用了,所以led1不能控制D5了.
2. 记住运行应用程序前确保内核中led.ko已被加载,并修改 /dev/leds的权限,否则led灯不受控制.
整个代码已打包上传到我的博客:
http://download.csdn.net/detail/colwer/5403281
本人新手,欢迎大家帮忙指正错误和提供建议.
下一步计划做一个远程控制的.就是局域网内通过另一个android设备来操控开发板.
- QT210开发板android应用程序控制led灯[android应用程序控制硬件]
- Android应用程序通过JNI控制LED
- 按键控制led应用程序
- 【转】Android应用程序:(jni方式)控制LED/GPIO
- 控制Android应用程序的耗电量
- 控制Android应用程序的耗电量
- 控制Android应用程序的耗电量
- Android控制应用程序安装位置
- android之应用程序LED
- 控制Android LED灯颜色代码
- wince6.0 +S3C6410 中断处理例子(按键控制LED灯)+应用程序控制LED流水灯
- Android底层开发Led控制实验
- Android底层开发Led控制实验
- Android底层开发Led控制实验
- Android LED控制
- 2440 led-管道-控制应用程序详细解释
- S3C6410 按键控制LED应用程序 ---源代码
- ok6410Android应用程序:(jni方式)控制LED/GPIO
- BOX2D总体关系图
- 单链表的逆置
- “红色病毒”问题--递推
- HDU 4545 魔法串
- memache 客户端
- QT210开发板android应用程序控制led灯[android应用程序控制硬件]
- 单链表的排序
- xmu 1246.素数筛选
- ibatis常见问题
- 创建表空间,用户授权
- 查找单链表的中间节点
- 参考说明
- 《一个操作系统的实现》(五):1.ELF
- SQL Server和MySql语法和关键字的区别