20114016039 发表于 2012-2-27 16:49:16

关于S3C6410LED驱动出现的问题~求助!

下面是我的驱动程序,用ioctl方法写的!


#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>

#include "memdev.h"

#define DEVICE_NAME "leds"

MODULE_AUTHOR("chenggang");
MODULE_LICENSE("Dual BSD/GPL");

void *XIE_GPKCON;
void *XIE_GPKDAT;

static u32 GPKDAT_SAVE;
static u32 GPKCON_SAVE;

static void gpk_iomap(void)
{
        XIE_GPBCON = ioremap(0x7F008800,0x4);
        XIE_GPBDAT = ioremap(0x7F008808,0x4);
}

static void unmap_gpb(void)
{
    iounmap(XIE_GPBCON);
    iounmap(XIE_GPBDAT);
}

static void resave_led_reg(void)
{
    __raw_writel(resave_gpbcon,R_GPBCON);
    __raw_writel(resave_gpbdat,R_GPBDAT);
}

       
static int sbc6410_leds_ioctl(
        struct inode *inode,
        struct file *file,
        unsigned int cmd,
        unsigned long arg)
{
          /* 检测命令的有效性 */
if (_IOC_TYPE(cmd) != MEMDEV_IOC_MAGIC)
      return -EINVAL;
if (_IOC_NR(cmd) > MEMDEV_IOC_MAXNR)
      return -EINVAL;
      
/* 根据命令,执行相应的操作 */
        switch(cmd) {
        u32 tmp;
        case MEMDEV_IOCOFF:
                     tmp = __raw_readl(XIE_GPKDAT); //从内存映射的i/o空间读取32位数据
                      tmp &= ~(1 << (4 + arg));
                      tmp |= ( (!cmd) << (4 + arg) );
                      __raw_writel(tmp, XIE_GPKDAT); //向i/o地址写入32位数据
                     printk(KERN_INFO "turn off all light by xie\n");
                return 0;
               
        case MEMDEV_IOCON:
                        tmp = __raw_readl(XIE_GPKDAT);
                      tmp |= (0xF << 4);
                      __raw_writel(tmp, XIE_GPKDAT); //初始化数据寄存器
                     printk(KERN_INFO "turn on all light by xie\n");
                return 0;
        default:
                return -EINVAL;
        }
}
/*文件操作结构体*/
static struct file_operations dev_fops = {
        .owner        =        THIS_MODULE,
        .unlocked_ioctl        =        sbc6410_leds_ioctl,
};

static struct miscdevice misc = {
        .minor = MISC_DYNAMIC_MINOR,
        .name = DEVICE_NAME,
        .fops = &dev_fops,
};

static int __init dev_init(void)
{
        int ret;

        //unsigned tmp;
      GPKCON_SAVE = _raw_readl(XIE_GPKCON);
      GPKCON_SAVE = (GPKCON_SAVE & ~(0xffffU<<16))|(0x1111U<<16);
      _raw_writel (GPKCON_SAVE, XIE_GPKCON); //初始化控制寄存器
         
      GPKDAT_SAVE= readl(XIE_GPKDAT);
      GPKDAT_SAVE|= (0xF << 4);
      _raw_writel(GPKDAT_SAVE, XIE_GPKDAT); //初始化数据寄存器
       
        /*注_册混杂型字符设备驱动*/
        ret = misc_register(&misc);

        printk (DEVICE_NAME"\tinitialized\n");

        return ret;
}

static void __exit dev_exit(void)
{
        /*注销混杂型字符设备驱动*/
        misc_deregister(&misc);
       resave_led_reg(void);
        unmap_gpb(void);
}

module_init(dev_init);
module_exit(dev_exit);

MODULE_AUTHOR("David Xie");
MODULE_LICENSE("GPL");
***********************************************************************************
***********************************************************************************
下面是memdev.h文件


#ifndef _MEMDEV_H_
#define _MEMDEV_H_

#include <linux/ioctl.h>

/* 定义幻数 */
#define MEMDEV_IOC_MAGIC'k'

/* 定义命令 */
#define MEMDEV_IOCON   _IO(MEMDEV_IOC_MAGIC, 1)
#define MEMDEV_IOCOFF _IO(MEMDEV_IOC_MAGIC, 2)

#define MEMDEV_IOC_MAXNR 2

#endif /* _MEMDEV_H_ */


**********************************************************************************
***********************************************************************************

在linux上 编译之后出现的情况是:

# make
make -C /home/smb/linux-2.6.38 M=/home/smb/S3C6410led modules ARCH=arm CROSS_COMPILE=arm-linux-
make: Entering directory `/home/smb/linux-2.6.38'
CC /home/smb/S3C6410led/mini6410_leds_misc.o
/home/smb/S3C6410led/mini6410_leds_misc.c:99:2: warning: initialization from incompatible pointer type
Building modules, stage 2.
MODPOST 1 modules
CC      /home/smb/S3C6410led/mini6410_leds_misc.mod.o
LD /home/smb/S3C6410led/mini6410_leds_misc.ko
make: Leaving directory `/home/smb/linux-2.6.38'


说是源文件有指针出的不对~怎么会出现这样的警告呢!!这样当我下载到开发板上的时候,进行加载时就出现了如下的信息:
下面是超级终端出现的信息

# cd sdcard
# ls
FriendlyARM.ini                  images
app-led                            mini6410_leds_misc.ko
beifen                           mjpg-streamer-mini6410-bin.tar.gz
char_device                        www
high_char_device
# insmod mini6410_leds_misc.ko
les   initialized
#

请问一下论坛的大侠了~~~小弟感激不尽!

20114016039 发表于 2012-2-28 00:12:58

高手呀~小弟初学驱动,帮帮忙啦~~为啥这个驱动不行,用混杂驱动,ioctl方法,再将物理地址映射到虚拟地址里,这里有什么没有??
页: [1]
查看完整版本: 关于S3C6410LED驱动出现的问题~求助!