android驱动[置顶] 我的DIY Android之旅--驱动并控制你的Android开发板蜂鸣器
2013-06-22 22:08
323 查看
改章节个人在深圳游玩的时候突然想到的...这几周就有想写几篇关于android驱动的博客,所以回家到之后就奋笔疾书的写出来发布了
这些天一直在想Android驱动框架层的实现,本文借助老罗教师的博客和现有通过过分析台湾的Jollen的mokoid 工程代码,并尝试在Android开发板上驱动一个简单的蜂鸣器,来解析Android下驱动的调用。
HAL架构由Patrick Brady (Google) 在2008 Google I/O报告中提出的,如下图。
其实可以斟酌先编写驱动代码,然后使用NDK编译库层的代码,最后在Android应用层来直接完成对硬件驱动层的调用!
先编写一个简单的蜂鸣器驱动程序,根据开发板上的硬件IO接口和Android驱动规范,在kernel中的driver目录中新建一个Buzzer文件,新建一个buzzer.c的源文件
每日一道理
俄国作家契诃夫说:“有大狗,有小狗,小狗不该因为大狗的存在而心慌意乱。所有的狗都应该叫,就让他各自用上帝给他的声音。
在目录下创建一个Makefile文件,文件内容如下
先运行make clean命令清楚到编译生成的一些工程文件,执行make命令,重新编译驱动程序。将编译生成的buzzer.ko内核镜像文件拷贝出来,adb push buzzer.ko /fpga/moudles
然后插入内核镜像文件到系统中,insmod buzzer.ko,并且装载设备驱动程序,mknod /dev/buzzer c 248 0
当初就能够在库层直接编写C/C++文件来调用这个驱动程序,这个可以在ubuntu中安装NDK编译环境,新建buzzer文件,编译生成一个库文件,那样就能够直接在应用层使用这个库提供的JNI方法,那样调用会显得更加的简单,当然这个调用方法google并不倡导,我在这里只是想展示这类调用方法而已
构建一个jni工程,新建一个buzzer.c的源文件,内容如下:
停止NDK编译,生成libbuzzer.so,这个库就能够直接在应用层停止调用
在eclipse中编写应用程序直接调用这个库,实现对底层驱动的调用!!
主要源代码:
全部工程目录:
直接运行,在开发板上查看运行结果。。。
文章结束给大家分享下程序员的一些笑话语录:
大家喝的是啤酒,这时你入座了。
你给自己倒了杯可乐,这叫低配置。
你给自已倒了杯啤酒,这叫标准配置。
你给自己倒了杯茶水,这茶的颜色还跟啤酒一样,这叫木马。
你给自己倒了杯可乐,还滴了几滴醋,不仅颜色跟啤酒一样,而且不冒热气还有泡泡,这叫超级木马。
你的同事给你倒了杯白酒,这叫推荐配置。
菜过三巡,你就不跟他们客气了。
你向对面的人敬酒,这叫p2p。
你向对面的人敬酒,他回敬你,你又再敬他……,这叫tcp。
你向一桌人挨个敬酒,这叫令牌环。
你说只要是兄弟就干了这杯,这叫广播。
有一个人过来向这桌敬酒,你说不行你先过了我这关,这叫防火墙。
你的小弟们过来敬你酒,这叫一对多。
你是boss,所有人过来敬你酒,这叫服务器。
酒是一样的,可是喝酒的人是不同的。
你越喝脸越红,这叫频繁分配释放资源。
你越喝脸越白,这叫资源不释放。
你已经醉了,却说我还能喝,叫做资源额度不足。
你明明能喝,却说我已经醉了,叫做资源保留。
喝酒喝到最后的结果都一样
你突然跑向厕所,这叫捕获异常。
你在厕所吐了,反而觉得状态不错,这叫清空内存。
你在台面上吐了,觉得很惭愧,这叫程序异常。
你在boss面前吐了,觉得很害怕,这叫系统崩溃。
你吐到了boss身上,只能索性晕倒了,这叫硬件休克。
---------------------------------
原创文章 By
android和驱动
---------------------------------
这些天一直在想Android驱动框架层的实现,本文借助老罗教师的博客和现有通过过分析台湾的Jollen的mokoid 工程代码,并尝试在Android开发板上驱动一个简单的蜂鸣器,来解析Android下驱动的调用。
HAL架构由Patrick Brady (Google) 在2008 Google I/O报告中提出的,如下图。
其实可以斟酌先编写驱动代码,然后使用NDK编译库层的代码,最后在Android应用层来直接完成对硬件驱动层的调用!
先编写一个简单的蜂鸣器驱动程序,根据开发板上的硬件IO接口和Android驱动规范,在kernel中的driver目录中新建一个Buzzer文件,新建一个buzzer.c的源文件
#include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/ioport.h> #include<linux/fs.h> #include<asm/io.h> #include<asm/uaccess.h> #define DRIVER_AUTHOR "canjianfantasy" #define DRIVER_DESCRIBLE "buzzer test program" #define BUZZER_MAJOR 248 //Device Driver Major Number #define BUZZER_NAME "BUZZER_IO_PORT" //Device Name #define BUZZER_DRIVER_VERSION "BUZZER IO PORT V0.1" //Device Driver Version #define BUZZER_ADDRESS 0x88000050 //physical address #define BUZZER_ADDRESS_RANGE 0x1000 // I/O region range //Glable variable static int buzzer_usage = 0; //if device is already used ? static unsigned long *buzzer_ioremap ; //io address region //It is called when program called open() system call int buzzer_open(struct inode *minode,struct file *mfile) { //if device is already opened if(buzzer_usage != 0) return -EBUSY; //mapping physical address to virtual address buzzer_ioremap = ioremap(BUZZER_ADDRESS,BUZZER_ADDRESS_RANGE); //check if it is usable virtual address. if(!check_mem_region((unsigned long)buzzer_ioremao,BUZZER_ADDRESS_RANGE)) { //register I/O address region request_mem_region((unsigned long)buzzer_ioremap,BUZZER_ADDRESS_RANGE,BUZZER_NAME); } else { printk(KERN_WARNING"Can't get I/O region 0x%x\n",(unsigned int)buzzer_ioremap); } buzzer_usage = 1; return 0; } //It is called when program called close() system call int buzzer_release(struct inode *mnode,struct file *mfile) { //Release mapped virtual address iounmap(buzzer_ioremap); //Release registed I/O memory region release_mem_region((unsigned long)buzzer_ioremap,BUZZER_ADDRESS_RANGE); buzzer_usage = 0; return 0; } //It is called when program calls write() system call size_t buzzer_write_byte(struct file *inode, const char* gdata, size_t length, loff_t *off_what) { unsigned char *addr; unsigned char c; //copy data from gdata to c get_user(c,gdata); addr = (unsigned char *)(buzzer_ioremap); *addr = c; return length; } //file operations structure static struct file_operations buzzer_fops = { .owner = THIS_MODULE, .open = buzzer_open, .write = buzzer_write_byte, .release = buzzer_release, }; // insert module to kernel int buzzer_init( void ) { int result; //Register character device drvier result = register_chrdev(BUZZER_MAJOR,BUZZER_NAME,&buzzer_fops); if(result < 0) { //registration failed printk(KERN_WARNING "Can't get any major \n"); return result; } //print MAJOR_NUMBER printk(KERN_WARNING "Init Module ,Buzzer Major number %d \n",BUZZER_MAJOR); return 0 ; } // remove module from kernel void buzzer_exit(void) { //Unregister character device driver unregister_chardev(BUZZER_MAJOR,BUZZER_NAME); printk(KERN_INFO"driver: %s DRIVER EXIT \n",BUZZER_NAME); } module_init(buzzer_init); module_exit(buzzer_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESCRIPTION); MODULE_LICENSE("Dual BSD/GPL");
每日一道理
俄国作家契诃夫说:“有大狗,有小狗,小狗不该因为大狗的存在而心慌意乱。所有的狗都应该叫,就让他各自用上帝给他的声音。
在目录下创建一个Makefile文件,文件内容如下
CC = /usr/local/arm-2009q3/bin/arm-none-linux-gnueabi-gcc obj-m := buzzer.o KDIR := /Android/linux-2.6.32 PWD := $(shell pwd) default : $(MAKE) -C $(KDIR) SUBDIRS=$(PWD modules rm -f default clean: rm -f *.ko rm -f *.o rm -f *.mod.* rm -f .*.cmd
先运行make clean命令清楚到编译生成的一些工程文件,执行make命令,重新编译驱动程序。将编译生成的buzzer.ko内核镜像文件拷贝出来,adb push buzzer.ko /fpga/moudles
然后插入内核镜像文件到系统中,insmod buzzer.ko,并且装载设备驱动程序,mknod /dev/buzzer c 248 0
当初就能够在库层直接编写C/C++文件来调用这个驱动程序,这个可以在ubuntu中安装NDK编译环境,新建buzzer文件,编译生成一个库文件,那样就能够直接在应用层使用这个库提供的JNI方法,那样调用会显得更加的简单,当然这个调用方法google并不倡导,我在这里只是想展示这类调用方法而已
构建一个jni工程,新建一个buzzer.c的源文件,内容如下:
#include<errno.h> #include<android/log.h> #define LOG_TAG "BuzzerDriver" //#define LOGW(a) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a) #define LOGW(a) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a) jint java_com_fantasy_buzzer_BuzzerActivity_BuzzerControl(JNIEnv *env,jobject thiz,jint value) { int fd,ret; int data=value; fd=open("/dev/buzzer",O_WRONLY); if(fd < 0) { LOGW("Android Open Driver buzzer failed!"); return -errno; } ret=write(fd ,&data ,1); if(ret < 0) close(fd); if(ret == 1) return 0;
停止NDK编译,生成libbuzzer.so,这个库就能够直接在应用层停止调用
在eclipse中编写应用程序直接调用这个库,实现对底层驱动的调用!!
主要源代码:
package com.fantasy.buzzer; //@ canjianfantasy 2013.6.22 import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; public class BuzzerActivity extends Activity { Button BuzzerButton; int BuzzerData =0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_buzzer); // BuzzerControl(BuzzerData); BuzzerButton =(Button)findViewById(R.id.On); BuzzerButton.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub if(BuzzerData == 0){ BuzzerData = 1; BuzzerButton.setText("Buzzer off"); } else{ BuzzerData = 0; BuzzerButton.setText("Buzzer On"); } // BuzzerControl(BuzzerData); } }); } static{ System.loadLibrary("buzzer"); } public native int BuzzerControl(int Value); @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_buzzer, menu); return true; } }
全部工程目录:
直接运行,在开发板上查看运行结果。。。
文章结束给大家分享下程序员的一些笑话语录:
大家喝的是啤酒,这时你入座了。
你给自己倒了杯可乐,这叫低配置。
你给自已倒了杯啤酒,这叫标准配置。
你给自己倒了杯茶水,这茶的颜色还跟啤酒一样,这叫木马。
你给自己倒了杯可乐,还滴了几滴醋,不仅颜色跟啤酒一样,而且不冒热气还有泡泡,这叫超级木马。
你的同事给你倒了杯白酒,这叫推荐配置。
菜过三巡,你就不跟他们客气了。
你向对面的人敬酒,这叫p2p。
你向对面的人敬酒,他回敬你,你又再敬他……,这叫tcp。
你向一桌人挨个敬酒,这叫令牌环。
你说只要是兄弟就干了这杯,这叫广播。
有一个人过来向这桌敬酒,你说不行你先过了我这关,这叫防火墙。
你的小弟们过来敬你酒,这叫一对多。
你是boss,所有人过来敬你酒,这叫服务器。
酒是一样的,可是喝酒的人是不同的。
你越喝脸越红,这叫频繁分配释放资源。
你越喝脸越白,这叫资源不释放。
你已经醉了,却说我还能喝,叫做资源额度不足。
你明明能喝,却说我已经醉了,叫做资源保留。
喝酒喝到最后的结果都一样
你突然跑向厕所,这叫捕获异常。
你在厕所吐了,反而觉得状态不错,这叫清空内存。
你在台面上吐了,觉得很惭愧,这叫程序异常。
你在boss面前吐了,觉得很害怕,这叫系统崩溃。
你吐到了boss身上,只能索性晕倒了,这叫硬件休克。
---------------------------------
原创文章 By
android和驱动
---------------------------------
相关文章推荐
- 我的DIY Android之旅--驱动并控制你的Android开发板蜂鸣器
- 友善之臂4412开发板android应用层通过jni直接控制除LED、蜂鸣器外的其它IO口,系统直接重启问题
- s5pv210开发板 android系统内存相应驱动路径
- s5pv210开发板 android 系统 特有驱动路径说明
- android底层驱动学习之内核信息的输出以及控制方式
- [置顶] ARM开发(10)基于STM32的通用定时器中断控制蜂鸣器响
- Android深度探索:HAL与驱动开发学习笔记--并发控制之自旋锁
- Android深度探索:HAL与驱动开发学习笔记--并发控制之顺序锁
- A10开发板增加红外驱动及android层红外按键修改介绍
- [置顶] android:在有EditText的Activity上,控制自动显示或者隐藏软键盘
- 字符设备驱动-----控制mini2440开发板的4个led灯
- 通用GPIO驱动和apk(含jni),支持所有GPIO,支持LED控制,支持友善6410/210开发板,支持安卓2.3/4.0,内核2.6/3.0
- android平台矩阵键盘驱动[基于x210开发板]
- Android应用控制LED(动态编译LED驱动)
- Android照相功能驱动层中HAL的实现(基于OK6410开发板+OV9650摄像头)
- Linux-2.6.32.2内核在mini2440上的移植(十七)---移植PWM控制蜂鸣器驱动
- 基于飞思卡尔imx6 sabrelite开发板的android lvds屏幕驱动调试
- [置顶] Android ril移植-6410开发板SIM300模块
- Android深度探索:HAL与驱动开发学习笔记--并发控制之互斥锁
- Android深度探索:HAL与驱动开发学习笔记--并发控制之信号量&完成量