首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在内核驱动程序中没有行为

在内核驱动程序中没有行为
EN

Stack Overflow用户
提问于 2013-08-07 23:01:02
回答 1查看 1.6K关注 0票数 1

我一直在为lcd模块编写LCD内核驱动程序。一切都进行得很顺利,我可以写到显示器上,创建一个/dev/lcd节点,然后将结果显示在屏幕上。我认为使用rewind fops回调将光标定位在lcd上会很好,这样我就可以使用倒带搜索等等。然而,它并不像我预期的那样工作,下面是我所看到的一个总结:

驱动端的相关代码行如下:

代码语言:javascript
运行
复制
loff_t lcd_llseek(struct file *filp, loff_t off, int whence)
{
    switch (whence) {
        case 0: // SEEK_SET
            if (off > 4*LINE_LENGTH || off < 0) {
                printk(KERN_ERR "unsupported SEEK_SET offset %llx\n", off);
                return -EINVAL;
            }
            lcd_gotoxy(&lcd, off, 0, WHENCE_ABS);
            break;
        case 1: // SEEK_CUR 
            if (off > 4*LINE_LENGTH || off < -4*LINE_LENGTH) {
                printk(KERN_ERR "unsupported SEEK_CUR offset %llx\n", off);
                return -EINVAL;
            }
            lcd_gotoxy(&lcd, off, 0, WHENCE_REL);
            break;
        case 2: // SEEK_END (not supported, hence fall though)
        default:
            // how did we get here !
            printk(KERN_ERR "unsupported seek operation\n");
            return -EINVAL;
    }
    filp->f_pos = lcd.pos;
    printk(KERN_INFO "lcd_llseek complete\n");
    return lcd.pos;
}

int lcd_open(struct inode *inode, struct file *filp)
{
    if (!atomic_dec_and_test(&lcd_available)) {
        atomic_inc(&lcd_available);
        return -EBUSY; // already open
    }

    return 0;
}

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .write = lcd_write,
    .llseek = lcd_llseek,
    .open = lcd_open,
    .release = lcd_release,
};

int lcd_init(void)
{
    ...

    // allocate a new dev number (this can be dynamic or
    // static if passed in as a module param)
    if (major) {
        devno = MKDEV(major, 0);
        ret = register_chrdev_region(devno, 1, MODULE_NAME);
    } else {
        ret = alloc_chrdev_region(&devno, 0, 1, MODULE_NAME);
        major = MAJOR(devno);
    }
    if (ret < 0) {
        printk(KERN_ERR "alloc_chrdev_region failed\n");
        goto fail;
    }

    // create a dummy class for the lcd
    cl = class_create(THIS_MODULE, "lcd");
    if (IS_ERR(cl)) {
        printk(KERN_ERR "class_simple_create for class lcd failed\n");
        goto fail1;
    }

    // create cdev interface
    cdev_init(&cdev, &fops);
    cdev.owner = THIS_MODULE;
    ret = cdev_add(&cdev, devno, 1);
    if (ret) {
        printk(KERN_ERR "cdev_add failed\n");
        goto fail2;
    }

    // create /sys/lcd/fplcd/dev so udev will add our device to /dev/fplcd
    device = device_create(cl, NULL, devno, NULL, "lcd");
    if (IS_ERR(device)) {
        printk(KERN_ERR "device_create for fplcd failed\n");
        goto fail3;
    }
    ...
}

要测试lseek调用,我有以下单元测试:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define log(msg, ...) fprintf(stdout, __FILE__ ":%s():[%d]:" msg, __func__, __LINE__, __VA_ARGS__)

int lcd;

void test(void)
{
    int k;

    // a lot of hello's
    log("hello world test\n",1);
    if (lseek(lcd, 0, SEEK_CUR) == -1) {
        log("failed to seek\n", 1);
    }
}

int main(int argc, char **argv)
{
    lcd = open("/dev/lcd", O_WRONLY);
    if (lcd == -1) {
        perror("unable to open lcd");
        exit(EXIT_FAILURE);
    }

    test();

    close(lcd);
    return 0;
}

这些文件被交叉编译如下:

代码语言:javascript
运行
复制
~/Workspace/ts4x00/lcd-module$ cat Makefile 
obj-m += fls_lcd.o

all:
    make -C $(KPATH) M=$(PWD) modules
    $(CROSS_COMPILE)gcc -g -fPIC $(CFLAGS) lcd_unit_test.c -o lcd_unit_test

clean:
    make -C $(KPATH) M=$(PWD) clean
    rm -rf lcd_unit_test
~/Workspace/ts4x00/lcd-module$ make CFLAGS+="-march=armv4 -ffunction-sections -fdata-sections"
make -C ~/Workspace/ts4x00/linux-2.6.29 M=~/Workspace/ts4x00/lcd-module modules
make[1]: Entering directory `~/Workspace/ts4x00/linux-2.6.29'
  CC [M]  ~/Workspace/ts4x00/lcd-module/fls_lcd.o
~/Workspace/ts4x00/lcd-module/fls_lcd.c:443: warning: 'lcd_entry_mode' defined but not used
  Building modules, stage 2.
  MODPOST 1 modules
  CC      ~/Workspace/ts4x00/lcd-module/fls_lcd.mod.o
  LD [M]  ~/Workspace/ts4x00/lcd-module/fls_lcd.ko
make[1]: Leaving directory `~/Workspace/ts4x00/linux-2.6.29'
~/Workspace/ts4x00/arm-2008q3/bin/arm-none-linux-gnueabi-gcc -g -fPIC -march=armv4 -ffunction-sections -fdata-sections lcd_unit_test.c -o lcd_unit_test

这是使用单元测试运行驱动程序的输出:

代码语言:javascript
运行
复制
root@ts4700:~/devel# insmod ./fls_lcd.ko 
root@ts4700:~/devel# ./lcd_unit_test 
lcd_unit_test.c:test():[61]:hello world test
lcd_unit_test.c:test():[63]:failed to seek
root@ts4700:~/devel# dmesg
FLS LCD driver started
unsupported SEEK_SET offset bf0a573c

我不明白为什么内核端的参数如此糟糕,我尝试SEEK_CUR定位0,而在驱动程序中,我得到一个SEEK_SET (不管我在单元测试中放了什么)和一个疯狂的大数字关闭?

有人知道这是怎么回事吗?

顺便说一下,我正在为arm开发工具包上的内核2.6.29编译

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-09 13:10:19

好吧,抱歉,伙计们,昨晚试着调试了一下,结果是编译错了内核(我把KPATH留给了一个与sdcard不同的内核配置)。

很抱歉浪费了每个人的时间,但是如果有人在他们的内核驱动程序中看到一个看起来很疯狂的堆栈,这可能会让他们明白。

谢谢你的帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18115218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档