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;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: a40i-linuxsdk是一个用于开发人脸识别系统的软件开发工具包。以下是对a40i-linuxsdk使用手册的回答: a40i-linuxsdk使用手册提供了关于如何使用a40i-linuxsdk的详细指导。手册中包含了安装、配置、编译和运行a40i-linuxsdk所需的步骤和说明。 首先,手册介绍了如何下载和安装a40i-linuxsdk。它提供了下载链接和安装指南,让用户能够迅速将a40i-linuxsdk部署到自己的开发环境中。 接下来,手册详细解释了如何配置a40i-linuxsdk。配置过程包括设置开发环境变量、添加所需的依赖项和库文件等。手册提供了清晰的步骤和示例,让用户能够轻松完成配置工作。 然后,手册介绍了如何编译和构建使用a40i-linuxsdk的应用程序。它提供了编译的指令和示例代码,帮助用户理解如何将a40i-linuxsdk集成到自己的项目中。 最后,手册讲解了如何运行a40i-linuxsdk开发的应用程序。它提供了启动应用程序的命令和参数的解释,帮助用户正确地运行和调试他们的应用程序。 总之,a40i-linuxsdk使用手册是一个详细的指南,提供了使用a40i-linuxsdk进行开发的全面支持。无论是初学者还是有经验的开发人员,都能从手册中获得所需的信息和指导,快速上手a40i-linuxsdk开发。 ### 回答2: a40i-linuxsdk是一种提供给开发者使用的软件开发工具包,用于开发基于Linux操作系统的应用程序。下面是关于如何使用a40i-linuxsdk的简要说明: 1. 下载和安装:首先,您需要从官方网站或其他可靠渠道下载a40i-linuxsdk软件包。然后,按照提供的安装指南进行安装。确保您的计算机符合所需的操作系统和硬件要求。 2. 环境设置:安装完成后,您需要设置适当的开发环境。这可能涉及设置路径变量、配置编译器和构建工具,以及安装其他必要的依赖项。阅读提供的环境设置指南以获得详细说明。 3. API文档和示例:查阅提供的API文档,了解可用的函数、类和方法,以及如何使用它们。如果有提供示例代码,建议您将其下载并尝试运行,以便更好地理解SDK的功能和用法。 4. 开发应用程序:现在,您可以开始编写自己的应用程序了。使用SDK提供的功能和工具,根据自己的需求来开发您的应用。您可以调用相应的API函数、处理事件、进行数据交互等等。 5. 调试和测试:在编写和构建应用程序的过程中,可能会出现一些错误或问题。通过使用SDK提供的调试工具和日志功能,可以帮助您找出并解决这些问题。测试您的应用程序以确保其在不同的情况下正常运行。 6. 发布应用程序:当您完成应用程序的开发、调试和测试后,您可以将其部署到目标设备上。按照提供的部署指南进行操作,将应用程序转移到目标设备上,并确保其能够正确运行。 总之,a40i-linuxsdk是一个提供开发工具和资源的软件开发工具包,可以帮助开发者在Linux操作系统上构建应用程序。通过阅读手册、查阅API文档和示例,开发者可以快速上手并使用该SDK进行应用程序开发。 ### 回答3: a40i-linuxsdk使用手册是一本详细介绍a40i-linuxsdk使用方法和指导的手册。它包含了以下几个方面的内容: 1. 安装指南:手册中会详细介绍如何在不同的操作系统上安装a40i-linuxsdk,并提供相应的安装包和命令。 2. 系统配置:手册会指导用户如何配置a40i-linuxsdk的系统环境,包括操作系统版本、依赖库、驱动程序等。 3. SDK基础:手册会介绍a40i-linuxsdk的基本概念、目录结构和核心组件,帮助用户快速了解整个开发框架。 4. API文档:手册会提供完整的API文档,详细说明每个API的功能、参数和调用方法,并提供示例代码供参考。 5. 开发示例:手册中会提供一些常见的开发示例,涵盖图像处理、声音处理、人脸识别等领域,帮助用户快速上手并实现自己的应用。 6. 故障排除:手册中会列举一些常见的问题和解决方法,帮助用户在开发过程中遇到问题时进行自助排查。 总之,a40i-linuxsdk使用手册是一本非常实用的参考资料,对于初学者帮助其快速上手并进行应用开发,对于有经验的开发者则提供了全面的文档和示例,为他们的开发工作提供支持和便利。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值