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
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- android第三方框架(五)ButterKnife
- 一个人的碎碎念
- 我从来不做坏事
- Android中的AES加密-下
- 从蓦然回首到花开在眼前,都是为了更好的明天。
- 带有Hilt的Android上的依赖注入
- 西湖游
- 改变自己,先从自我反思开始
- leetcode|leetcode 92. 反转链表 II