免费注册 查看新帖 |

Chinaunix

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

如何编写LINUX设备驱动程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-07 10:18 |只看该作者 |倒序浏览
5可用积分
http://www.it.com.cn/f/edu/0411/30/53811.htm
按照上面连接的范例想要编写设备驱动程序
得到如下错误,请教高手该如何修改
test.c:13: warning: `struct file' declared inside parameter list
test.c:13: warning: its scope is only this definition or declaration, which is probably not what you want
test.c:13: warning: `struct inode' declared inside parameter list
test.c: In function `read_test':
test.c:18: `VERIFY_WRITE' undeclared (first use in this function)
test.c:18: (Each undeclared identifier is reported only once
test.c:18: for each function it appears in.)
test.c:21: parse error before "for"
test.c: At top level:
test.c:30: warning: `struct file' declared inside parameter list
test.c:30: warning: `struct inode' declared inside parameter list
test.c:35: warning: `struct file' declared inside parameter list
test.c:35: warning: `struct inode' declared inside parameter list
test.c: In function `open_tibet':
test.c:37: `MOD_ING_USE_COUNT' undeclared (first use in this function)
test.c: At top level:
test.c:41: warning: `struct file' declared inside parameter list
test.c:41: warning: `struct inode' declared inside parameter list
test.c: In function `release_tibet':
test.c:43: union has no member named `usecount'
test.c: At top level:
test.c:46: variable `test_fops' has initializer but incomplete type
test.c:47: warning: excess elements in struct initializer
test.c:47: warning: (near initialization for `test_fops')
test.c:48: warning: excess elements in struct initializer
test.c:48: warning: (near initialization for `test_fops')
test.c:49: `write_test' undeclared here (not in a function)
test.c:49: warning: excess elements in struct initializer
test.c:49: warning: (near initialization for `test_fops')
test.c:50: warning: excess elements in struct initializer
test.c:50: warning: (near initialization for `test_fops')
test.c:51: warning: excess elements in struct initializer
test.c:51: warning: (near initialization for `test_fops')
test.c:52: warning: excess elements in struct initializer
test.c:52: warning: (near initialization for `test_fops')
test.c:53: warning: excess elements in struct initializer
test.c:53: warning: (near initialization for `test_fops')
test.c:54: `open_test' undeclared here (not in a function)
test.c:54: warning: excess elements in struct initializer
test.c:54: warning: (near initialization for `test_fops')
test.c:55: `release_test' undeclared here (not in a function)
test.c:55: warning: excess elements in struct initializer
test.c:55: warning: (near initialization for `test_fops')
test.c:56: warning: excess elements in struct initializer
test.c:56: warning: (near initialization for `test_fops')
test.c:57: warning: excess elements in struct initializer
test.c:57: warning: (near initialization for `test_fops')
test.c: In function `init_module':
test.c:64: parse error before '=' token
test.c:67: `KERN_INFO' undeclared (first use in this function)
test.c:67: parse error before string constant
/usr/include/linux/timer.h: At top level:
test.c:46: storage size of `test_fops' isn't known

<LINUX设备驱动>那本书的第三章看完了,但由于没有具体例子,很多地方都搞不懂,麻烦高手帮忙,谢谢!!!

最佳答案

查看完整内容

给lz提几点建议:1、内核源码版本最好和系统版本要一致;2、不要什么头文件都一骨碌弄进去,哪个函数需要哪个头文件,搞清楚了再说;3、调用的函数有什么作用,参数的意义,都搞明确;4、Makefile的写法,应该明确一些。

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2008-08-07 10:18 |只看该作者
原帖由 yyykkk1229 于 2008-8-7 16:37 发表
非常感谢楼上的回答,虽然说自己还是很模糊
慢慢琢磨吧,哎...现在思路有些乱


给lz提几点建议:
1、内核源码版本最好和系统版本要一致;
2、不要什么头文件都一骨碌弄进去,哪个函数需要哪个头文件,搞清楚了再说;
3、调用的函数有什么作用,参数的意义,都搞明确;
4、Makefile的写法,应该明确一些。

论坛徽章:
0
3 [报告]
发表于 2008-08-07 10:39 |只看该作者
顶一下........

论坛徽章:
0
4 [报告]
发表于 2008-08-07 11:09 |只看该作者
Linux设备驱动不是有一个最简单的例子吗?hello world的那个

论坛徽章:
0
5 [报告]
发表于 2008-08-07 11:17 |只看该作者
hello world 只是模块的加载啊
驱动设备的加载我没有找到想对应的例子,我用的是2.4.20-8版本,可能是编写版本的冲突啊
谁能给个2.4.20-8版本的范例,最简单的就可以了,只是为了了解这个过程,谢谢

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
6 [报告]
发表于 2008-08-07 11:32 |只看该作者
/*  hello-1.c - The simplest kernel module.
*/
#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>  /* Needed for KERN_ALERT */


int init_module(void)
{
   printk("<1>Hello world 1.\n");
       
   // A non 0 return means init_module failed; module can't be loaded.
   return 0;
}


void cleanup_module(void)
{
  printk(KERN_ALERT "Goodbye world 1.\n");
}  

把这个在2.4下面实现一下吧。

makefile:
TARGET  := hello-1
WARN    := -W -Wall -Wstrict-prototypes -Wmissing-prototypes
INCLUDE := -isystem /lib/modules/`uname -r`/build/include
CFLAGS  := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
CC      := gcc-3.0
       
${TARGET}.o: ${TARGET}.c

.PHONY: clean

clean:
    rm -rf {TARGET}.o

论坛徽章:
0
7 [报告]
发表于 2008-08-07 11:39 |只看该作者
楼上的,非常感谢你的程序,那你没有理解我的意思,模块的编译我已经会了,我需要一个驱动设备的程序,2者是不一样的,编译后的.o文件是能连接到/dev当中的,驱动设备比模块要复杂许多,不过还是非常感谢你的回答~

[ 本帖最后由 yyykkk1229 于 2008-8-7 11:40 编辑 ]

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
8 [报告]
发表于 2008-08-07 12:11 |只看该作者

回复 #6 yyykkk1229 的帖子

你试试这个,虚拟的一个设备,/dev/hello

  1. /*  chardev.c: Creates a read-only char device that says how many times
  2. *  you've read from the dev file
  3. */
  4.        
  5.         #if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
  6.            #include <linux/modversions.h>
  7.            #define MODVERSIONS
  8.         #endif
  9.         #include <linux/kernel.h>
  10.         #include <linux/module.h>
  11.         #include <linux/fs.h>
  12.         #include <asm/uaccess.h>  /* for put_user */
  13.        
  14.         /*  Prototypes - this would normally go in a .h file
  15.          */
  16.         int init_module(void);
  17.         void cleanup_module(void);
  18.         static int device_open(struct inode *, struct file *);
  19.         static int device_release(struct inode *, struct file *);
  20.         static ssize_t device_read(struct file *, char *, size_t, loff_t *);
  21.         static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
  22.        
  23.         #define SUCCESS 0
  24.         #define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices   */
  25.         #define BUF_LEN 80            /* Max length of the message from the device */
  26.        
  27.        
  28.         /* Global variables are declared as static, so are global within the file. */
  29.        
  30.         static int Major;            /* Major number assigned to our device driver */
  31.         static int Device_Open = 0;  /* Is device open?  Used to prevent multiple  */
  32.                                         access to the device                       */
  33.         static char msg[BUF_LEN];    /* The msg the device will give when asked    */
  34.         static char *msg_Ptr;
  35.        
  36.         static struct file_operations fops = {
  37.           .read = device_read,
  38.           .write = device_write,
  39.           .open = device_open,
  40.           .release = device_release
  41.         };
  42.        
  43.        
  44.         /*                   Functions
  45.          */
  46.        
  47.         int init_module(void)
  48.         {
  49.            Major = register_chrdev(0, DEVICE_NAME, &fops);
  50.        
  51.            if (Major < 0) {
  52.              printk ("Registering the character device failed with %d\n", Major);
  53.              return Major;
  54.            }
  55.        
  56.            printk("<1>I was assigned major number %d.  To talk to\n", Major);
  57.            printk("<1>the driver, create a dev file with\n");
  58.                  printk("'mknod /dev/hello c %d 0'.\n", Major);
  59.            printk("<1>Try various minor numbers.  Try to cat and echo to\n");
  60.                  printk("the device file.\n");
  61.            printk("<1>Remove the device file and module when done.\n");
  62.        
  63.            return 0;
  64.         }
  65.        
  66.        
  67.         void cleanup_module(void)
  68.         {
  69.            /* Unregister the device */
  70.            int ret = unregister_chrdev(Major, DEVICE_NAME);
  71.            if (ret < 0) printk("Error in unregister_chrdev: %d\n", ret);
  72.         }  
  73.        
  74.        
  75.         /*                   Methods
  76.          */
  77.        
  78.         /* Called when a process tries to open the device file, like
  79.          * "cat /dev/mycharfile"
  80.          */
  81.         static int device_open(struct inode *inode, struct file *file)
  82.         {
  83.            static int counter = 0;
  84.            if (Device_Open) return -EBUSY;
  85.            Device_Open++;
  86.            sprintf(msg,"I already told you %d times Hello world!\n", counter++");
  87.            msg_Ptr = msg;
  88.            MOD_INC_USE_COUNT;
  89.        
  90.           return SUCCESS;
  91.         }
  92.        
  93.        
  94.         /* Called when a process closes the device file.
  95.          */
  96.         static int device_release(struct inode *inode, struct file *file)
  97.         {
  98.            Device_Open --;     /* We're now ready for our next caller */
  99.        
  100.            /* Decrement the usage count, or else once you opened the file, you'll
  101.                     never get get rid of the module. */
  102.            MOD_DEC_USE_COUNT;
  103.        
  104.            return 0;
  105.         }
  106.        
  107.        
  108.         /* Called when a process, which already opened the dev file, attempts to
  109.            read from it.
  110.         */
  111.         static ssize_t device_read(struct file *filp,
  112.            char *buffer,    /* The buffer to fill with data */
  113.            size_t length,   /* The length of the buffer     */
  114.            loff_t *offset)  /* Our offset in the file       */
  115.         {
  116.            /* Number of bytes actually written to the buffer */
  117.            int bytes_read = 0;
  118.        
  119.            /* If we're at the end of the message, return 0 signifying end of file */
  120.            if (*msg_Ptr == 0) return 0;
  121.        
  122.            /* Actually put the data into the buffer */
  123.            while (length && *msg_Ptr)  {
  124.        
  125.                 /* The buffer is in the user data segment, not the kernel segment;
  126.                  * assignment won't work.  We have to use put_user which copies data from
  127.                  * the kernel data segment to the user data segment. */
  128.               put_user(*(msg_Ptr++), buffer++);
  129.        
  130.               length--;
  131.               bytes_read++;
  132.            }
  133.        
  134.            /* Most read functions return the number of bytes put into the buffer */
  135.            return bytes_read;
  136.         }
  137.        
  138.        
  139.         /*  Called when a process writes to dev file: echo "hi" > /dev/hello */
  140.         static ssize_t device_write(struct file *filp,
  141.            const char *buff,
  142.                  size_t len,
  143.                  loff_t *off)
  144.         {
  145.            printk ("<1>Sorry, this operation isn't supported.\n");
  146.            return -EINVAL;
  147.         }
复制代码

makefile 我就不说了,自己编译,试一下。

论坛徽章:
0
9 [报告]
发表于 2008-08-07 13:50 |只看该作者
感谢,可是还是同样的错误,说出现fops时出错,跟我刚才的问题一样,我刚才设置那个文件是用的是test_fops
Major = register_chrdev(0, DEVICE_NAME, &fops);
这句话的DEVICE_NAME应该如何设置呀

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
10 [报告]
发表于 2008-08-07 14:13 |只看该作者
原帖由 yyykkk1229 于 2008-8-7 13:50 发表
感谢,可是还是同样的错误,说出现fops时出错,跟我刚才的问题一样,我刚才设置那个文件是用的是test_fops
Major = register_chrdev(0, DEVICE_NAME, &fops);
这句话的DEVICE_NAME应该如何设置呀


DEVICE_NAME前面不是有宏定义吗?你可不可以把你的makefile贴出来看看?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP