您的位置:首页 > 其它

编写led驱动及其实验过程

2015-04-12 16:37 381 查看
1,首先需要打开Ubuntu和putty(远程控制终端)

2,在Ubuntu下运行s5pc100_led程序:s5pc100_led(Makefile s5pc100_led.c test.c)

(1)Make程序:

/*******************Makefile****************/

MOD_NAME = s5pc100_led

obj-m = $(MOD_NAME).o

KERN_DIR = /home/linux/linux-2.6.35-farsight
#KERN_DIR = /lib/modules/$(shell uname -r)/build

all:
make -C $(KERN_DIR)  M=$(shell pwd) modules
arm-cortex_a8-linux-gnueabi-gcc test.c
cp a.out *.ko /source/rootfs

clean:
rm  -rf *.o *.ko  *.mod.c  *.order \
*.symvers .*.cmd .*versions a.out .*.swp

backup:
tar cvf ../$(MOD_NAME).tar.gz ../$(MOD_NAME)
cp ../$(MOD_NAME).tar.gz /mnt/hgfs/ubuntu_share


应用程序test.c

/**********test.c*********************
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/ioctl.h>

#define CMD_ON   _IO('k', 0)
#define CMD_OFF  _IO('k', 1)

int main(int argc, const char *argv[])
{
int fd;

fd = open("/dev/led", O_RDWR);

if (fd < 0) {
perror("open");
return -1;
}
while (1) {
ioctl(fd, CMD_ON, 0);
sleep(1);
ioctl(fd, CMD_OFF, 0);
sleep(1);
}
close(fd);
return 0;
}


/**************s5pc100_led.c***********************/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <asm/uaccess.h>  /*copy_to_user copy_from_user*/
#include <asm/io.h>          /*ioremap*/

#define NUM_MINORS 1
#define MINOR_NR 0
#define DEV_NAME "s5pc100_led_char"
#define KBUF_SIZE 50

#define CMD_ON   _IO('k', 0)
#define CMD_OFF  _IO('k', 1)

#define GPG3CON 0xe03001c0
#define GPG3DAT 0xe03001c4
static int *vgpg3con;
static int *vgpg3dat;

static struct cdev s5pc100_led_cdev;
static int s5pc100_led_major = 250; /*Documentation/devices.txt*/
static dev_t s5pc100_led_devno;
static char kbuf[KBUF_SIZE];

MODULE_LICENSE("GPL");

/**
* led_init: init led pins
*/
void led_init(void)
{
writel((readl(vgpg3con) & ~(0xffff)) | 0x1111, vgpg3con);
}

void led_exit(void)
{
writel(readl(vgpg3dat) & ~(0xf), vgpg3con);
}

static int s5pc100_led_open(struct inode *nodp, struct file *filp)
{
led_init();
printk(KERN_INFO "s5pc100_led open! \n");
return 0;
}
static int s5pc100_led_release(struct inode *nodp, struct file *filp)
{
led_exit();
printk(KERN_INFO "s5pc100_led release! \n");
return 0;
}

static long
s5pc100_led_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
switch (cmd) {
case CMD_ON:
printk(KERN_INFO "cmd = %d arg = %lu \n", cmd, arg);
writel(readl(vgpg3dat) | (1 << arg), vgpg3dat);
break;
case CMD_OFF:
printk(KERN_INFO "cmd = %d arg = %lu \n", cmd, arg);
writel(readl(vgpg3dat) & ~(1 << arg), vgpg3dat);
break;
default:
printk(KERN_INFO "no such command! \n");
break;
}
return 0;
}

struct file_operations s5pc100_led_ops = {
.open = s5pc100_led_open,
.release = s5pc100_led_release,
.unlocked_ioctl = s5pc100_led_unlocked_ioctl,
};

static int __init s5pc100_led_init(void)
{
int ret;

/*construct cdev number*/
s5pc100_led_devno = MKDEV(s5pc100_led_major, MINOR_NR); //s5pc100_led_major << 20 | s5pc100_led_minor;
ret = register_chrdev_region(s5pc100_led_devno, NUM_MINORS, DEV_NAME);

/*register char dev number*/
if (ret) {
printk(KERN_WARNING "register_chrdev_region failed! \n");
ret = alloc_chrdev_region(&s5pc100_led_devno, MINOR_NR, NUM_MINORS, DEV_NAME);
if (ret) {
printk(KERN_WARNING "alloc chrdev_region failed! \n");
goto err_0;
}
}

/*register char device*/
/*cdev initialize*/
cdev_init(&s5pc100_led_cdev, &s5pc100_led_ops);

/*add to kernel*/
ret = cdev_add(&s5pc100_led_cdev, s5pc100_led_devno, NUM_MINORS);
if (ret) {
printk(KERN_WARNING "cdev add failed! \n");
goto err_1;
}

/*physical address --->  virtual address*/
vgpg3con = ioremap(GPG3CON, 4);
vgpg3dat = ioremap(GPG3DAT, 4);

printk(KERN_INFO "s5pc100_led_init ! \n");
return 0;

/*error management*/
err_1:
unregister_chrdev_region(s5pc100_led_devno, NUM_MINORS);
err_0:
return ret;
}

static void __exit s5pc100_led_exit(void)
{
iounmap(vgpg3con);
iounmap(vgpg3dat);
cdev_del(&s5pc100_led_cdev);
unregister_chrdev_region(s5pc100_led_devno, NUM_MINORS);
printk("s5pc100_led_exit ! \n");
}

module_init(s5pc100_led_init);
module_exit(s5pc100_led_exit);

MODULE_AUTHOR("minj@farsight.com.cn");
MODULE_DESCRIPTION("just for test!");


操作过程如下:


3,在putty下做如下操作:


4,yunx后的终端效果如下:(FS_S5PC100 -A板面会有跑马灯现象)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: