rkipc控制ircut的分析

rk_isp_set_night_to_day函数

rkipc控制ircut主要通过rk_isp_set_night_to_day函数,例如在ser_rk_isp_set_night_to_day函数中

int ser_rk_isp_set_night_to_day(int fd) {int ret = 0;int id, len;char *value = NULL;if (sock_read(fd, &id, sizeof(id)) == SOCKERR_CLOSED)return -1;if (sock_read(fd, &len, sizeof(len)) == SOCKERR_CLOSED)return -1;if (len) {value = (char *)malloc(len);//读取前段发过来的值if (sock_read(fd, value, len) == SOCKERR_CLOSED) {free(value);return -1;}LOG_DEBUG("id is %d, value is %s\n", id, value);//设置日夜模式,会对ircut进行操作ret = rk_isp_set_night_to_day(id, value);free(value);if (sock_write(fd, &ret, sizeof(int)) == SOCKERR_CLOSED)return -1;}

rv1106的rk_isp_set_night_to_day函数在/luckfox-pico/project/app/rkipc/rkipc/common/isp/rv1106/isp.c中

int rk_isp_set_night_to_day(int cam_id, const char *value) {int ret;//检查传过来的cam_idRK_ISP_CHECK_CAMERA_ID(cam_id);aie_attrib_t attr;//获取isp的属性rk_aiq_user_api2_aie_GetAttrib(rkipc_aiq_get_ctx(cam_id), &attr);if (!strcmp(value, "night")) {//夜晚模式设置attr.mode 为 RK_AIQ_IE_EFFECT_BW;attr.mode = RK_AIQ_IE_EFFECT_BW;rk_aiq_user_api2_aie_SetAttrib(rkipc_aiq_get_ctx(cam_id), &attr);//ircut设置为假rk_isp_enable_ircut(false);} else {//白天模式ircut设置为真rk_isp_enable_ircut(true);//关灯if (light_state == 1)rk_isp_close_light(3);//夜晚模式设置attr.mode 为 RK_AIQ_IE_EFFECT_NONE;attr.mode = RK_AIQ_IE_EFFECT_NONE;rk_aiq_user_api2_aie_SetAttrib(rkipc_aiq_get_ctx(cam_id), &attr);}//改写ini文件char entry[128] = {'\0'};snprintf(entry, 127, "isp.%d.night_to_day:night_to_day", rkipc_get_scenario_id(cam_id));rk_param_set_string(entry, value);return ret;
}

对ircut的操作由rk_isp_enable_ircut函数完成

rk_isp_enable_ircut函数

int rk_isp_enable_ircut(bool on) {int ret, open_gpio, close_gpio;//ircut_open_gpio = 36//ircut_close_gpio = 35open_gpio = rk_param_get_int("isp:ircut_open_gpio", -1);close_gpio = rk_param_get_int("isp:ircut_close_gpio", -1);if ((open_gpio < 0) || (close_gpio < 0)) {LOG_ERROR("fail get gpio form ini file\n");return -1;}//设置gpio方向ret = rk_gpio_export_direction(open_gpio, false);ret |= rk_gpio_export_direction(close_gpio, false);//设置值if (on) {rk_gpio_set_value(open_gpio, 1);usleep(100 * 1000);rk_gpio_set_value(open_gpio, 0);} else {rk_gpio_set_value(close_gpio, 1);usleep(100 * 1000);rk_gpio_set_value(close_gpio, 0);}//关闭gpio控制rk_gpio_unexport(open_gpio);rk_gpio_unexport(close_gpio);return ret;
}

gpio的编号计算

rv1106 GPIO的命名是GPIO{bank}_{group}{X},比如GPIO0_A0到A7,然后计算公式是pin = bank * 32 + (group * 8 + X)。例如,GPIO1_C7_d的bank是1,group是C对应2,X是7,所以计算是132 + (28+7)=55。(夸克说的)
本电路板的ircut+ 接 mx2804的 OUTB,ircut- 接 mx2804的 OUTA
mx2804的 INB 接 rv1106的pin114 GPIO2_A5_d 232+08+5=69
mx2804的 INA 接 rv1106的pin113 GPIO2_A4_d 232+08+4=68

rk_gpio_export_direction函数

该函数在luckfox-pico/project/app/rkipc/rkipc/src/rv1126_ipc_rkmedia/rk_gpio.c中

int rk_gpio_export_direction(uint32_t gpio, enum gpio_direction input) {int ret;//取得控制权ret = rk_gpio_export(gpio);if (ret < 0)goto out;//设置方向,真为输入ret = rk_gpio_set_direction(gpio, input);if (ret < 0)rk_gpio_unexport(gpio);
out:return ret;
}

rk_gpio_export函数

#define GPIO_SYSFS_PATH "/sys/class/gpio"int rk_gpio_export(uint32_t gpio) {int ret;char file[64];//例如ircut+的GPIO为69, //file为"/sys/class/gpio/gpio69"ret = sprintf(file, "%s/gpio%d", GPIO_SYSFS_PATH, gpio);if (ret < 0)return ret;//如果gpio被占用if (!access(file, F_OK)) {printf("warning: gpio %d, file (%s) has exist\n", gpio, file);return 0;}return write_sysfs_int("export", GPIO_SYSFS_PATH, gpio);
}
int write_sysfs_int(const char *filename, const char *basedir, int val) {return _write_sysfs_int(filename, basedir, val, false);
}
//filename "export"
//basedir "/sys/class/gpio"
//val 69
//verify false
static int _write_sysfs_int(const char *filename, const char *basedir, int val, bool verify) {int ret = 0;FILE *sysfsfp;int test;char *temp = (char *)malloc(strlen(basedir) + strlen(filename) + 2);if (!temp)return -ENOMEM;//temp /sys/class/gpio/exportret = sprintf(temp, "%s/%s", basedir, filename);if (ret < 0)goto error_free;//写打开/sys/class/gpio/exportsysfsfp = fopen(temp, "w");if (!sysfsfp) {ret = -errno;fprintf(stderr, "failed to open %s\n", temp);goto error_free;}//写入要export的gpio编号ret = fprintf(sysfsfp, "%d", val);if (ret < 0) {if (fclose(sysfsfp))perror("_write_sysfs_int(): Failed to close dir");goto error_free;}//关闭if (fclose(sysfsfp)) {ret = -errno;goto error_free;}if (verify) {sysfsfp = fopen(temp, "r");if (!sysfsfp) {ret = -errno;fprintf(stderr, "failed to open %s\n", temp);goto error_free;}if (fscanf(sysfsfp, "%d", &test) != 1) {ret = errno ? -errno : -ENODATA;if (fclose(sysfsfp))perror("_write_sysfs_int(): Failed to close dir");goto error_free;}if (fclose(sysfsfp)) {ret = -errno;goto error_free;}if (test != val) {fprintf(stderr, "Possible failure in int write %d to %s/%s\n", val, basedir, filename);ret = -1;}}error_free:free(temp);return ret;
}

这样系统就取得了gpio的控制权。

rk_gpio_set_direction函数

int rk_gpio_set_direction(uint32_t gpio, enum gpio_direction input) {int ret;char path[64];const char *direction = input ? "in" : "out";ret = sprintf(path, "%s/gpio%d", GPIO_SYSFS_PATH, gpio);if (ret < 0)return ret;return write_sysfs_string_and_verify("direction", path, direction);
}

和上面一样,只是换成"direction"和gpio的路径

rk_gpio_set_value

和上面差不多,最终调用write_sysfs_string_and_verify进行gpio管脚设置

int rk_gpio_set_value(uint32_t gpio, int value) {int ret;char path[64] = {0};char direction[8] = {0};ret = sprintf(path, "%s/gpio%d", GPIO_SYSFS_PATH, gpio);if (ret < 0)return ret;ret = read_sysfs_string("direction", path, direction);if (ret < 0)return ret;if (strcmp(direction, "out") != 0)return -EINVAL;return write_sysfs_int_and_verify("value", path, value);
}

rk_gpio_unexport函数

和rk_gpio_export相反,原理也差不多,通过write_sysfs_int(“unexport”, GPIO_SYSFS_PATH, gpio);进行取消控制权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/897350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Retrofit + RxJava + OkHttp 网络请求高效封装方案

Retrofit RxJava OkHttp 是 Android 开发中常用的网络请求库组合。Retrofit 是一个类型安全的 HTTP 客户端&#xff0c;RxJava 是一个响应式编程库&#xff0c;OkHttp 是一个高效的 HTTP 客户端。 Retrofit RxJava OkHttp 的组合可以提供以下功能&#xff1a; 职责清晰 R…

【nRF52832】【Nodic】开发入门【三】模块化

title: nRF52832开发入门【二】模块化 tags: nodic categories: nodic abbrlink: 37752 date: 2025-03-09 17:22:17 1. 介绍 我们实际开发过程中往往会很复杂&#xff0c;为了更好的管理代码&#xff0c;我们需要模块化。模块化的好处有很多&#xff0c;比如&#xff1a; 降…

爬虫案例八js逆向爬取网易音乐

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、js逆向的前期准备二、网站分析三、代码 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 爬取网易音乐 提示&#xff1a;以下是本篇…

vue2实现组件库的自动按需引入,unplugin-auto-import,unplugin-vue-components

1.使用ant-design-vue或者element-ui时&#xff0c;如何每个组件都去import导入组件&#xff0c;大大降低了开发效率&#xff0c;如果全局一次性注册会增加项目体积&#xff0c;那么如何实现既不局部引入&#xff0c;也不全局注册&#xff1f; 2.在element-plus官网看到有说明…

【Andrej Karpathy 神经网络从Zero到Hero】--2.语言模型的两种实现方式 (Bigram 和 神经网络)

目录 统计 Bigram 语言模型质量评价方法 神经网络语言模型 【系列笔记】 【Andrej Karpathy 神经网络从Zero到Hero】–1. 自动微分autograd实践要点 本文主要参考 大神Andrej Karpathy 大模型讲座 | 构建makemore 系列之一&#xff1a;讲解语言建模的明确入门&#xff0c;演示…

(二 十 二)趣学设计模式 之 备忘录模式!

目录 一、 啥是备忘录模式&#xff1f;二、 为什么要用备忘录模式&#xff1f;三、 备忘录模式的实现方式四、 备忘录模式的优缺点五、 备忘录模式的应用场景六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;…

安装SPSS后启动显示应用程序无法启动,因为应用程序的并行配置不正确的解决方案

软件安装报错问题有需要远程文章末尾获取联系方式&#xff0c;可以帮你远程处理各类安装报错。 一、安装SPSS后启动显示应用程序无法启动&#xff0c;因为应用程序的并行配置不正确报错 在成功安装 SPSS 软件后&#xff0c;尝试启动应用程序时&#xff0c;系统弹出错误提示窗…

IP,MAC,ARP 笔记

1.什么是IP地址 IP 地址是一串由句点分隔的数字。IP 地址表示为一组四个数字&#xff0c;比如 192.158.1.38 就是一个例子。该组合中的每个数字都可以在 0 到 255 的范围内。因此&#xff0c;完整的 IP 寻址范围从 0.0.0.0 到 255.255.255.255。 IP 地址不是随机的。它们由互…

C++11中的Condition_variable

C11中的condition_variable 在C11中&#xff0c;条件变量&#xff08;std::condition_variable&#xff09;是线程同步机制之一&#xff0c;用于在多线程环境中实现线程间的通信和协调。它允许一个或多个线程在某个条件尚未满足时等待&#xff0c;直到其他线程通知条件已经满足…

IO多路复用实现并发服务器

一.select函数 select 的调用注意事项 在使用 select 函数时&#xff0c;需要注意以下几个关键点&#xff1a; 1. 参数的修改与拷贝 readfds 等参数是结果参数 &#xff1a; select 函数会直接修改传入的 fd_set&#xff08;如 readfds、writefds 和 exceptfds&#xf…

_二级继电器程控放大倍数自动设置

简介 在开发项目中&#xff0c;有时会遇到需要使用程控放大的情况&#xff0c;如果没有opa那种可编程放大器&#xff0c;那么就需要通过继电器来控制放大倍数。而在继电器程控中&#xff0c;常用的是二级程控&#xff0c;三级程控相较于二级就复杂了许多。 在二级程控中&#x…

电脑总显示串口正在被占用处理方法

1.现象 在嵌入式开发过程中&#xff0c;有很多情况下要使用串口调试&#xff0c;其中485/422/232转usb串口是非常常见的做法。 根据协议&#xff0c;接口芯片不同&#xff0c;需要安装对应的驱动程序&#xff0c;比如ch340&#xff0c;cp2102&#xff0c;CDM212364等驱动。可…

优雅拼接字符串:StringJoiner 的完整指南

在Java开发中&#xff0c;字符串拼接是高频操作。无论是日志格式化、构建CSV数据&#xff0c;还是生成动态SQL&#xff0c;开发者常需处理分隔符、前缀和后缀的组合。传统的StringBuilder虽然灵活&#xff0c;但代码冗余且易出错。Java 8推出的StringJoiner类&#xff0c;以简洁…

LabVIEW闭环控制系统硬件选型与实时性能

在LabVIEW闭环控制系统的开发中&#xff0c;硬件选型直接影响系统的实时性、精度与稳定性。需综合考虑数据采集速度&#xff08;采样率、接口带宽&#xff09;、计算延迟&#xff08;算法复杂度、处理器性能&#xff09;、输出响应时间&#xff08;执行器延迟、控制周期&#x…

Hive的架构

1. 概念 Hive 是建立在 Hadoop 上的数据仓库工具&#xff0c;旨在简化大规模数据集的查询与管理。它通过类 SQL 语言&#xff08;HiveQL&#xff09;将结构化数据映射为 Hadoop 的 MapReduce&#xff0c;适合离线批处理&#xff0c;尤其适用于数据仓库场景。 2. 数据模型 表&a…

深入解析:Linux中KVM虚拟化技术

这篇文章将深入分析Linux中虚拟化技术的实现----KVM技术&#xff0c;从KVM技术的简介、技术架构、以及虚拟机和宿主机交互的重要处理逻辑出发&#xff0c;深入探究KVM技术的实现。 一、KVM简介&#xff1a; 首先&#xff0c;我们先查看一下KVM架构&#xff0c;看看它的整体工…

golang学习笔记——go语言安装及系统环境变量设置

文章目录 go语言安装go envgo getgoproxy测试安装 Go 插件安装 Go 插件依赖工具参考资料用户环境变量和系统环境变量用户环境变量系统环境变量示例设置环境变量的步骤设置用户环境变量设置系统环境变量 验证环境变量总结 2024年最火的5大Go框架1. Gin&#xff1a;高并发接口的“…

3.6c语言

#define _CRT_SECURE_NO_WARNINGS #include <math.h> #include <stdio.h> int main() {int sum 0,i,j;for (j 1; j < 1000; j){sum 0;for (i 1; i < j; i){if (j % i 0){sum i;} }if (sum j){printf("%d是完数\n", j);}}return 0; }#de…

【TI】如何更改 CCS20.1.0 的 WORKSPACE 默认路径

参考链接&#xff1a; 如何更改 CCS Theia 中工作区的默认位置&#xff1f;- Code Composer Studio 论坛 - Code Composer Studio™︎ - TI E2E 支持论坛 --- How to change the default location for the workspace in CCS Theia? - Code Composer Studio forum - Code Comp…

Vue3中动态Ref的魔法:绑定与妙用

前言 在Vue 3的开发过程中,动态绑定Ref是一项非常实用的技术,特别是在处理复杂组件结构和动态数据时。通过动态绑定Ref,我们可以更灵活地访问和操作DOM元素或组件实例,实现更高效的交互和状态管理。本文将详细介绍如何在Vue 3中实现动态Ref的绑定,并通过实例展示其妙用。…