寄存器调试 (2):应用层通过C代码访问

除了前面所述通过shell命令访问寄存器外, 还支持通过C代码访问.

驱动层通过注册miscdevice设备, 实现了对应用层open/write/read等标准api的支持.

static DEVICE_ATTR(dump, 0644, misc_dump_show, misc_dump_store);
static DEVICE_ATTR(compare, 0644, misc_compare_show, misc_compare_store);
static DEVICE_ATTR(write, 0644, misc_write_show, misc_write_store);
static struct attribute *misc_attributes[] = {
    &dev_attr_dump.attr,
    &dev_attr_compare.attr,
    &dev_attr_write.attr,
    NULL
};
static struct attribute_group misc_attribute_group = {
    .name  = "rw",
    .attrs = misc_attributes
};
static struct miscdevice sunxi_reg_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name  = "sunxi-reg",
};

模块初始化时,通过sunxi_reg_init注册misc设备到内核, 并将属性组设为misc_attribute_group

static int __init sunxi_reg_init(void) {
    int     err;

    printk(KERN_INFO "sunxi_reg_init enter
");
    err = misc_register(&sunxi_reg_dev);
    if(err) {
        printk(KERN_ERR "%s register sunxi debug register driver as misc device error
", __func__);
        goto exit;
    }

    err = sysfs_create_group(&sunxi_reg_dev.this_device->kobj, &misc_attribute_group);
    if(err)
        printk("%s err: sysfs_create_group failed
", __func__);
exit:
    return err;
}

static void __exit sunxi_reg_exit(void) {
    printk("sunxi_reg_exit enter
");
    WARN_ON(0 != misc_deregister(&sunxi_reg_dev));
    sysfs_remove_group(&sunxi_reg_dev.this_device->kobj, &misc_attribute_group);
}

module_init(sunxi_reg_init);
module_exit(sunxi_reg_exit);

1. 获取单个寄存器的的值

按以下步骤:

(1) 打开sysfs设备节点.

fd = open("/sys/class/misc/sunxi-reg/rw/dump", O_RDWR);

(2) 传递寄存器地址给内核.

write(fd, "0xf1c20000 ", sizeof("0xf1c20000 "));

注意字符串请以换行符' '结尾.

(3) 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

(4) 读取寄存器值字符串. 保存到buff.

char buf[20];

read(fd, buf, sizeof(buf));

(5) 将字符串转化成整型值

value = strtoul(buf, NULL, 16);

示例代码:

#define DUMP_TEST_STRING    "0xf1c20000
"
int test_dump_reg(void)
{
    unsigned long value = 0;
    int     fd = 0, ret = -1;
    char     in_buf[250] = {0}, out_buf[250] = {0};

    fd = open("/sys/class/misc/sunxi-reg/rw/dump", O_RDWR);
    if(0 == fd) {
        printf("%s(%d): open "%s" failed, err!
", __func__, __LINE__);
        goto end;
    }
    /* store para */
    strcpy(in_buf, DUMP_TEST_STRING);
    ret = write(fd, in_buf, strlen(in_buf));
    if(ret < 0) {
        printf("%s(%d): write "%s" failed, err!
", __func__, __LINE__, in_buf);
        goto end;
    }
    printf("%s(%d): write %s success!
", __func__, __LINE__, in_buf);
    /* seek to begin */
    if(lseek(fd, 0, SEEK_SET) < 0) {
        printf("%s(%d): seek to begin failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): seek to begin success!
", __func__, __LINE__);
    /* show output value */
    ret = read(fd, out_buf, sizeof(out_buf));
    if(ret < 0) {
        printf("%s(%d): read failed, err!
", __func__, __LINE__);
        goto end;
    }
    value = strtoul(out_buf, NULL, 16);
    printf("%s(%d): read success! out string "%s", value 0x%08x
", __func__, __LINE__, out_buf, value);
    /* return success */
    ret = 0;
end:
    if(fd)
        close(fd);
    return ret;
}

运行结果打印:

 

 

2. 获取一组寄存器值

 

示例代码:

#define DUMP_TEST_STRING    "0xf1c20000,0xf1c20020
"
int test_dump_reg(void)
{
    unsigned long value = 0;
    int     fd = 0, ret = -1;
    char     in_buf[250] = {0}, out_buf[250] = {0};

    fd = open("/sys/class/misc/sunxi-reg/rw/dump", O_RDWR);
    if(0 == fd) {
        printf("%s(%d): open "%s" failed, err!
", __func__, __LINE__);
        goto end;
    }
    /* store para */
    strcpy(in_buf, DUMP_TEST_STRING);
    ret = write(fd, in_buf, strlen(in_buf));
    if(ret < 0) {
        printf("%s(%d): write "%s" failed, err!
", __func__, __LINE__, in_buf);
        goto end;
    }
    printf("%s(%d): write %s success!
", __func__, __LINE__, in_buf);
    /* seek to begin */
    if(lseek(fd, 0, SEEK_SET) < 0) {
        printf("%s(%d): seek to begin failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): seek to begin success!
", __func__, __LINE__);
    /* show output value */
    ret = read(fd, out_buf, sizeof(out_buf));
    if(ret < 0) {
        printf("%s(%d): read failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): read success! out string "%s"
", __func__, __LINE__, out_buf);
    /* 这里需自行从buf中解析出需要的寄存器值 */
    ...
    //value = strtoul(out_buf, NULL, 16);
    /* return success */
    ret = 0;
end:
    if(fd)
        close(fd);
    return ret;
}

 

3. 写单个寄存器值

示例代码:

#define WRITE_TEST_STRING    "0x01f01018 0x000000a0
"
int test_write_reg(void)
{
    int     fd = 0, ret = -1;
    char     in_buf[250] = {0}, out_buf[250] = {0};

    fd = open("/sys/class/misc/sunxi-reg/rw/write", O_RDWR);
    if(0 == fd) {
        printf("%s(%d): open "%s" failed, err!
", __func__, __LINE__);
        goto end;
    }
    /* store para */
    strcpy(in_buf, WRITE_TEST_STRING);
    ret = write(fd, in_buf, sizeof(in_buf));
    if(ret < 0) {
        printf("%s(%d): write "%s" failed, err!
", __func__, __LINE__, in_buf);
        goto end;
    }
    printf("%s(%d): write "%s" success!
", __func__, __LINE__, in_buf);
    /* seek to begin */
    if(lseek(fd, 0, SEEK_SET) < 0) {
        printf("%s(%d): seek to begin failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): seek to begin success!
", __func__, __LINE__);
    /* show output value */
    ret = read(fd, out_buf, sizeof(out_buf));
    if(ret < 0) {
        printf("%s(%d): read failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): read success! out string "%s"
", __func__, __LINE__, out_buf);
    /* return success */
    ret = 0;
end:
    if(fd)
        close(fd);
    return ret;
}

 

4. 写一组寄存器值

示例代码:

#define WRITE_TEST_STRING    "0xf1c20800 0x00000031,0xf1c20818 0x55555555
"
int test_write_reg(void)
{
    int     fd = 0, ret = -1;
    char     in_buf[250] = {0}, out_buf[250] = {0};

    fd = open("/sys/class/misc/sunxi-reg/rw/write", O_RDWR);
    if(0 == fd) {
        printf("%s(%d): open "%s" failed, err!
", __func__, __LINE__);
        goto end;
    }
    /* store para */
    strcpy(in_buf, WRITE_TEST_STRING);
    ret = write(fd, in_buf, sizeof(in_buf));
    if(ret < 0) {
        printf("%s(%d): write "%s" failed, err!
", __func__, __LINE__, in_buf);
        goto end;
    }
    printf("%s(%d): write "%s" success!
", __func__, __LINE__, in_buf);
    /* seek to begin */
    if(lseek(fd, 0, SEEK_SET) < 0) {
        printf("%s(%d): seek to begin failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): seek to begin success!
", __func__, __LINE__);
    /* show output value */
    ret = read(fd, out_buf, sizeof(out_buf));
    if(ret < 0) {
        printf("%s(%d): read failed, err!
", __func__, __LINE__);
        goto end;
    }
    printf("%s(%d): read success! out string "%s"
", __func__, __LINE__, out_buf);
    /* return success */
    ret = 0;
end:
    if(fd)
        close(fd);
    return ret;
}

 

原文地址:https://www.cnblogs.com/zhangyin-ethan/p/7487352.html