嵌入式 字符设备驱动经典示例
来源:互联网 发布:java导出excel的方法 编辑:程序博客网 时间:2024/06/04 15:57
1、驱动led_joseph.c
{
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <asm/dma.h>
#include <asm/delay.h>
#include <linux/delay.h>
#define DEVICE_NAME "JOSEPH_LED"
#define HW_REG(reg) *((volatile unsigned int *)(reg))
#define GPIO_1_LED_DAT 0x201503FC
#define GPIO_1_LED_DIR 0x20150400
#define GPIO_1_MUX 0x200f0004
#define GPIO_G_DAT 0x201a03fc
#define GPIO_G_DIR 0x201a0400
#define GPIO_G_MUX 0x200f0080
volatile unsigned long *gpio1_1data = NULL;
volatile unsigned long *gpio1_1dir = NULL;
volatile unsigned long *gpio6_0data = NULL;
volatile unsigned long *gpio6_0dir = NULL;
volatile unsigned long *gpio_1_mux = NULL;//red
volatile unsigned long *gpio_6_mux = NULL;//blue
static dev_t joseph_led_devid;
static struct class *joseph_led_class;
static struct cdev *joseph_led_cdev;
static struct device *joseph_led_device;
static int joseph_led_open(struct inode * in, struct file *f)
{
return 0;
}
static ssize_t joseph_led_read(struct file *f, char __user *buf, size_t size, loff_t *off)
{
unsigned char joseph_led_buf[8] = {0};
static int led_status =0;
static int red_led_status = 0;//0 - on ; 1 - off
static int green_led_status = 0;//0 - on ; 1 - off
memset(joseph_led_buf,0,8);
#if 0
*gpio_6_mux&= ~BIT_MASK(0); //gpio
*gpio_1_mux &= ~BIT_MASK(0); //gpio
*gpio1_1dir &= ~(1<<1);//input
*gpio6_0dir &= ~(1<<0);//input
#endif
red_led_status = *gpio1_1data;
green_led_status = *gpio6_0data;
if((red_led_status & 0x2) == 0)
{
led_status = 0;
sprintf(joseph_led_buf,"%d",led_status);
}
if((red_led_status & 0x2) == 2)
{
led_status = 1;
sprintf(joseph_led_buf,"%d",led_status);
}
if((green_led_status & 0x1) == 0)
{
led_status = 0;
sprintf(joseph_led_buf+1,"%d",led_status);
}
if((green_led_status & 0x1) == 1)
{
led_status = 1;
sprintf(joseph_led_buf+1,"%d",led_status);
}
mdelay(500);
copy_to_user(buf,joseph_led_buf,sizeof(joseph_led_buf));
return sizeof(joseph_led_buf);
}
static ssize_t joseph_led_write(struct file *f, const char __user *buf, size_t size, loff_t *off)
{
char buf_tmp[8];
copy_from_user(buf_tmp, buf, size); //
printk(KERN_INFO"joseh_led_write begin %s !\n",buf_tmp);
*gpio1_1dir |= 1<<1;//output
*gpio6_0dir |= 1<<0;//output
mdelay(5);
*gpio_1_mux &= ~BIT_MASK(0); //gpio
mdelay(5);
*gpio_6_mux &= ~BIT_MASK(0); //gpio
mdelay(5);
if( strcmp(buf_tmp,"00") == 0)
{
*gpio1_1data &= ~BIT_MASK(1);//on
mdelay(5);
*gpio6_0data &= ~BIT_MASK(0);//on
mdelay(5);
}
if( strcmp(buf_tmp,"01") == 0)
{
*gpio1_1data &= ~BIT_MASK(1);//on
mdelay(5);
*gpio6_0data |= BIT_MASK(0);//off
mdelay(5);
}
if( strcmp(buf_tmp,"10") == 0)
{
*gpio1_1data |= BIT_MASK(1);//off
mdelay(5);
*gpio6_0data &= ~BIT_MASK(0);//on
mdelay(5);
}
if( strcmp(buf_tmp,"11") == 0)
{
*gpio1_1data |= BIT_MASK(1);//off
mdelay(5);
*gpio6_0data |= BIT_MASK(0);//off
mdelay(5);
}
return size;
}
static struct file_operations joseph_led_fops = {
.owner = THIS_MODULE,
.open = joseph_led_open,
.read = joseph_led_read,
.write = joseph_led_write
};
static int __init joseph_led_init(void)
{
int ret;
ret = alloc_chrdev_region(&joseph_led_devid, 0, 1,DEVICE_NAME);
if(ret < 0)
{
printk(KERN_ERR "can't allocate char device ID\n");
return -1;
}
joseph_led_class = class_create(THIS_MODULE, DEVICE_NAME);
joseph_led_cdev = cdev_alloc();
if(joseph_led_cdev == NULL)
{
printk(KERN_ERR "can't allocate cdev struct \n");
return -1;
}
joseph_led_cdev->ops = &joseph_led_fops;
joseph_led_cdev->owner = THIS_MODULE;
ret = cdev_add(joseph_led_cdev,joseph_led_devid,1);
if(ret < 0)
{
printk(KERN_ERR "can't add cdev \n");
return -1;
}
joseph_led_device = device_create(joseph_led_class,NULL,joseph_led_devid,NULL,"joseph_led");
printk("Congratulate joseph_led_init ok !\n");
gpio1_1data = ioremap_nocache((unsigned long)0x201503fc, (unsigned long)0x10000);
gpio1_1dir = ioremap_nocache((unsigned long)0x20150400, (unsigned long)0x10000);
gpio6_0data= ioremap_nocache((unsigned long)GPIO_G_DAT, (unsigned long)0x10000);
gpio6_0dir= ioremap_nocache((unsigned long)GPIO_G_DIR, (unsigned long)0x10000);
gpio_1_mux = ioremap_nocache((unsigned long)GPIO_1_MUX, (unsigned long)0x10000);
gpio_6_mux = ioremap_nocache((unsigned long)GPIO_G_MUX, (unsigned long)0x10000);
return 0;
}
static void __exit joseph_led_exit(void)
{
unregister_chrdev_region(joseph_led_devid, 1);
device_destroy(joseph_led_class, joseph_led_devid);
cdev_del(joseph_led_cdev);
class_destroy(joseph_led_class);
iounmap(gpio1_1data);
iounmap(gpio1_1dir);
iounmap(gpio_1_mux);
iounmap(gpio6_0data);
iounmap(gpio6_0dir);
iounmap(gpio_6_mux);
printk("Congratulate joseph_led_init Rmmod ok !\n");
}
module_init(joseph_led_init);
module_exit(joseph_led_exit);
MODULE_AUTHOR("xxxx");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Device Driver for joseph_led ! ");
}
2、Makefile
{
ifneq ($(KERNELRELEASE),)
obj-m := led_joseph.o
else
KERNELDIR ?= /home/kongjun/mywork/develop_kj/Hi3518_SDK_V1.0.3.0/osdrv/kernel/linux-3.0.y
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
}
3、上层应用
{
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define LED_DEV "/dev/joseph_led"
int main(int argc , char *argv[])
{
#if 1
int i;
int fd = -1;
char buf[8];
char *buf_write = NULL;
if((fd=open(LED_DEV, O_RDWR))<0){
printf("Error opening %s can device\n", LED_DEV);
return 1;
}
buf_write = argv[1];
write(fd,buf_write,8);
#else
int i;
int fd = -1;
char buf[8];
if((fd=open(LED_DEV, O_RDWR))<0){
printf("Error opening %s can device\n", LED_DEV);
return 1;
}
read(fd,buf,8);
printf("%s %d The status of led is %s\n",__FUNCTION__,__LINE__,buf);
#endif
close(fd);
return 0;
}
}
- 嵌入式 字符设备驱动经典示例
- 嵌入式linux字符设备驱动
- 嵌入式linux字符设备驱动
- 嵌入式 字符设备驱动编程
- linux字符设备驱动示例
- 简单字符设备驱动示例
- 嵌入式 globalmem虚拟字符设备驱动雏形
- 嵌入式Linux之字符设备驱动
- 嵌入式Linux字符设备驱动模型详解
- linux早期经典字符设备驱动模型
- 【嵌入式Linux驱动开发】三、字符设备驱动(一)
- 【嵌入式Linux驱动开发】三、字符设备驱动(二)
- 嵌入式Linux字符设备驱动LED驱动编写
- 嵌入式Linux字符设备驱动LED驱动编写
- 嵌入式学习-驱动开发-lesson1-字符设备驱动模型
- 嵌入式学习-驱动开发-lesson2-LED字符设备驱动
- 07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-LED字符设备驱动
- scull0字符设备驱动示例(参考《Linux设备驱动程序》)
- 用结构计算两个有理数的和。
- 紫外线消毒器:飞利浦紫外线杀菌灯TUV36W
- hadoop input文件路径匹配
- [Linux学习笔记]系统分区知识点归纳
- iOS使用xib文件创建一个组件为子控件,进行复用
- 嵌入式 字符设备驱动经典示例
- 如何制作 iOS ipa - Ad-Hoc
- word2vec 中的数学原理详解(三)背景知识
- Android:从assets资源目录下安装apk
- convmv 解决GBK 迁移到 UTF-8 ,中文 文件名乱码
- Android入门笔记 - 数据存储 - SharedPreferences
- 紫外线消毒器:飞利浦紫外线杀菌灯TUV55W
- python学习笔记(一)
- android实现增量更新