免费注册 查看新帖 |

Chinaunix

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

内核编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-03 10:05 |只看该作者 |倒序浏览
内核编程的时候如何使用 本地自己定义的头文件?有人知道马?

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2009-04-03 10:16 |只看该作者
自定义的头文件,直接#include "your.h"就可以了吧

论坛徽章:
0
3 [报告]
发表于 2009-04-03 10:27 |只看该作者
我也是这样想的,可是,我在头文件里用#define定义的函数 在主文件里识别不了

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
4 [报告]
发表于 2009-04-03 10:29 |只看该作者
原帖由 jazeltq 于 2009-4-3 10:27 发表
我也是这样想的,可是,我在头文件里用#define定义的函数 在主文件里识别不了


光说不行。可以的话贴出点代码看看。:wink:

论坛徽章:
0
5 [报告]
发表于 2009-04-03 10:45 |只看该作者
哦,
这是头文件 chardev.h
/*
* chardev.h - the header file with the ioctl definitions
*
* The declarations here have to be in a header file, because
* they need to be known both to the kernel module
* (in chardev.c ) and the proces calling ioctl (ioctl.c)
*/
#ifdef CHARDEV_H
#define CHARDEV_H

#include <linux/ioctl.h>

/*
* The major device number. We can't rely on dynamic
* registration any more, because ioctls need to know
* it
*/
#define MAJOR_NUM 100
/*
* Set the message of the device driver
*/
#define IOCTL_SET_MEG _IOR(MAJOR_NUM, 0, char *)
/*
* _IOR means that we're creating an ioctl command
* number for passing information from a user process
* to the kernel module.
*
* The first arguments, MAJOR_NUM, is the major device
* number we're using .
*
* The second argument is the number of the command
* (there could be several with different meanings)
*
* The third argument is the type we want to get from
* the process to the kernel.
*
*/

/*
* Get the message of the device driver
*/
#define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, char *)

/* This IOCTL is used for output, to get the message
* of the device driver, However, we still need the
* buffer to place the message in to be input,
* as it is allocated by the process.
*/
/*
* Get the n'th byte of the message
*/
#define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int)

/*
* The IOCTL is used for both input and output. It receives from the user a
* number, n, and returns Message[n].
*/
/*
* The name of the device file
*/
#define DEVICE_FILE_NAME "char_dev"
#endif



这是主文件 chardev.c
/*
* chardev.c-- Create an input/output character device
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

#include "chardev.h"
#define SUCCESS 0
#define DEVICE_ANME "char_dev"
#define BUF_LEN 80

/*
* Is the device open right now ?
* Used to prevent concurrent access into the same device
*/

static int Device_Open = 0;

/*
* The message the device will given when asked
*/
static char Message[BUF_LEN];

/*
* How far did the process reading the message get?
* Useful if the message is larger than the size of the
* buffer we get to fill in device_read
*/
static char * Message_Ptr;

/*
* 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 "devcie_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 */
                                                ioff_t * offset)
{
        /*
         * Number of bytes actually written to the buffer
         */
        int bytes_read = 0;
#ifdef DEBUG
        printk(KERN_INFO "device_read(%p,%p,%d)\n", file, buffer, length);
#endif
        /*
         * If we're at the end of the message, return 0
         * (whichd signifies end of the file)
         */
        if (*Message_Ptr == 0)
                return 0;
        /*
         * Actually put the data into the buffer
         */
        while (length && * Message_Ptr) {
                /*
                 * Because the buffer is in the user data segment,
                 * not the kernel data segment, assignment would't
                 * work. Instead, we have to use put_user which
                 * copies data from the kernel data segment to the
                 * user data segment
                 */
                put_user(*(Message_Ptr++), buffer++);
                length--;
                bytes_read++;
        }
#ifdef DEBUG
        printk(KERN_INFO "Read %d bytes, %d left\n",bytes_read, length);
#endif
        /*
         * Read functions are supposed to return the number
         * of bytes actually inserted into the buffer
         */
        return bytes_read;
}
/*
* This function is called when somebody tries to write into our devcie
* file
*/
static ssize_t
device_write(struct file *file,
                const char __user * buffer, size_t length, loff_t * offset)
{
        int i;
#ifdef DEBUG
        printk(KERN_INFO "device_write(%p,%s,%d)", file, buffer, length)
#endif
        for (i=0; i < length && i< BUF_LEN; i++)
                get_user(Message, buffer + i);
        Message_Ptr = Message;
        /*
         * Again, return the number of input charactres used
         */
        return i;
}
/*
* 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
* structure, which all device function get): the number of the ioctl called
* and the parameter given to the ioctl funciton.
*
* 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 inode * inode ,        /* see include/linux/fs.h*/
                                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_SET_MSG:
                                /*
                                 * Receive a pointer to a message (in user space) and set that
                                 * to be the device 's message. Get the parameter given to
                                 * ioctl by the process.
                                 */
                                temp = (char *)ioctl_param;
                                /*
                                 * Find the length of the message
                                 */
                                get_user(ch, temp);
                                for (i=0; ch && i< BUF_LEN; i++, temp++)
                                        get_user(ch, temp);
                                device_write(file, (char *)ioctl_param, i, 0);
                                break;
                        case IOCTL_GET_MSG:
                                /*
                                 * Give the current message to the calling process-
                                 * the parameter we got is pointer, fill it.
                                 */
                                i = device_read(file, (char *)ioctl_param, 99, 0);

                                /*
                                 * Put a zero at the end of the buffer, so it will be
                                 * properly terminated
                                 */
                                put_user('\0', (char *)ioctl_param + i);
                                break;
                        case IOCTL_GET_NTH_BYTE:
                                /*
                                 * This ioctl is both input (ioctl_param) and
                                 * output (the return value of this function)
                                 */
                                return Message[ioctl_param];
                                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
* device table, it can't be ioctl to
* init_module. NULL is for unimplemented functions.
*/
struct file_operations Fops = {
        .read = device_read,
        .write = device_write,
        .ioctl = device_ioctl,
        .open = device_open,
        .release = device_release,   /* a.k.a close*/
};
/*
* Initialize the moduel - Register the character device
*/
int init_module()
{
        int ret_val;
        /*
         * Register the character device (at least try )
         */
        ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, & Fops);

        /*
         * Negative values signify an error
         */
        if (ret_val < 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 "you'll have to create a device file.\n");
        printk(KERN_INFO "we suggest you use:\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 "file you'll use.\n");
        return 0;
}
/*
* Clean up -unregister the appropriater file from /proc
*/
void cleanup_module()
{
        int ret;
        /*
         * Unregister the device
         */
        ret = unregister_chrdev(MAJOR_NUM, DEVICE_NAME);

        /*
         * If there's an error, report it
         */
        if (ret < 0)
                printk(KERN_INFO "Error: unregister_chrdev: %d\n", ret);
}
这是Makefile
obj-m                        :=chardev.o
default:
        $(MAKE) -C /lib/modules/$(shell uname -r)/build  M=$(PWD)  modules
clean:
        $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

论坛徽章:
0
6 [报告]
发表于 2009-04-04 01:49 |只看该作者

回复 #5 jazeltq 的帖子

#ifdef CHARDEV_H
改成#ifndef CHARDEV_H
...

论坛徽章:
0
7 [报告]
发表于 2009-04-04 08:45 |只看该作者
谢谢了,我把问题想复杂了,没想到是这里出来问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP