http://blog.chinaunix.net/uid-29512885-id-5754512.html
http://blog.chinaunix.net/uid-29512885-id-5752440.html
根据上面两篇记录,可以整合成内核驱动的编程写法。
代码中新需要的函数:
实地址转换成虚拟地址,ioremap
void *ioremap(unsinged long phys_addr, unsigned long size)
phys_addr:要映射的起始地IO地址
size:要映射的空间的大小
头文件:linux/io.h
writel() 往内存映射的 I/O 空间上写数据,wirtel() I/O 上写入 32 位数据 (4字节)。
原型:
void writel (unsigned char data , unsigned short addr );
data:需要写入的数据
addr:写入数据的地址
头文件:linux/io.h?
led.c:
-
#include <linux/module.h>
-
#include <linux/init.h>
-
#include <linux/cdev.h>
-
#include <linux/fs.h>
-
#include <linux/io.h>
-
#include <asm/uaccess.h>
-
#include "led.h"
-
-
#define GPBCON 0x56000010
-
#define GPBDAT 0x56000014
-
-
unsigned int *led_config; //定义CONTRAL控制器指针
-
unsigned int *led_data; //定义DATA控制器指针
-
-
struct cdev led_dev; //分配设备号
-
dev_t led_devno;
-
-
int led_open(struct inode *inode, struct file *filp)
-
{
-
led_config = ioremap(GPBCON, 4);
-
writel(0x15400, led_config);
-
-
led_data = ioremap(GPBDAT, 4);
-
-
return 0;
-
}
-
-
long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-
{
-
switch(cmd) {
-
case LED_ON:
-
writel(0x6bf, led_data);
-
return 0;
-
-
case LED_OFF:
-
writel(0x7ff, led_data);
-
return 0;
-
-
default:
-
return -EINVAL;
-
}
-
}
-
-
struct file_operations led_fops = {
-
.open = led_open,
-
.unlocked_ioctl = led_ioctl,
-
};
-
-
static int led_init()
-
{
-
cdev_init(&led_dev, &led_fops); //设备初始化
-
-
alloc_chrdev_region(&led_devno, 0, 1, "myled"); //动态分配设备号
-
cdev_add(&led_dev, led_devno, 1); //添加设备
-
-
return 0;
-
}
-
-
static void led_exit()
-
{
-
cdev_del(&led_dev); //注销设备
-
unregister_chrdev_region(led_devno, 1); //释放设备号
-
}
-
-
module_init(led_init);
-
module_exit(led_exit);
led.h:
-
#define LED_MAGIC 'L'
-
#define LED_ON _IO(LED_MAGIC, 0)
-
#define LED_OFF _IO(LED_MAGIC, 1)
led_app.c:
-
#include <sys/stat.h>
-
#include <sys/types.h>
-
#include <fcntl.h>
-
#include <stdio.h>
-
#include <sys/ioctl.h>
-
#include "led.h"
-
-
int main(int argc, char *argv[])
-
{
-
int fd;
-
int cmd;
-
if(argc < 2)
-
{
-
printf("please enter the second para!\n");
-
return 0;
-
}
-
-
cmd = atoi(argv[1]);
-
-
fd = open("/dev/myled", O_RDWR);
-
-
if(cmd == 1)
-
ioctl(fd, LED_ON);
-
else
-
ioctl(fd, LED_OFF);
-
-
return 0;
-
}
遇到的错误:
open实现的函数没有return 0;
阅读(645) | 评论(0) | 转发(0) |