首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 驱动开发 >

!更改驱动程序,将控制由ioctl 形式改为write形式,并添加read接口,通过read可获取LED 状态

2012-03-18 
求助!更改驱动程序,将控制由ioctl 形式改为write形式,并添加read接口,通过read可获取LED 状态。C/C++ code

求助!更改驱动程序,将控制由ioctl 形式改为write形式,并添加read接口,通过read可获取LED 状态。

C/C++ code
驱动程序:修改ioctl为write和read方法#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/devfs_fs_kernel.h> #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/arch/regs-gpio.h> #include <asm/hardware.h>  #define DEVICE_NAME "led" #define LED_MAJOR 231 #define LED_BASE  (0xE1180000)  static int eduk4_led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg{   unsigned char status;    switch(cmd) {   case 0:   case 1:     if (arg > 4) {       return -EINVAL;     }     status = inb(LED_BASE);     if(0 == cmd){       status &= ~(0x1 << arg);     }else if(1 == cmd){       status |= (0x1 << arg);     }     outb(status, LED_BASE);          return 0;   default:     return -EINVAL;   } }  static struct file_operations eduk4_led_fops = {   .owner  =  THIS_MODULE,   .ioctl  =  eduk4_led_ioctl, };  static int __init eduk4_led_init(void) {   int ret;   unsigned char status;    ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &eduk4_led_fops);   if (ret < 0) {     printk(DEVICE_NAME " can't register major number\n");     return ret;   }    devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);    status = inb(LED_BASE);   outb(status & 0xf0,LED_BASE);       printk(DEVICE_NAME " initialized\n");   return 0; }  static void __exit eduk4_led_exit(void) {   unsigned char status;           status = inb(LED_BASE);          outb(status | 0x0f,LED_BASE);    printk(DEVICE_NAME " remove\n");   devfs_remove(DEVICE_NAME);   unregister_chrdev(LED_MAJOR, DEVICE_NAME); }  module_init(eduk4_led_init); module_exit(eduk4_led_exit); MODULE_LICENSE("BSD/GPL"); 测试应用程序#include <stdio.h> #include <stdlib.h> #include <unistd.h>  #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/select.h> #include <sys/time.h>  static int led_fd;  int main(void) {   // open device   led_fd = open("/dev/led", 0);   if (led_fd < 0) {   if (led_fd < 0) {     perror("open device led");     exit(1);   }      printf("Please look at the leds\n");    // led all off   ioctl(led_fd, 1, 0);   ioctl(led_fd, 1, 1);   ioctl(led_fd, 1, 2);   ioctl(led_fd, 1, 3);    close(led_fd);   return 0; } 


[解决办法]
[code=C/C++][/code]
#include <linux/config.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/fs.h> 
#include <linux/init.h> 
#include <linux/devfs_fs_kernel.h> 
#include <linux/miscdevice.h> 
#include <linux/delay.h> 
#include <asm/irq.h> 
#include <asm/io.h> 
#include <asm/arch/regs-gpio.h> 
#include <asm/hardware.h> 
 
#define DEVICE_NAME "led" 
#define LED_MAJOR 231 
#define LED_BASE (0xE1180000) 
 
ssize_t eduk4_led_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos)

unsigned char status; 
 

if (copy_from_user(&status, buf, 1)) {
retval = -EFAULT;
goto out;
}

outb(status, LED_BASE);

return 1;
out:
return 0;


ssize_t eduk4_led_read_read(struct file *filp, char __user *buf, size_t count,


loff_t *f_pos)
{
unsigned char status;

 status = inb(LED_BASE); 
if (copy_to_user(buf, &status, 1)) {
retval = -EFAULT;
goto out;
}
return 1;
out:
return 0;
}
 
static struct file_operations eduk4_led_fops = { 
.owner = THIS_MODULE, 
.read = eduk4_led_read,
.write = edu4_led_write, 
}; 
 
static int __init eduk4_led_init(void) 

int ret; 
unsigned char status; 
 
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &eduk4_led_fops); 
if (ret < 0) { 
printk(DEVICE_NAME " can't register major number\n"); 
return ret; 

 
devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 
DEVICE_NAME); 
 
status = inb(LED_BASE); 
outb(status & 0xf0,LED_BASE);
 
printk(DEVICE_NAME " initialized\n"); 
return 0; 

 
static void __exit eduk4_led_exit(void) 

unsigned char status; 
 
status = inb(LED_BASE); 
outb(status | 0x0f,LED_BASE); 
 
printk(DEVICE_NAME " remove\n"); 
devfs_remove(DEVICE_NAME); 
unregister_chrdev(LED_MAJOR, DEVICE_NAME); 

 
module_init(eduk4_led_init); 
module_exit(eduk4_led_exit); 
MODULE_LICENSE("BSD/GPL"); 



测试应用程序

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
 
#include <sys/ioctl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/select.h> 
#include <sys/time.h> 
 
static int led_fd; 
 
int main(void) 
{
unsigned char status;
unsigned char read_status; 
// open device 
led_fd = open("/dev/led", 0); 
 
if (led_fd < 0) { 
perror("open device led"); 
exit(1); 

 
printf("Please look at the leds\n"); 
 
// led all off 
status = 0xf;
write(led_fd, &status, sizeof(status));
read(led_fd, &read_status, 1);
printf("the leds status is %d \n", _read_status);
close(led_fd); 
return 0; 

大体上就是这样。

热点排行