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 ...
随机推荐
- discuz 使用阿里云OSS
discuz 使用阿里云OSS (转)http://bbs.aliyun.com/read/239257.html 说明:我绑定了二级域名,本演示采用二级域名oss来介绍,我实际使用的是二级域名pic ...
- js判断密码强度
html代码: <form name="form1" action=""> 密码:<input type="password&quo ...
- ASP lable标签显示过长,自动换行。
<asp:Label ID="lab_BeforPostR" runat="server" CssClass="labSty" Wid ...
- js数据类型判断和数组判断
这么基础的东西实在不应该再记录了,不过嘛,温故知新~就先从数据类型开始吧 js六大数据类型:number.string.object.Boolean.null.undefined string: 由单 ...
- 2. MongoDB基本操作 —— 用Mongo.exe操作数据库增删改查
一.开篇 传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成,MongoDB是由数据库(database).集合(collection).文档对象 ...
- C#集合 -- Equality和Order插件
在前面的文章C#相等性比较和C#排序比较中,我已经叙述了类型相等,类型哈希,和类型比较的.NET标准协议.实现了这些协议的类型在一个字典或者列表中也可以正常工作.但是需要注意的是: 只有当类型的Equ ...
- 在Windows2008系统中利用IIS建立FTP服务器
一.服务器管理器 1.2008的系统使用服务器管理器,选择角色,因为我之前已经开启了IIS服务器角色,所以我现在只要添加角色服务即可,如果你没有开启过的话,直接添加角色即可. 2.选择WEB服 ...
- 浅析 mondrian 模式文件 Schema
1.前言 前面几篇文章一经介绍过saiku.模式文件和MDX的关系.通俗点说模式文件(Schema)就是一个xml,里面定义了一个虚拟立方体,共MDX查询语言使用. 2.模式文件 Schema 最顶层 ...
- Android开发之Canvas rotate方法释疑
Canvas的rotate()函数本应该是很简单的一个函数,但是由于api手册言之不详,使用中难免有吃不准的地方.下面所记录的几点,都是我在使用中所迷惑过的问题,特此记录. 1,坐标原点在哪里? 如果 ...
- linux下备份mysql命令
一,数据库的备份与导入 1),数据库的备份 1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名例:mysqldump -u dbadmin -p myblog ...