A40i/T3的sunxi_dump_reg使用说明(二)

  • 应用层通过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\n");

   err = misc_register(&sunxi_reg_dev);

   if(err) {

      printk(KERN_ERR "%s register sunxi debug register driver as misc device error\n", __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\n", __func__);

exit:

   return err;

}

static void __exit sunxi_reg_exit(void) {

   printk("sunxi_reg_exit enter\n");

   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. 打开sysfs设备节点.

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

  1. 传递寄存器地址给内核.

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

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

  1. 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

  1. 读取寄存器值字符串. 保存到buff.

char buf[20];

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

  1. 将字符串转化成整型值

value = strtoul(buf, NULL, 16);

示例代码:

#define DUMP_TEST_STRING "0xf1c20000\n"

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!\n", __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!\n", __func__, __LINE__, in_buf);

      goto end;

   }

   printf("%s(%d): write %s success!\n", __func__, __LINE__, in_buf);

   /* seek to begin */

   if(lseek(fd, 0, SEEK_SET) < 0) {

      printf("%s(%d): seek to begin failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): seek to begin success!\n", __func__, __LINE__);

   /* show output value */

   ret = read(fd, out_buf, sizeof(out_buf));

   if(ret < 0) {

      printf("%s(%d): read failed, err!\n", __func__, __LINE__);

      goto end;

   }

   value = strtoul(out_buf, NULL, 16);

   printf("%s(%d): read success! out string \"%s\", value 0x%08x\n", __func__, __LINE__, out_buf, value);

   /* return success */

   ret = 0;

end:

   if(fd)

      close(fd);

   return ret;

}

运行时打印:

test_dump_reg(56): write 0xf1c20000

success!

test_dump_reg(62): seek to begin success!

test_dump_reg(70): read success! out string "0x90001410

", value 0x90001410

      1.  获取一组寄存器值
  1. 打开sysfs设备节点.

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

  1. 传递寄存器地址给内核.

write(fd, "0xf1c20000,0xf1c20020\n", sizeof("0xf1c20000,0xf1c20020\n"));

0xf1c20000为起始寄存器, 0xf1c20020为末尾寄存器.

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

  1. 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

  1. 读取寄存器值字符串. 保存到buf.

char buf[20];

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

  1. 从buf中解析出需要的寄存器值

此步和"获取单个寄存器值"不同, 需要自行解析buf内容, 提取出寄存器值. buf内容格式如下:

0xf1c20000: 0x90001410 0x00000000 0x90035514 0x00000000

0xf1c20010: 0x93001300 0x00000000 0x93001801 0x00000000

0xf1c20020: 0x90000911                                 

注意: 上述最后一行(0xf1c20020所在行)末尾为若干个补齐的空格.

示例代码:

