QT210开发板android应用程序控制led灯[android应用程序控制硬件]

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引脚,在核心板上找到与之相对应的引脚,最终对应到了GPIOGPH0_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.cMakefile. 这里将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拷贝到eclipseLed应用程序中的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;

	@Override
	protected 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 
            }  
        }); 
	}

	@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);
	
	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设备来操控开发板.

 

 

        

 

 

 

 

 

 

   

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值