ok6410 android driver(8)
In the past, we know how to create and run a simple character device driver on pc, goldfish and ok6410.
These two essays I will talk about a led device real exists on ok6410.
In this essay, we will compile a led device driver and test it.
At first, I wanna write some short summary of the different between a character device and a real device.
(1) Character device :
We always control character device in bytes, just like we control a normal file.
Open file with a file handle, then read, write, llseek and put others control to the handle.
(2) Real device :
Acturely, we can control a real device like a normal character driver with file streams.
But we should know more about the ioctl.
When a real device connects to pc, it register a address for itself automaticly.
Then the pc malloc some I/O memory for it, and they will communicate via the I/O memory instead of immediately.
The I/O memory will protect both pc and device from speech mismach.
1、 leds.c
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank-m.h> #define DEVICE_NAME "s3c6410_leds"
#define DEVICE_COUNT 1
#define S3C6410_LEDS_MAJOR 0
#define S3C6410_LEDS_MINOR 234
#define PARAM_SIZE 3 static unsigned char mem[];
static int major = S3C6410_LEDS_MAJOR;
static int minor = S3C6410_LEDS_MINOR;
static dev_t leds_number;
static int leds_state = ;
static char *param[] = {"string1", "string2", "string3"};
static int param_size = PARAM_SIZE;
static struct class *leds_class = NULL; static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
switch (cmd) {
unsigned int tmp;
case :
case :
if (arg > ) {
return -EINVAL;
}
tmp = ioread32(S3C64XX_GPMDAT);
if (cmd == ) {
tmp &= (~( << arg));
} else {
tmp |= ( << arg);
}
iowrite32(tmp, S3C64XX_GPMDAT);
return ;
default :
return -EINVAL;
}
} static ssize_t s3c6410_leds_write(struct file *filp,
const char __user *buf, size_t count, loff_t *ppos)
{
unsigned tmp = count;
unsigned long i = ;
memset(mem, , ); if (count > ) {
tmp = ;
}
if (copy_from_user(mem, buf, tmp)) {
return -EINVAL;
} else {
for (i = ; i < ; i++) {
tmp = ioread32(S3C64XX_GPMDAT);
if (mem[i] == '') {
tmp &= (~( << i));
} else {
tmp |= ( << i);
}
iowrite32(tmp, S3C64XX_GPMDAT);
}
return count;
}
} static struct file_operations leds_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = s3c6410_leds_ioctl,
.write = s3c6410_leds_write,
};
static struct cdev leds_cdev; static int leds_create_device(void)
{
int ret = ;
int err = ; cdev_init(&leds_cdev, &leds_fops);
leds_cdev.owner = THIS_MODULE;
if (major > ) {
leds_number = MKDEV(major, minor);
err = register_chrdev_region(leds_number, DEVICE_COUNT, DEVICE_NAME);
if (err < ) {
printk(KERN_WARNING "register_chardev_region() failed.\n");
return err;
}
} else {
err = alloc_chrdev_region(&leds_cdev.dev, ,
DEVICE_COUNT, DEVICE_NAME);
if (err < ) {
printk(KERN_WARNING "register_chardev_region failed.\n");
return err;
}
major = MAJOR(leds_cdev.dev);
minor = MINOR(leds_cdev.dev);
leds_number = leds_cdev.dev;
} ret = cdev_add(&leds_cdev, leds_number, DEVICE_COUNT);
leds_class = class_create(THIS_MODULE, DEVICE_NAME) ;
device_create(leds_class, NULL, leds_number, NULL, DEVICE_NAME);
return ret; }
static void leds_init_gpm(int leds_default)
{
int tmp = ;
tmp = ioread32(S3C64XX_GPMCON);
tmp &= (~0xFFFF);
tmp |= 0x1111;
iowrite32(tmp, S3C64XX_GPMCON); tmp = ioread32(S3C64XX_GPMPUD);
tmp &= (~0xFF);
tmp |= 0xAA;
iowrite32(tmp, S3C64XX_GPMPUD); tmp = ioread32(S3C64XX_GPMDAT);
tmp &= (~0xF);
tmp |= leds_default;
iowrite32(tmp, S3C64XX_GPMDAT);
} static int leds_init(void)
{
int ret;
ret = leds_create_device();
leds_init_gpm(~leds_state);
printk(DEVICE_NAME "\tinitialized.\n"); printk("param0\t%s\n", param[]);
printk("param1\t%s\n", param[]);
printk("param2\t%s\n", param[]); return ret;
} static void leds_destroy_device(void)
{
device_destroy(leds_class, leds_number);
if (leds_class) {
unregister_chrdev_region(leds_number, DEVICE_COUNT);
return;
}
}
static void leds_exit(void)
{
leds_destroy_device();
printk(DEVICE_NAME"\texit.\n");
} module_init(leds_init);
module_exit(leds_exit); module_param(leds_state, int, S_IRUGO | S_IWUSR);
module_param_array(param, charp, ¶m_size, S_IRUGO | S_IWUSR); MODULE_LICENSE("GPL");
Then follow the steps we analysis in wordcount device (character device).
2、init and exit entrance functions
(1) init function :
// init entrance function
module_init(leds_init);
//
static int leds_init(void)
{
...
// create device like normal character device
ret = leds_create_device();
// init the device by its I/O memory
leds_init_gpm(~leds_state);
...
}
(2) exit function :
// exit entrance function
module_exit(leds_exit);
//
static void leds_exit(void)
{
// destroy and unregister the device
leds_destroy_device();
printk(DEVICE_NAME"\texit.\n");
}
3、the device mechanism supported by the device driver
// file control mechanism
static struct file_operations leds_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = s3c6410_leds_ioctl,
.write = s3c6410_leds_write,
};
// device defination
static struct cdev leds_cdev;
4、the callback operation functions
static struct file_operations leds_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = s3c6410_leds_ioctl,
.write = s3c6410_leds_write,
};
//
static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
...
//
static ssize_t s3c6410_leds_write(struct file *filp,
const char __user *buf, size_t count, loff_t *ppos)
...
I don't want to talk much about file_operations, you can check it in /kernel_dir/include/linux/fs.h and 《LDD》.
TIPS-1 :
If you want to test the device, you could use echo.
But don't try to use a shell scripts to control it. because the shell in android and pc is working not like the original shell.
Ok, if you turely want to got a test in shell scripts, try this in you pc :
// choose no
$ sudo dpkg-reconfigure dash
TIPS-2 :
Our device is /dev/s3c6410_leds instead of /dev/leds
ok6410 android driver(8)的更多相关文章
- ok6410 android driver(5)
Test the android driver by JNI (Java Native Interface), In the third article, we know how to compile ...
- ok6410 android driver(11)
This essay, I go to a deeply studying to android HAL device driver program. According to the android ...
- ok6410 android driver(9)
In this essay, I will write the JNI to test our leds device. If you don't know how to create a jni p ...
- ok6410 android driver(3)
This article discusses the Makefile and how to port the module to different platform (localhost and ...
- ok6410 android driver(12)
In this essay, I will talk about how to write the service libraries. TIPS : I won't discuss the name ...
- ok6410 android driver(10)
From this essay, we go to a new discussion "Android Hardware Abstraction Layer". In this e ...
- ok6410 android driver(7)
This article talk about how to test device driver on JNI. There are two ways to test the device driv ...
- ok6410 android driver(6)
This is a short essay about the mistakes in compiling ok6410 android-2.3 source codes. If there is n ...
- ok6410 android driver(1)
target system : Android (OK6410) host system : Debian Wheezy AMD64 1.Set up android system in ok6410 ...
随机推荐
- JS 获取自定义标签
<abc-aaa xwe='sdf'>AAAAAAAAAAAAAAAAAAAAAA</abc-aaa> alert($("abc-aaa").attr(&q ...
- iOS中的webView加载HTML
在日常开发中,我们为了效率会用到很多很多的WebView,比如在做某个明细页面的时候我们返回给你的可能是一个html字符串,我们就需要将当前字符串展示到webView上面,所以我们对HTML标签需要有 ...
- 很好的一篇讲LTP在编解码中的作用的文章
原文链接 LONG-TERM PREDICTION by: Adit Aviv Kfir Grichman introduction: The speech signal has been ...
- ch5 MySQL 备份与恢复
第 5 章 MySQL 备份与恢复 前言 数据库的备份与恢复一直都是 DBA 工作中最为重要的部分之一,也是基本工作之一.任何正式环境的数据库都必须有完整的备份计划和恢复测试,本章内容将主要介绍 My ...
- window_x64微信小程序环境搭建
所需文件地址如下: http://pan.baidu.com/s/1nv0IHhn(ylk7) 1.下载微信开发工具0.7.0_x64 安装完成后,打开程序,进行微信扫码登录 2.下载微信开发工具 ...
- wndows系统命令总结
window8系统下 打开运行窗口----------鼠标放到任务栏的windows图标下,右击,弹出菜单中如上图或者 打开运行窗口---------按“WIN+R”键, cmd-------打开命令 ...
- Firefox火狐添加书签功能失灵解决办法
一直使用firefox,书签管理用的是插件Tabmix.感觉很好,只是不知道从那天起添加书签就不灵了!不论是Ctrl+D快捷键,还是Add Bookmark Here2插件,甚至“将此页加为书签”的菜 ...
- WordPress博客搬家注意事项
博客域名还有一段时间就到期了,准备更换域名和空间,会出现一些问题,我这里在网上收集整理了一下,基本上会遇到两个重要的问题. 首先第一个问题就是数据的搬迁中出现的错误. 我这里用的是phpmyadmin ...
- ODAC (V9.5.15) 学习笔记(二十一)数据复制
用TVirtualTable在内存中缓存TOraQuery中的数据,主要应用场景是参照其他数据,需要将TOraQuery中的数据复制到TVirtualTable,由于没有类似于TClientDataS ...
- Backbone1.0.0数据验证的变化
0.5.3版本对Model数据验证时,绑定Error就可以了: (function(){ var Model = Backbone.Model.extend({ initialize : functi ...