- 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,