免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2171 | 回复: 6
打印 上一主题 下一主题

[驱动] arm linux下驱动开发 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-24 11:16 |只看该作者 |倒序浏览
请教大家个问题:

      我有个给arm linux 下一个字符设备写好的驱动程序,这个驱动程序编译成模块形式之后,用insmod手动加载,并且手动建立/dev下的设备节点后,工作正常。
      但是我希望使用静态加载的方式,我将它编译进内核(修改Kconfig,Makefile),引导系统后,始终找不相应的设备或驱动信息。
      /proc/devices 里没有相关项, /dev下也没有设备节点。


      我想知道如何来确定我的驱动已成功编译进内核了?  要使用静态加载方式,在写驱动的时候有没有要注意的地方?  什么导致了我的静态加载失败?

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
2 [报告]
发表于 2014-05-24 13:16 |只看该作者
要自动创建结点,需要使用device_create
把代码贴出来

论坛徽章:
0
3 [报告]
发表于 2014-05-24 16:41 |只看该作者
看下模块编译产生的临时文件。回复 1# hoursjl


   

论坛徽章:
0
4 [报告]
发表于 2014-05-26 14:52 |只看该作者
本帖最后由 hoursjl 于 2014-05-26 14:58 编辑

回复 2# arm-linux-gcc

确实没用你说的函数。   我刚接触嵌入式linux驱动,有没有什么资料推荐我看一下啊? 谢谢!



/*
* blink.c - Create an input/output character device
*/
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module */
#include <linux/fs.h>
#include <asm/uaccess.h> /* for get_user and put_user */
#include <asm/io.h>
#include "blink.h"
#define SUCCESS 0
#define DEVICE_NAME "/dev/blink_Dev"


#define BLINK_CTRL_REG         0x7C600000
static void *mmio;
static int major_num;

/*
* Is the device open right now? Used to prevent
* concurent access into the same device
*/
static int Device_Open = 0;


static void set_blink_ctrl(void)
{
        printk("KERNEL PRINT : set_blink_ctrl \n\r");
        *(unsigned int *)mmio = 0x1;
}



static void reset_blink_ctrl(void)
{

        printk("KERNEL PRINT : reset_blink_ctrl \n\r");
        *(unsigned int *)mmio = 0x0;
}
/*
* This is called whenever a process attempts to open the device file
*/
static int device_open(struct inode *inode, struct file *file)
{
        #ifdef DEBUG
                printk(KERN_INFO "device_open(%p)\n", file);
        #endif
        /*
        * We don't want to talk to two processes at the same time
        */
        if (Device_Open)
                return -EBUSY;
        Device_Open++;
        /*
        * Initialize the message
        */
//        Message_Ptr = Message;
        try_module_get(THIS_MODULE);
        return SUCCESS;
}
static int device_release(struct inode *inode, struct file *file)
{
        #ifdef DEBUG
                printk(KERN_INFO "device_release(%p,%p)\n", inode, file);
        #endif
        /*
        * We're now ready for our next caller
        */
        Device_Open--;
        module_put(THIS_MODULE);
        return SUCCESS;
}
/*
* This function is called whenever a process which has already opened the
* device file attempts to read from it.
*/
static ssize_t device_read(        struct file *file, /* see include/linux/fs.h */
                                                        char __user * buffer, /* buffer to be filled with data */
                                                        size_t length, /* length of the buffer */
                                                        loff_t * offset)
{
        return SUCCESS;
}
/*
* This function is called when somebody tries to
* write into our device file.
*/
static ssize_t device_write(struct file *file,
                                                        const char __user * buffer,
                                                        size_t length,
                                                        loff_t * offset)
{
        return SUCCESS;
}
/*
* This function is called whenever a process tries to do an ioctl on our
* device file. We get two extra parameters (additional to the inode and file
* structures, which all device functions get): the number of the ioctl called
* and the parameter given to the ioctl function.
*
* If the ioctl is write or read/write (meaning output is returned to the
* calling process), the ioctl call returns the output of this function.
*
*/
int device_ioctl(                        struct file *file, /* ditto */
                                        unsigned int ioctl_num, /* number and param for ioctl */
                                        unsigned long ioctl_param)
{
//        int i;
        char *temp;
//        char ch;
        /*
        * Switch according to the ioctl called
        */
        switch (ioctl_num)
        {
        case IOCTL_ON_LED:
               
                temp = (char *)ioctl_param;
                set_blink_ctrl();
        break;
        case IOCTL_STOP_LED:
                temp = (char *)ioctl_param;
                reset_blink_ctrl();
        break;
       
        }
        return SUCCESS;
}
/* Module Declarations */
/*
* This structure will hold the functions to be called
* when a process does something to the device we
* created. Since a pointer to this structure is kept in
* the devices table, it can't be local to
* init_module. NULL is for unimplemented functions.
*/
struct file_operations Fops = {
                                                                .read = device_read,
                                                                .write = device_write,
                                                                .unlocked_ioctl = device_ioctl,
                                                                .open = device_open,
                                                                .release = device_release, /*close */                                                                };
/*
* Initialize the module - Register the character device
*/
int init_module()
{
        int ret_val;
       
        /*
        * Register the character device (atleast try)
        */
        major_num = register_chrdev(0,DEVICE_NAME, &Fops);
        /*
        * Negative values signify an error
        */
        if (major_num < 0)
        {
                printk(KERN_ALERT "%s failed with %d\n","Sorry, registering the character device ", ret_val);
                return ret_val;
        }
        printk(KERN_INFO "%s The major device number is %d.\n",
        "Registeration is a success", major_num);
        printk(KERN_INFO "If you want to talk to the device driver,\n");
        printk(KERN_INFO "Than create a device file by following command. \n");
        printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, major_num);
        printk(KERN_INFO "The device file name is important, because\n");
        printk(KERN_INFO "the ioctl program assumes that's the\n");
        printk(KERN_INFO "file you'll use.\n");

        mmio = ioremap(BLINK_CTRL_REG,0x100);

        return 0;
}
/*
* Cleanup - unregister the appropriate file from /proc
*/
void cleanup_module()
{
        /*
        * Unregister the device
        */
        iounmap(mmio);
        unregister_chrdev(major_num,DEVICE_NAME);
}

论坛徽章:
0
5 [报告]
发表于 2014-05-26 14:55 |只看该作者
中间结果都是有的



回复 3# fairy795


   

无标题.png (1.65 KB, 下载次数: 28)

无标题.png

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
6 [报告]
发表于 2014-05-26 20:10 |只看该作者
本帖最后由 arm-linux-gcc 于 2014-05-26 20:28 编辑

你的写法还是很古老的写法,没有使用设备模型这一套东西,没把设备、驱动、总线分开

建议参考platform_device_register和platform_driver_register的用法

论坛徽章:
0
7 [报告]
发表于 2014-05-26 20:36 |只看该作者
回复 6# arm-linux-gcc


用了device_create()现在可以了。 马上去学习platform_device_register和platform_driver_register,多谢你的指点啊!   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP