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, &param_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)的更多相关文章

  1. ok6410 android driver(5)

    Test the android driver by JNI (Java Native Interface), In the third article, we know how to compile ...

  2. ok6410 android driver(11)

    This essay, I go to a deeply studying to android HAL device driver program. According to the android ...

  3. 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 ...

  4. ok6410 android driver(3)

    This article discusses the Makefile and how to port the module to different platform (localhost and ...

  5. ok6410 android driver(12)

    In this essay, I will talk about how to write the service libraries. TIPS : I won't discuss the name ...

  6. ok6410 android driver(10)

    From this essay, we go to a new discussion "Android Hardware Abstraction Layer". In this e ...

  7. ok6410 android driver(7)

    This article talk about how to test device driver on JNI. There are two ways to test the device driv ...

  8. ok6410 android driver(6)

    This is a short essay about the mistakes in compiling ok6410 android-2.3 source codes. If there is n ...

  9. ok6410 android driver(1)

    target system : Android (OK6410) host system : Debian Wheezy AMD64 1.Set up android system in ok6410 ...

随机推荐

  1. 【linux】如何将Vim打造成一个成熟的IDE

    如果你稍微写过一点代码,就能知道“集成开发环境”(IDE)是多么的便利.不管是Java.C还是Python,当IDE会帮你检查语法.后台编译,或者自动导入你需要的库时,写代码就变得容易许多.另外,如果 ...

  2. IntelliJ IDEA + Maven环境编写第一个hadoop程序

    1. 新建IntelliJ下的maven项目 点击File->New->Project,在弹出的对话框中选择Maven,JDK选择你自己安装的版本,点击Next 2. 填写Maven的Gr ...

  3. u3d动态加入模型

    楼层一层一层的加,把模型分开,弄成prefab放到Resourse文件夹里,在代码里用Instantiate(Resources.Load("模型名字") as GameObjec ...

  4. Silverlight:版本控制的衍化

    版本控制是企业开发中一个老生长谈的主题,这也是大部分公司新人进来后需要接纳的一个基础知识体系. 从08年首次接触商业软件编写后,这几年先后接触了SVN,TFS,Git这几个主要的版本控制器,但是并没有 ...

  5. 提高FOR插入数据库动作的优化代码

    await Task.Factory.StartNew(() => Parallel.ForEach(result.data.o, s => { sql = "insert in ...

  6. 针对 SQL Server 2008 在Windows Server 2008上的访问配置 Windows 防火墙

    现在Windows Server 2008 服务器用的越来越多,2008的防火墙比2003的有了很大的增强,安全性有了更大的提高. 甚至80端口的出站默认都是被关闭的.所以如果在2008Server上 ...

  7. 康力优蓝机器人 -- 优友U05类人型机器人发布

    [寒武计划]优友U05类人型机器人发布: http://digi.tech.qq.com/a/20151124/043234.htm?pgv_ref=aio2015&ptlang=2052 北 ...

  8. SZ,RZ传送文件

    linux 和window之间通过xshell的命令 SZ,RZ传送文件:

  9. uniGUI试用笔记(十三)调用WebService

    今天尝试用uniGUI做Web服务器,调用应用服务器的WebService,遇到些问题记录下来备忘. 1.对WebService的调用同一般App程序,只是注意如果WebService的执行时间较长, ...

  10. CCF推荐国际学术会议

    类别如下计算机系统与高性能计算,计算机网络,网络与信息安全,软件工程,系统软件与程序设计语言,数据库.数据挖掘与内容检索,计算机科学理论,计算机图形学与多媒体,人工智能与模式识别,人机交互与普适计算, ...