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 ...
随机推荐
- SQL Server死锁
SQL Server死锁 多个事务之间互相等待对方的资源,导致这些事务永久等待 注意是永久等待,而非长事务 死锁的4个条件 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程 ...
- 利用Mysql提供的字符串方法查找字符串中某字符出现的次数
有这么一个需求,查出分类中没有子分类的一级分类,脑海中首次出现的解决思路和这样的 先使用PHP查出所有的一级分类 递归查询一级分类是否有子分类 将没有子分类的一级分类汇总 但觉的这样处理太麻烦了,然后 ...
- 微信公众平台开发视频教程-03-获取Access Token和获取微信服务器IP,添加微信菜单
1 获取access token 此token是以后每次调用微信接口都会带上的票据,token是公众号全局唯一票据,在调用其他接口之前都需要先得到token,taoken长度至少512个字符,通常用s ...
- 如何在C语言中调用Swift函数
在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...
- Service Station - An Introduction To RESTful Services With WCF
Learning about REST An Abstract Example Why Should You Care about REST? WCF and REST WebGetAttribute ...
- RHEL 6 或者 Oracle Linux 6, 不关机识别新添加的scsi硬盘
下面看一下在系统不重启的情况,如何让系统认识新的磁盘,并能对其分区与格式化1.在开机状态下新增磁盘2.执行下面的命令 echo "- - -" > /sys/class/sc ...
- LINQ TO ENTITY 根据Birthday获取Age
from emp in EmployeeInfo let years = EntityFunctions.DiffYears(emp.Birthday.Value,DateTime.Now) let ...
- C# 向Http服务器送出 POST 请求
//向Http服务器送出 POST 请求 public string m_PostSubmit(string strUrl,string strParam) { string strResult = ...
- IOS 开发环境,证书和授权文件等详解
(转自:http://blog.csdn.net/gtncwy/article/details/8617788) 一.成员介绍1. Certification(证书)证书是对电脑开发资格的认证, ...
- 64位Linux下编译搭建Nginx1.5与PHP5.5(CentOS6.4)
(1)安装Nginx1.5.2更新Nginx和PHP的依赖包yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng \libp ...