#define DUMP_TEST_STRING "0xf1c20000,0xf1c20020\n"

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!\n", __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!\n", __func__, __LINE__, in_buf);

      goto end;

   }

   printf("%s(%d): write %s success!\n", __func__, __LINE__, in_buf);

   /* seek to begin */

   if(lseek(fd, 0, SEEK_SET) < 0) {

      printf("%s(%d): seek to begin failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): seek to begin success!\n", __func__, __LINE__);

   /* show output value */

   ret = read(fd, out_buf, sizeof(out_buf));

   if(ret < 0) {

      printf("%s(%d): read failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): read success! out string \"%s\"\n", __func__, __LINE__, out_buf);

   /* 这里需自行从buf中解析出需要的寄存器值 */

   ...

   //value = strtoul(out_buf, NULL, 16);

   /* return success */

   ret = 0;

end:

   if(fd)

      close(fd);

   return ret;

}

      1.  写单个寄存器值
  1. 打开sysfs设备节点.

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

  1. 传递寄存器地址给内核.

write(fd, "0x01f01018 0x000000a0\n", sizeof("0x01f01018 0x000000a0\n"));

0x01f01018为寄存器地址, 0x000000a0为待写入的值, 之间有且仅有一个空格.

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

  1. 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

  1. 通过read发起sysfs的xxx_show调用, 执行写操作. 返回信息保存到buf.

char buf[20];

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

  1. 由于写操作已完成, buf内容可以不处理:

reg         to_write    after_write

0x01f01018  0x000000a1  0x000000a1

示例代码:

#define WRITE_TEST_STRING "0x01f01018 0x000000a0\n"

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!\n", __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!\n", __func__, __LINE__, in_buf);

      goto end;

   }

   printf("%s(%d): write \"%s\" success!\n", __func__, __LINE__, in_buf);

   /* seek to begin */

   if(lseek(fd, 0, SEEK_SET) < 0) {

      printf("%s(%d): seek to begin failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): seek to begin success!\n", __func__, __LINE__);

   /* show output value */

   ret = read(fd, out_buf, sizeof(out_buf));

   if(ret < 0) {

      printf("%s(%d): read failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): read success! out string \"%s\"\n", __func__, __LINE__, out_buf);

   /* return success */

   ret = 0;

end:

   if(fd)

      close(fd);

   return ret;

}

      1.  写一组寄存器值
  1. 打开sysfs设备节点.

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

  1. 传递寄存器地址给内核.

write(fd, "0xf1c20800 0x00000031,0xf1c20818 0x55555555\n", sizeof("0xf1c20800 0x00000031,0xf1c20818 0x55555555\n"));

格式请参考3.1.6"写一组寄存器值"章节, 注意字符串以'\n'结尾.

  1. 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

  1. 通过read发起sysfs的xxx_show调用, 执行写操作. 返回信息保存到buf.

char buf[20];

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

  1. 由于写操作已完成, buf内容可以不处理. Buf内容如下:

reg         to_write    after_write

0xf1c20800  0x00000031  0x00000031

0xf1c20818  0x55555555  0x00555555

示例代码:

#define WRITE_TEST_STRING "0xf1c20800 0x00000031,0xf1c20818 0x55555555\n"

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!\n", __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!\n", __func__, __LINE__, in_buf);

      goto end;

   }

   printf("%s(%d): write \"%s\" success!\n", __func__, __LINE__, in_buf);

   /* seek to begin */

   if(lseek(fd, 0, SEEK_SET) < 0) {

      printf("%s(%d): seek to begin failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): seek to begin success!\n", __func__, __LINE__);

   /* show output value */

   ret = read(fd, out_buf, sizeof(out_buf));

   if(ret < 0) {

      printf("%s(%d): read failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): read success! out string \"%s\"\n", __func__, __LINE__, out_buf);

   /* return success */

   ret = 0;

end:

   if(fd)

      close(fd);

   return ret;

}

      1.  比较单个寄存器值
  1. 打开sysfs设备节点.

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

  1. 传递寄存器地址给内核.

write(fd, "0x01f01018 0x000000a0 0x000000a0\n", sizeof("0x01f01018 0x000000a0 0x000000a0\n"));

格式请参考3.1.3"比较单个寄存器值"章节, 注意字符串以'\n'结尾.

  1. 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

  1. 通过read发起sysfs的xxx_show调用, 执行比较操作. 返回信息保存到buf.

char buf[20];

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

  1. buf内容为比较结果:

reg         expect      actual      mask        result

0x01f01018  0x000000a0  0x000000a0  0x000000a0  OK

结果分析请参考3.1.3章节.

示例代码:

#define COMPARE_TEST_STRING  "0x01f01018 0x000000a0 0x000000a0\n"

int test_compare_reg(void)

{

   int    fd = 0, ret = -1;

   char   in_buf[250] = {0}, out_buf[250] = {0};

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

   if(0 == fd) {

      printf("%s(%d): open \"%s\" failed, err!\n", __func__, __LINE__);

      goto end;

   }

   /* store para */

   strcpy(in_buf, COMPARE_TEST_STRING);

   ret = write(fd, in_buf, strlen(in_buf));

   if(ret < 0) {

      printf("%s(%d): write \"%s\" failed, err!\n", __func__, __LINE__, in_buf);

      goto end;

   }

   printf("%s(%d): write \"%s\" success!\n", __func__, __LINE__, in_buf);

   /* seek to begin */

   if(lseek(fd, 0, SEEK_SET) < 0) {

      printf("%s(%d): seek to begin failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): seek to begin success!\n", __func__, __LINE__);

   /* show output value */

   ret = read(fd, out_buf, sizeof(out_buf));

   if(ret < 0) {

      printf("%s(%d): read failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): read success! out string \"%s\"\n", __func__, __LINE__, out_buf);

   /* return success */

   ret = 0;

end:

   if(fd)

      close(fd);

   return ret;

}

      1.  比较一组寄存器值
  1. 打开sysfs设备节点.

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

  1. 传递寄存器地址给内核.

write(fd, "0xf1c20010 0x03006207 0x03006207,0xf1c20020 0x00001000 0x00001000,0xf1c20028 0x80000000 0x80000000\n", sizeof("0xf1c20010 0x03006207 0x03006207,0xf1c20020 0x00001000 0x00001000,0xf1c20028 0x80000000 0x80000000\n"));

格式请参考3.1.4"比较一组寄存器值"章节, 注意字符串以'\n'结尾.

  1. 将读写指针移植文件首.

lseek(fd, 0, SEEK_SET);

  1. 通过read发起sysfs的xxx_show调用, 执行比较操作. 返回信息保存到buf.

char buf[20];

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

  1. buf内容为比较结果:

reg         expect      actual      mask        result

0xf1c20010  0x03006207  0x93001300  0x03006207  ERR

0xf1c20020  0x00001000  0x90000911  0x00001000  ERR

0xf1c20028  0x80000000  0x90041811  0x80000000  OK

结果分析请参考3.1.4章节.

示例代码:

#define COMPARE_TEST_STRING  "0xf1c20010 0x03006207 0x03006207,0xf1c20020 0x00001000 0x00001000,0xf1c20028 0x80000000 0x80000000\n"

int test_compare_reg(void)

{

   int    fd = 0, ret = -1;

   char   in_buf[250] = {0}, out_buf[250] = {0};

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

   if(0 == fd) {

      printf("%s(%d): open \"%s\" failed, err!\n", __func__, __LINE__);

      goto end;

   }

   /* store para */

   strcpy(in_buf, COMPARE_TEST_STRING);

   ret = write(fd, in_buf, strlen(in_buf));

   if(ret < 0) {

      printf("%s(%d): write \"%s\" failed, err!\n", __func__, __LINE__, in_buf);

      goto end;

   }

   printf("%s(%d): write \"%s\" success!\n", __func__, __LINE__, in_buf);

   /* seek to begin */

   if(lseek(fd, 0, SEEK_SET) < 0) {

      printf("%s(%d): seek to begin failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): seek to begin success!\n", __func__, __LINE__);

   /* show output value */

   ret = read(fd, out_buf, sizeof(out_buf));

   if(ret < 0) {

      printf("%s(%d): read failed, err!\n", __func__, __LINE__);

      goto end;

   }

   printf("%s(%d): read success! out string \"%s\"\n", __func__, __LINE__, out_buf);

   /* return success */

   ret = 0;

end:

   if(fd)

      close(fd);

   return ret;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值