请教关于platform驱动
#include <linux/types.h>#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <linux/ioctl.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <asm/arch/at91sam9260.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/arch/io.h>
#include <asm/arch/gpio.h>
#define DEV_NAME "AT91SAM9260_LED_SCREEN"
#define LED_SCREEN_MAGIC 'L'
#define LED_SCREEN_ON _IOW(LED_SCREEN_MAGIC,0,int)
#define LED_SCREEN_OFF _IOW(LED_SCREEN_MAGIC,1,int)
#define LED_SCREEN_MINOR 125
#define LED_SCREEN_MAJOR 10
#define LED_SCREEN_CON 0
#define LED_SCREEN_DAT 4
#define LED_SCREEN_UP 8
#define LED_SCREEN_PIN_BASE PIN_BASE + 0x20
int major;
dev_t devNu;
struct cdev led_screen_cdev;
void *led_screen_base;
ssize_t led_screen_read(struct file *filp,char __user *buffer,size_t size,loff_t *offset);
ssize_t led_screen_write(struct file *filp,const char __user *buffer,size_t size,loff_t *offset);
int led_screen_open(struct inode *inode,struct file *filp);
int led_screen_release(struct inode *inode,struct file *filp);
int led_screen_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);
static int led_screen_probe(struct platform_device *pdev);
static int led_screen_remove(struct platform_device *pdev);
static unsigned long led_table [] =
{
//AT91_PIN_PA6,
AT91_PIN_PB0,
};
struct resource led_screen_resource[] = {
={
.start =LED_SCREEN_PIN_BASE,
.end =LED_SCREEN_PIN_BASE + 31,
.flags =IORESOURCE_MEM,
}
};
struct file_operations led_screen_opt ={
.owner =THIS_MODULE,
.ioctl =led_screen_ioctl,
.open =led_screen_open,
.read =led_screen_read,
.write =led_screen_write,
.release =led_screen_release,
};
static struct miscdevice misc_led_screen ={
.minor =MISC_DYNAMIC_MINOR,
.name ="led_screen",
.fops =&led_screen_opt,
};
struct platform_device led_screen_Device= {
.name ="led_screen",
.id =-1,
.num_resources =ARRAY_SIZE(led_screen_resource),
.resource =led_screen_resource,
.dev =
{
.release =led_screen_release,
}
};
struct platform_driver led_screen_Driver ={
.probe =led_screen_probe,
.remove =led_screen_remove,
.driver =
{
.owner =THIS_MODULE,
.name ="led_screen",
}
};
int led_screen_open(struct inode *inode,struct file *filp)
{
at91_set_gpio_value(led_table,1);
//writel(AT91_PIOB,led_screen_base+LED_SCREEN_CON);
//writel(0,led_screen_base+LED_SCREEN_UP);
//writel(0,led_screen_base+LED_SCREEN_DAT);
printk("\n LED_SCREEN open success! \n");
return 0;
}
ssize_t led_screen_read(struct file *filp,char __user *buffer,size_t size,loff_t *offset)
{
return 0;
}
ssize_t led_screen_write(struct file *filp,const char __user *buffer,size_t size,loff_t *offset)
{
return 0;
}
int led_screen_release(struct inode *inode,struct file *filp)
{
at91_set_gpio_value(led_table,1);
printk("\nled_screen_release!\n");
return 0;
}
int led_screen_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
printk ( "cmd = %d", cmd );
at91_set_gpio_value(led_table,cmd);
printk("\nled_screen_ioctl!\n");
return 0;
}
static int led_screen_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev;
int size;
int ret;
at91_set_gpio_output(led_table,1);
at91_set_gpio_value(led_table,0);
dev=&pdev->dev;
printk("\nMatch success!\n");
res = platform_get_resource(pdev,IORESOURCE_MEM,0);
if(res==NULL)
{
dev_err(dev,"no memory resource specified\n");
return -ENOENT;
}
size = res->end-res->start +1;
led_screen_base = ioremap(res->start,size);
if(led_screen_base==NULL)
{
dev_err(dev,"fail to ioremap() region\n");
ret=-EINVAL;
goto err_req;
}
ret=misc_register(&misc_led_screen);
//ret=platform_driver_register();
if(ret)
{
dev_err(dev,"cannot register ledmiscdev!\n");
goto err_misc;
}
err_misc:
iounmap(led_screen_base);
err_req:
return ret;
}
static int led_screen_remove(struct platform_device *pdev)
{
//iounmap(ledbase);这一句有问题,加上就会出现oops
misc_deregister(&misc_led_screen);
return 0;
}
int __init led_screen_init(void)
{
major = LED_SCREEN_MAJOR;
printk("\n LED_SCREEN is %d\n",major);
devNu = MKDEV(LED_SCREEN_MAJOR,LED_SCREEN_MINOR);
platform_device_register(&led_screen_Device);
platform_driver_register(&led_screen_Driver);
return 0;
}
void __exit led_screen_exit(void)
{
platform_driver_unregister(&led_screen_Driver);
platform_device_unregister(&led_screen_Device);
}
module_init(led_screen_init);
module_exit(led_screen_exit);
我现在是这个驱动
但是用insmod的时候能打开LED灯
rmmod的时候能关闭
但是open和ioctl的时候就不能控制LED了!我这个驱动是哪里有问题呢! 沉的好快啊!
顶下! open和ioctl的时候,printk的打印信息能出来吗,用dmesg来看看 open的能出来,但是ioctl不能哈! 现在我程序修改了!但是open的时候感觉没有和驱动的open联系上!
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/arch/io.h>
#include <asm/arch/gpio.h>
#include <linux/delay.h>
#include <asm/arch/at91sam9260.h>
#include <asm/arch/at91_pio.h>
#include <linux/miscdevice.h>
#define DEV_NAME "led_screen"
#define PORTB_BASE 0xfffff600// PORTB
ssize_t screen_read(struct file *filp,char __user *buffer,size_t size,loff_t *offset);
ssize_t screen_write(struct file *filp,const char __user *buffer,size_t size,loff_t *offset);
int screen_open(struct inode *inode,struct file *filp);
int screen_release(struct inode *inode,struct file *filp);
int screen_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg);
static int led_screen_probe ( struct platform_device *dev );
void led_screen_release(struct device * dev);
// 这个是GPIO的物理地址的基址
static void __iomem *led_screen_base;
static struct resource *led_screen_mem;
// 控制LED屏的GPIO口
static unsigned long led_screen_table [] =
{
//AT91_PIN_PA6,
AT91_PIN_PB0,
};
struct resource led_screen_resource[] = {
={
.start =PORTB_BASE,
.end =PORTB_BASE + 512,
.flags =IORESOURCE_MEM,
}
};
struct platform_device led_screen_device= {
.name =DEV_NAME,
.id =-1,
.num_resources =ARRAY_SIZE(led_screen_resource),
.resource =led_screen_resource,
.dev ={
.release =led_screen_release,
}
};
int screen_open(struct inode *inode,struct file *filp)
{
printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
writel( 0x0000000f, led_screen_base + PIO_SODR );
return 0;
}
ssize_t screen_read(struct file *filp,char __user *buffer,size_t size,loff_t *offset)
{
return 0;
}
ssize_t screen_write(struct file *filp,const char __user *buffer,size_t size,loff_t *offset)
{
return 0;
}
int screen_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
return 0;
}
int screen_release(struct inode *inode,struct file *filp)
{
return 0;
}
struct file_operations led_screen_opt ={
.owner =THIS_MODULE,
.ioctl =screen_ioctl,
.open =screen_open,
.read =screen_read,
.write =screen_write,
.release =screen_release,
};
static struct miscdevice led_screen_misc ={
.minor =MISC_DYNAMIC_MINOR,
//.name ="screen",
.name = DEV_NAME,
.fops =&led_screen_opt,
};
void led_screen_release(struct device * dev)
{
printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
}
static int led_screen_probe ( struct platform_device *dev )
{
struct resource *res;
int ret = 0;
int size;
printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
res = platform_get_resource( dev, IORESOURCE_MEM, 0 );
if (res == NULL)
{
printk("no memory resource specified\n");
return -ENOENT;
}
size = (res->end-res->start)+1;
led_screen_mem = request_mem_region(res->start, size, dev->name);
if (NULL == led_screen_mem)
{
printk("failed to get memory region\n");
ret = -ENOENT;
goto err_req;
}
led_screen_base = ioremap(res->start, size);
if (led_screen_base == 0)
{
printk("failed to ioremap() region\n");
ret = -EINVAL;
goto err_req;
}
printk("resource is ok!\n");
/*ret=misc_register(&led_screen_misc);
if(ret)
{
printk("cannot register led_screen_misc miscdev!\n");
iounmap(led_screen_base);
return ret;
}
*/
writel( 0x0000000f, led_screen_base + PIO_PER );
writel( 0x0000000f, led_screen_base + PIO_PUER );
writel( 0x0000000f, led_screen_base + PIO_ODSR );
writel( 0x0000000f, led_screen_base + PIO_OER );
writel( 0x0000000f, led_screen_base + PIO_CODR );
//at91_set_gpio_output(led_screen_table,1);
//at91_set_gpio_value(led_screen_table,0);
printk("resource is ok!\n");
return ret;
err_req:
release_resource(led_screen_mem);
kfree(led_screen_mem);
printk("resource is fail!\n");
return ret;
}
static int led_screen_remove ( struct platform_device *dev )
{
printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
return 0;
}
static struct platform_driver led_screen_driver = {
.probe = led_screen_probe,
.remove = led_screen_remove,
.driver = {
.owner = THIS_MODULE,
.name = DEV_NAME,
},
};
static int __init led_screen_init ( void )
{
int ret = 0;
printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
//at91_set_gpio_output(led_screen_table,1);
//at91_set_gpio_value(led_screen_table,0);
ret = platform_device_register ( &led_screen_device );
if ( ret )
{
platform_device_unregister ( &led_screen_device );
printk ( "platform_device_register is fail!\n" );
return ret;
}
ret=misc_register(&led_screen_misc);
if(ret)
{
printk("cannot register led_screen_misc miscdev!\n");
iounmap(led_screen_base);
return ret;
}
printk ( "platform_device_register is ok!\n" );
ret = platform_driver_register ( &led_screen_driver );
if ( ret )
{
printk ( "platform_driver_register is fail!\n" );
platform_driver_unregister ( &led_screen_driver );
return ret;
}
printk ( "platform_driver_register is ok!\n" );
return ret;
}
static void __exit led_screen_exit ( void )
{
printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
//at91_set_gpio_value(led_screen_table,1);
writel( 0x0000000f, led_screen_base + PIO_SODR );
platform_driver_unregister ( &led_screen_driver );
misc_deregister(&led_screen_misc);
platform_device_unregister ( &led_screen_device );
}
module_init ( led_screen_init );
module_exit ( led_screen_exit );
MODULE_AUTHOR("m");
MODULE_DESCRIPTION("this is led_screen driver modules");
MODULE_LICENSE("Dual BSD/GPL");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(void)
{
int fd;
printf("%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
fd=open("/sys/class/misc/led_screen",0);
if(fd<0)
{
printf("can not open /sys/class/misc/led_screen\n");
goto end1;
}
//while(1)
{
//ioctl(fd,0,0);
//sleep(1);
//ioctl(fd,1,0);
printf ( "*********\n" );
//sleep(1);
}
close(fd);
end1:
return 0;
}
希望大侠能帮我看看是!问题出在哪里?
$insmod led_screen.ko
led_screen_init:Aug 31 2010,09:55:58
platform_device_register is ok!
led_screen_probe:Aug 31 2010,09:55:58
resource is ok!
resource is ok!
platform_driver_register is ok!
$./ledtest
main:Aug 31 2010,09:41:28
*********
$rmmod led_screen.ko
led_screen_exit:Aug 31 2010,09:55:58
led_screen_remove:Aug 31 2010,09:55:58
led_screen_release:Aug 31 2010,09:55:58
$dmesg
led_screen_init:Aug 31 2010,09:55:58
platform_device_register is ok!
led_screen_probe:Aug 31 2010,09:55:58
resource is ok!
resource is ok!
platform_driver_register is ok!
led_screen_exit:Aug 31 2010,09:55:58
led_screen_remove:Aug 31 2010,09:55:58
led_screen_release:Aug 31 2010,09:55:58
$
$insmod led_screen.ko
led_screen_init:Aug 31 2010,09:55:58
platform_device_register is ok!
led_screen_probe:Aug 31 2010,09:55:58
resource is ok!
resource is ok!
platform_driver_register is ok!
$ls /sys/bus/platform/devices/
at91_nand at91_udc atmel_usart.1led_screen
at91_ohci at91_wdt atmel_usart.2macb
at91_rtt.0 atmel_usart.0i2c-gpio ssc.0
$ls /sys/bus/platform/drivers
at91_nand at91_wdt i2c-gpio rtc-at91sam9
at91_ohci atmel_usart led_screen ssc
at91_udc gen_nand macb
$ls /sys/devices/
platformsystem
$ls /sys/devices/platform/
at91_nand at91_udc atmel_usart.1led_screen uevent
at91_ohci at91_wdt atmel_usart.2macb
at91_rtt.0 atmel_usart.0i2c-gpio ssc.0
$ls /sys/class/misc/
fuse led_screenwatchdog
$
以上可以看到都添加到系统里面去了啊! 1、fd=open("/sys/class/misc/led_screen",0),0表示的读写权限是什么?
2、在执行你的测试程序时,没看到screen_open()里的printk有打印出来,会不会在创建设备节点时,设备号没对上,打开了其它的设备。
3、如果screen_open()有执行了,那直接对gpio的操作应该起作用,led会有变化。 fd=open("/sys/class/misc/led_screen
有没有这样打开设备的哈 。?? 可不可以直接用platform_device和platform_driver写驱动哈!
不用msic_device
但是platform_device没有文件操作函数哈!(open函数等)
页:
[1]