android|android 从驱动到应用(一)

系统框架:


硬件层——驱动程序——linux内核——JNI——JAVA应用程序(个人理解)



下面是一个基于三星210芯片 led驱动的例子:
.c文件代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

//add include
#include


#define DEVICE_NAME "yyp_led"// 加载模式后,执行car /proc/devices命令看到的设备名称
#define LED_MAJOR 234 // 主设备号
#define IOCTL_LED_ON 1
#define IOCTL_LED_OFF 0

static struct class *yyp_led_class;

//led 所用的GPIO引脚
//static unsigned long led_gpio_table[] = {};

// 指定gpio的引脚功能:输出
//static unsigned int gpio_cfg_table[] ={};

ssize_t yyp_led_open(struct inode * inode,struct file * file)
{
printk("yyp_led_open() \n");
return 0;
}


static int yyp_led_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
int ret = -EINVAL;
if(arg>3)
{
return -EINVAL;
}
switch(cmd)
{
case IOCTL_LED_ON:
gpio_direction_output(S5PV210_GPJ3(4+arg), 0);
ret = 0;
break;
case IOCTL_LED_OFF:
gpio_direction_output(S5PV210_GPJ3(4+arg), 1);
ret = 0;
break;
default:
ret = -EINVAL;
break;
}
return ret;
}

static struct file_operations dev_fops =
{
.owner = THIS_MODULE,
.ioctl = yyp_led_ioctl,
};

static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};


static int __init dev_init(void)
{
int ret;
int i;
for(i=0; i<4; i++)
{
s3c_gpio_cfgpin(S5PV210_GPJ3(4+i), S3C_GPIO_SFN(1));
}
ret = misc_register(&misc);
printk(DEVICE_NAME" initialized\n");

/*静态方式注册驱动*/
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &dev_fops);
if (ret < 0) {
printk(KERN_ERR "led: unable to get major %d/n", ret);
return ret;
}
//创建class
yyp_led_class = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(yyp_led_class)) {
unregister_chrdev(LED_MAJOR, "capi20");
return PTR_ERR(yyp_led_class);
}
//创建节点,
device_create(yyp_led_class, NULL, MKDEV(LED_MAJOR, 0), NULL, DEVICE_NAME);

return ret;
}

static void __exit dev_exit(void)
{
misc_deregister(&misc);
}


module_init(dev_init);
module_exit(dev_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("yyp");
MODULE_DESCRIPTION("This is led driver!");
参考:http://blog.csdn.net/imyang2007/article/details/7370167把驱动编译到内核,重新烧录内核。
驱动测试:
两种方法:
方法一:C语言写测试程序
【android|android 从驱动到应用(一)】test.c文件:
#include
#include
#include
//#include

#define DEVICE_NAME "/dev/yyp_led"//device point

#define LED_ON 0x1
#define LED_OFF 0x0

int main(int count,char *name[])
{
/* int i,j;
for(i=0; i<10; i++)
{
printf("%d:",count);
for(j=0; j {
printf("*");
// usleep(1000*500);
// sleep(1);
}
printf("\r\n");
sleep(1);
}
printf("%s\r\n",*(name+1)); */
int fd;
int ret;
int i;
printf("\n start gpio_led_driver test \r\n");
fd = open(DEVICE_NAME,O_RDWR); //Open device ,get the handle
printf("fd = %d \n",fd);
if(fd == -1) //open fail
{
printf("open device %s error \n",DEVICE_NAME);
}
else
{
i = 0;
while(i<20)
{
ioctl(fd,LED_OFF,0); //call the output function to off LEDs
ioctl(fd,LED_OFF,1);
ioctl(fd,LED_OFF,2);
ioctl(fd,LED_OFF,3);
sleep(1); //wait 1 second
ioctl(fd,LED_ON,0); //call the output function to off LEDs
ioctl(fd,LED_OFF,1);
ioctl(fd,LED_OFF,2);
ioctl(fd,LED_OFF,3);
sleep(1);
ioctl(fd,LED_OFF,0); //call the output function to off LEDs
ioctl(fd,LED_ON,1);
ioctl(fd,LED_OFF,2);
ioctl(fd,LED_OFF,3);
sleep(1);
ioctl(fd,LED_OFF,0); //call the output function to off LEDs
ioctl(fd,LED_OFF,1);
ioctl(fd,LED_ON,2);
ioctl(fd,LED_OFF,3);
sleep(1); //wait 1 second
ioctl(fd,LED_OFF,0); //call the output function to off LEDs
ioctl(fd,LED_OFF,1);
ioctl(fd,LED_OFF,2);
ioctl(fd,LED_ON,3);
sleep(1); //wait 1 second
i++;
}
ret = close(fd); //close device
printf("ret = %d \n",ret);
printf("close gpio_led test \n");
}
return 0;
}
用交叉编译工具编译 后使用adb下载到android设备中,运行测试。具体方法参考:
http://blog.csdn.net/imyang2007/article/details/7329866

    推荐阅读