xiaoyu/project/app/aov_sample/common/aov/sample_comm_aov.c
2025-03-04 22:36:42 +08:00

1088 lines
33 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sample_comm_aov.h"
#include "sample_comm.h"
#include <net/if.h> // must be included later than <net/if.h>
#include <linux/if.h> // must be included later than <net/if.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/input.h>
#define MAX_CAMERA_NUM 3
#ifdef AOV_FASTBOOT_ENABLE
#include "rk_meta.h"
#include "rk_meta_wakeup_param.h"
#include "sensor_iq_info.h"
// Memory region definitions
#define META_PHY_ADDR 0x800000
// Meta region
#define META_SIZE (384 * 1024)
struct meta_para_vir {
int mem_fd;
void *mapped_base;
void *meta_head;
int meta_head_size;
void *param_share2kernel_offset;
int param_share2kernel_offset_size;
void *sensor_init_offset;
int sensor_init_offset_size;
void *cmdline_offset;
int cmdline_offset_size;
void *ae_table_offset;
int ae_table_offset_size;
void *app_param_offset;
int app_param_offset_size;
void *secondary_sensor_init_offset;
int secondary_sensor_init_offset_size;
void *wakeup_param_offset;
int wakeup_param_offset_size;
void *reserve;
int reserve_size;
void *backup;
int backup_size;
void *sensor_iq_bin_offset;
int sensor_iq_bin_offset_size;
void *secondary_sensor_iq_bin_offset;
int secondary_sensor_iq_bin_offset_size;
void *wakeup_aov_param_offset;
int wakeup_aov_param_max_size;
};
static struct meta_para_vir *g_meta_vir = NULL;
#endif // #ifdef AOV_FASTBOOT_ENABLE
#define MAX_NL_BUF_SIZE (1024 * 16)
#define MAX_SELECT_TIMEOUT (2 * 1000 * 1000)
static pthread_mutex_t g_wakeup_run_mutex = PTHREAD_MUTEX_INITIALIZER;
static RK_S32 g_input_device_fd = -1;
#ifdef AOV_FASTBOOT_ENABLE
static void SAMPLE_COMM_AOV_MetaDump() {
if (!g_meta_vir) {
printf("[%s()] empty meta!\n", __func__);
return;
}
printf("g_meta_vir->mem_fd: %d\n", g_meta_vir->mem_fd);
printf("g_meta_vir->mapped_base: %p\n", g_meta_vir->mapped_base);
printf("g_meta_vir->meta_head: %p\n", g_meta_vir->meta_head);
printf("g_meta_vir->meta_head_size: %d\n", g_meta_vir->meta_head_size);
printf("g_meta_vir->param_share2kernel_offset: %p\n",
g_meta_vir->param_share2kernel_offset);
printf("g_meta_vir->param_share2kernel_offset_size: %d\n",
g_meta_vir->param_share2kernel_offset_size);
printf("g_meta_vir->sensor_init_offset: %p\n", g_meta_vir->sensor_init_offset);
printf("g_meta_vir->sensor_init_offset_size: %d\n",
g_meta_vir->sensor_init_offset_size);
printf("g_meta_vir->cmdline_offset: %p\n", g_meta_vir->cmdline_offset);
printf("g_meta_vir->cmdline_offset_size: %d\n", g_meta_vir->cmdline_offset_size);
printf("g_meta_vir->ae_table_offset: %p\n", g_meta_vir->ae_table_offset);
printf("g_meta_vir->ae_table_offset_size: %d\n", g_meta_vir->ae_table_offset_size);
printf("g_meta_vir->app_param_offset: %p\n", g_meta_vir->app_param_offset);
printf("g_meta_vir->app_param_offset_size: %d\n", g_meta_vir->app_param_offset_size);
printf("g_meta_vir->secondary_sensor_init_offset: %p\n",
g_meta_vir->secondary_sensor_init_offset);
printf("g_meta_vir->secondary_sensor_init_offset_size: %d\n",
g_meta_vir->wakeup_param_offset_size);
printf("g_meta_vir->wakeup_param_offset: %p\n", g_meta_vir->wakeup_param_offset);
printf("g_meta_vir->wakeup_param_offset_size: %d\n",
g_meta_vir->secondary_sensor_init_offset_size);
printf("g_meta_vir->reserve: %p\n", g_meta_vir->reserve);
printf("g_meta_vir->reserve_size: %d\n", g_meta_vir->reserve_size);
printf("g_meta_vir->backup: %p\n", g_meta_vir->backup);
printf("g_meta_vir->backup_size: %d\n", g_meta_vir->backup_size);
printf("g_meta_vir->sensor_iq_bin_offset: %p\n", g_meta_vir->sensor_iq_bin_offset);
printf("g_meta_vir->sensor_iq_bin_offset_size: %d\n",
g_meta_vir->sensor_iq_bin_offset_size);
printf("g_meta_vir->secondary_sensor_iq_bin_offset: %p\n",
g_meta_vir->secondary_sensor_iq_bin_offset);
printf("g_meta_vir->secondary_sensor_iq_bin_offset_size: %d\n",
g_meta_vir->secondary_sensor_iq_bin_offset_size);
printf("g_meta_vir->wakeup_aov_param_offset: %p\n",
g_meta_vir->wakeup_aov_param_offset);
printf("g_meta_vir->wakeup_aov_param_max_size: %d\n",
g_meta_vir->wakeup_aov_param_max_size);
// ... Print other fields ...
}
#define se32_to_be32(x) \
((0x000000FF & x) << 24) | ((0x0000FF00 & x) << 8) | ((0x00FF0000 & x) >> 8) | \
((0xFF000000 & x) >> 24)
static int SAMPLE_COMM_AOV_MetaMmap() {
int mem_fd = -1;
void *mapped_base, *virt_addr;
uint32_t meta_addr, meta_size;
int dts_fd;
if (g_meta_vir != NULL) {
printf("[%s()] g_meta_vir has been mapped!", __func__);
return RK_FAILURE;
}
g_meta_vir = malloc(sizeof(struct meta_para_vir));
if (g_meta_vir == NULL) {
printf("[%s()] g_meta_vir malloc failed!", __func__);
return RK_FAILURE;
}
memset(g_meta_vir, 0, sizeof(struct meta_para_vir));
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd == -1) {
perror("Error opening /dev/mem");
return EXIT_FAILURE;
}
dts_fd =
open("/sys/firmware/devicetree/base/reserved-memory/meta@800000/reg", O_RDONLY);
if (dts_fd > 0) {
int read_bytes = read(dts_fd, &meta_addr, sizeof(meta_addr));
read_bytes = read(dts_fd, &meta_size, sizeof(meta_size));
if (read_bytes > 0) {
meta_size = se32_to_be32(meta_size);
meta_addr = se32_to_be32(meta_addr);
printf("# read firmware meta addr 0X%08x size 0X%08x!\n", meta_addr,
meta_size);
} else {
meta_size = META_SIZE;
meta_addr = META_PHY_ADDR;
printf("# read dts reg failed!\n");
}
close(dts_fd);
} else {
meta_size = META_SIZE;
meta_addr = META_PHY_ADDR;
printf("# read dts failed!\n");
}
mapped_base =
mmap(0, meta_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, meta_addr);
if (mapped_base == MAP_FAILED) {
perror("Error mapping physical address to virtual address");
close(mem_fd);
return EXIT_FAILURE;
}
g_meta_vir->mem_fd = mem_fd;
g_meta_vir->mapped_base = mapped_base;
g_meta_vir->meta_head = mapped_base + META_INFO_HEAD_OFFSET;
g_meta_vir->meta_head_size = META_INFO_SIZE;
g_meta_vir->param_share2kernel_offset = mapped_base + PARAM_SHARE2KERNEL_OFFSET;
g_meta_vir->param_share2kernel_offset_size = PARAM_SHARE2KERNEL_SIZE;
g_meta_vir->sensor_init_offset = mapped_base + SENSOR_INIT_OFFSET;
g_meta_vir->sensor_init_offset_size = SENSOR_INIT_MAX_SIZE;
g_meta_vir->cmdline_offset = mapped_base + CMDLINE_OFFSET;
g_meta_vir->cmdline_offset_size = CMDLINE_MAX_SIZE;
g_meta_vir->ae_table_offset = mapped_base + AE_TABLE_OFFSET;
g_meta_vir->ae_table_offset_size = AE_TABLE_MAX_SIZE;
g_meta_vir->app_param_offset = mapped_base + APP_PARAM_OFFSET;
g_meta_vir->app_param_offset_size = APP_PARAM_MAX_SIZE;
g_meta_vir->secondary_sensor_init_offset = mapped_base + SECONDARY_SENSOR_INIT_OFFSET;
g_meta_vir->secondary_sensor_init_offset_size = SECONDARY_SENSOR_INIT_MAX_SIZE;
g_meta_vir->wakeup_param_offset = mapped_base + WAKEUP_PARAM_OFFSET;
g_meta_vir->wakeup_param_offset_size = WAKEUP_PARAM_MAX_SIZE;
// g_meta_vir->reserve = mapped_base + RESERVE;
// g_meta_vir->reserve_size = RESERVE_SIZE;
// g_meta_vir->backup = mapped_base + BACKUP;
// g_meta_vir->backup_size = BACKUP_SIZE;
g_meta_vir->sensor_iq_bin_offset = mapped_base + SENSOR_IQ_BIN_OFFSET;
g_meta_vir->sensor_iq_bin_offset_size = SENSOR_IQ_BIN_MAX_SIZE;
g_meta_vir->secondary_sensor_iq_bin_offset =
mapped_base + SECONDARY_SENSOR_IQ_BIN_OFFSET;
g_meta_vir->secondary_sensor_iq_bin_offset_size = SENSOR_IQ_BIN_MAX_SIZE;
// g_meta_vir->secondary_sensor_iq_bin_offset_size = 0; // not support
g_meta_vir->wakeup_aov_param_offset = mapped_base + WAKEUP_AOV_PARAM_OFFSET;
g_meta_vir->wakeup_aov_param_max_size = WAKEUP_AOV_PARAM_MAX_SIZE;
SAMPLE_COMM_AOV_MetaDump(g_meta_vir);
// init mcu mode
struct wakeup_param_info *wakeup_param =
(struct wakeup_param_info *)g_meta_vir->wakeup_param_offset;
wakeup_param->wakeup_mode = 0;
wakeup_param->ae_wakeup_mode = 0;
wakeup_param->arm_run_count = 0;
wakeup_param->arm_max_run_count = -1;
wakeup_param->mcu_run_count = 0;
wakeup_param->mcu_max_run_count = -1;
return RK_SUCCESS;
}
static int SAMPLE_COMM_AOV_MetaMunmap() {
if (g_meta_vir) {
if (g_meta_vir->mapped_base)
munmap(g_meta_vir->mapped_base, META_SIZE);
if (g_meta_vir->mem_fd >= 0)
close(g_meta_vir->mem_fd);
free(g_meta_vir);
g_meta_vir = NULL;
} else {
printf("[%s()] empty g_meta_vir!\n", __func__);
return RK_FAILURE;
}
return RK_SUCCESS;
}
#endif // #ifdef AOV_FASTBOOT_ENABLE
#ifdef RK_ENABLE_RTT
int SAMPLE_COMM_Get_WakeupBin_Info(uint32_t *addr, uint32_t *size) {
#define RTT_BIN_PARAM "/proc/device-tree/reserved-memory/rtos@40000/reg"
#define uswap_32(x) \
((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | (((x)&0x0000ff00) << 8) | \
(((x)&0x000000ff) << 24))
int rtt_bin_param_fd = -1;
struct RttBinParam {
unsigned int addr;
unsigned int size;
};
struct RttBinParam bin_param = {0, 0};
if ((rtt_bin_param_fd = open(RTT_BIN_PARAM, O_RDONLY)) < 0) {
printf("cannot open [%s]\n", RTT_BIN_PARAM);
return RK_FAILURE;
}
if (read(rtt_bin_param_fd, (void *)&bin_param, sizeof(bin_param)) == -1) {
printf("read log param error.\n");
if (rtt_bin_param_fd != -1)
close(rtt_bin_param_fd);
return RK_FAILURE;
}
if (rtt_bin_param_fd != -1)
close(rtt_bin_param_fd);
bin_param.addr = uswap_32(bin_param.addr);
bin_param.size = uswap_32(bin_param.size);
printf("rtt wakeup bin addr [%#x]\n", bin_param.addr);
printf("rtt wakeup bin size [%#x]\n", bin_param.size);
*addr = bin_param.addr;
*size = bin_param.size;
return RK_SUCCESS;
}
int SAMPLE_COMM_AOV_WakeupBinMmap(const char *rtthread_wakeup_bin_path) {
int mem_fd = -1;
uint32_t rtt_bin_addr, rtt_bin_max_size;
void *mapped_base, *virt_addr;
if (access(rtthread_wakeup_bin_path, F_OK) != 0) {
perror("read ree wakeup bin info error");
return EXIT_FAILURE;
}
if (SAMPLE_COMM_Get_WakeupBin_Info(&rtt_bin_addr, &rtt_bin_max_size) != 0) {
return EXIT_FAILURE;
}
FILE *rtt_bin_file = fopen(rtthread_wakeup_bin_path, "r");
if (rtt_bin_file == NULL) {
perror("Error opening meta file");
close(mem_fd);
return EXIT_FAILURE;
}
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd == -1) {
perror("Error opening /dev/mem");
fclose(rtt_bin_file);
return EXIT_FAILURE;
}
mapped_base = mmap(0, rtt_bin_max_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd,
rtt_bin_addr);
if (mapped_base == MAP_FAILED) {
perror("Error mapping physical address to virtual address");
fclose(rtt_bin_file);
close(mem_fd);
return EXIT_FAILURE;
}
memset(mapped_base, 0, rtt_bin_max_size);
char buffer[1024];
size_t read_bytes;
while ((read_bytes = fread(buffer, 1, sizeof(buffer), rtt_bin_file)) > 0) {
memcpy(mapped_base, buffer, read_bytes);
mapped_base += read_bytes;
}
fclose(rtt_bin_file);
munmap(mapped_base, rtt_bin_max_size);
close(mem_fd);
return RK_SUCCESS;
}
#endif // #ifdef RK_ENABLE_RTT
int SAMPLE_COMM_AOV_Init() {
#ifdef AOV_FASTBOOT_ENABLE
SAMPLE_COMM_AOV_MetaMmap();
#endif
// INFO:
// Find event device path in /proc/bus/input/devices is a better way.
g_input_device_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
if (g_input_device_fd < 0) {
printf("Open failed /dev/input/event0: %s, you can ignore this"
" msg if you don't need gpio wakeup...\n",
strerror(errno));
}
pthread_mutex_init(&g_wakeup_run_mutex, NULL);
return RK_SUCCESS;
}
int SAMPLE_COMM_AOV_Deinit() {
pthread_mutex_lock(&g_wakeup_run_mutex);
#ifdef AOV_FASTBOOT_ENABLE
SAMPLE_COMM_AOV_MetaMunmap();
#endif
pthread_mutex_unlock(&g_wakeup_run_mutex);
pthread_mutex_destroy(&g_wakeup_run_mutex);
if (g_input_device_fd >= 0)
close(g_input_device_fd);
}
void SAMPLE_COMM_AOV_EnterSleep() {
#if 0
pthread_mutex_lock(&g_wakeup_run_mutex);
writeReg(0x02000200, 8); // output
// writeReg(0x02000000, 0); //low
// usleep(50 * 1000);
writeReg(0x02000200, 0); // high
#endif
pthread_mutex_lock(&g_wakeup_run_mutex);
FILE *file;
// 打开文件
file = fopen("/sys/power/state", "w");
if (file == NULL) {
perror("Failed to open /sys/power/state");
pthread_mutex_unlock(&g_wakeup_run_mutex);
exit(EXIT_FAILURE);
}
// 写入字符串
const char *state = "mem";
printf("start echo mem > /sys/power/state\n");
// 进入休眠
size_t bytes_written = fwrite(state, sizeof(char), strlen(state), file);
if (bytes_written != strlen(state)) {
perror("Failed to write to /sys/power/state");
fclose(file);
pthread_mutex_unlock(&g_wakeup_run_mutex);
exit(EXIT_FAILURE);
}
fflush(file);
// 关闭文件
fclose(file);
#if 0
writeReg(0x02000200, 8); // output
writeReg(0x02000000, 0); // low
// writeReg(0x02000200, 8); //output
// writeReg(0x02000000, 0); //low
// usleep(50 * 1000);
// writeReg(0x02000200, 0); //high
pthread_mutex_unlock(&g_wakeup_run_mutex);
#endif
pthread_mutex_unlock(&g_wakeup_run_mutex);
}
int SAMPLE_COMM_AOV_SetSuspendTime(int wakeup_suspend_time) {
char wakeup_cmd[256];
sprintf(wakeup_cmd, "io -4 0xff300048 %d", wakeup_suspend_time * 32);
system(wakeup_cmd);
sleep(1);
printf("wakeup suspend time = %d", wakeup_suspend_time);
return RK_SUCCESS;
}
int SAMPLE_COMM_AOV_PreInitIsp(const char *sensor_name, const char *iq_file_dir,
int cam_index) {
int ret = RK_SUCCESS;
rk_aiq_tb_info_t tb_info;
struct sensor_iq_info *sensor_iq = NULL;
void *main_iq_offset = NULL;
void *secondary_iq_offset = NULL;
pthread_mutex_lock(&g_wakeup_run_mutex);
memset(&tb_info, 0, sizeof(rk_aiq_tb_info_t));
tb_info.magic = sizeof(rk_aiq_tb_info_t) - 2;
#ifdef AOV_FASTBOOT_ENABLE
if (!g_meta_vir) {
printf("[%s()] empty meta image!\n", __func__);
pthread_mutex_unlock(&g_wakeup_run_mutex);
return RK_FAILURE;
}
if (cam_index < MAX_CAMERA_NUM) {
sensor_iq = (struct sensor_iq_info *)g_meta_vir->sensor_iq_bin_offset;
main_iq_offset = (uint8_t *)g_meta_vir->mapped_base +
(sensor_iq->main_sensor_iq_offset - META_PHY_ADDR);
secondary_iq_offset = (uint8_t *)g_meta_vir->mapped_base +
(sensor_iq->secondary_sensor_iq_offset - META_PHY_ADDR);
printf("[%s()] main addr %p size %d, second addr %p size %d\n", __func__,
sensor_iq->main_sensor_iq_offset, sensor_iq->main_sensor_iq_size,
sensor_iq->secondary_sensor_iq_offset,
sensor_iq->secondary_sensor_iq_size);
} else {
printf("[%s()] error camera index %d!\n", __func__, cam_index);
pthread_mutex_unlock(&g_wakeup_run_mutex);
return RK_FAILURE;
}
tb_info.is_start_once = true;
tb_info.is_pre_aiq = true;
tb_info.prd_type = RK_AIQ_PRD_TYPE_TB_BATIPC;
// tb_info.rtt_share_addr = g_meta_vir->wakeup_aov_param_offset;
tb_info.rtt_share_addr = 0;
#else
tb_info.is_start_once = false;
tb_info.is_pre_aiq = false;
tb_info.prd_type = RK_AIQ_PRD_TYPE_SINGLE_FRAME;
tb_info.rtt_share_addr = 0;
if (iq_file_dir != NULL) {
printf("rkaiq use iqfiles from %s\n", iq_file_dir);
tb_info.iq_bin_mode = RK_AIQ_META_NOT_FULL_IQ_BIN;
}
#endif
ret = rk_aiq_uapi2_sysctl_preInit_tb_info(sensor_name, &tb_info);
if (ret != RK_SUCCESS)
printf("[%s()] rk_aiq_uapi2_sysctl_preInit_tb_info failed %#X!\n", __func__, ret);
#ifdef AOV_FASTBOOT_ENABLE
if (cam_index == 0)
ret = rk_aiq_uapi2_sysctl_preInit_iq_addr(sensor_name, main_iq_offset,
sensor_iq->main_sensor_iq_size);
else if (cam_index == 1)
ret = rk_aiq_uapi2_sysctl_preInit_iq_addr(sensor_name, secondary_iq_offset,
sensor_iq->secondary_sensor_iq_size);
else
printf("[%s()] not support camera index %d now!\n", cam_index);
if (ret != RK_SUCCESS)
printf("[%s()] rk_aiq_uapi2_sysctl_preInit_iq_addr failed %#X!\n", __func__, ret);
#endif
pthread_mutex_unlock(&g_wakeup_run_mutex);
return ret;
}
#define ETHERNET_DEVICE "ffa80000.ethernet"
#define ETHERNET_DRIVER "/sys/bus/platform/drivers/rk_gmac-dwmac/"
// #define NIC_DEVICE "stmmac-0:02"
// #define NIC_DRIVER "/sys/bus/mdio_bus/drivers/RK630 PHY/"
#define ETHERNET_BIND_DONE "/sys/bus/platform/drivers/rk_gmac-dwmac/"
#define ETHERNET_UNBNID_DONE "/sys/bus/platform/drivers/rk_gmac-dwmac/"
int SAMPLE_COMM_AOV_BindEthernet() {
char buf[MAX_NL_BUF_SIZE] = {'\0'};
char name[256] = {'\0'};
int ret = 0;
int fd = -1;
int len = MAX_NL_BUF_SIZE;
fd_set read_set;
struct ifreq ifr;
struct timeval timeout;
struct sockaddr_nl addr;
struct nlmsghdr *nh = NULL;
struct ifinfomsg *ifinfo = NULL;
printf("[%s()] Enter\n", __func__);
if (access(ETHERNET_DRIVER ETHERNET_DEVICE, F_OK) == 0) {
printf("[%s()] ethernet device already bind!\n", __func__);
goto __FAILED;
}
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK;
addr.nl_pid = getpid();
if (fd < 0) {
printf("[%s()] Failed to open network netlink because %s\n", __func__,
strerror(errno));
goto __FAILED;
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
printf("[%s()] bind network netlink addr failed because %s\n", __func__,
strerror(errno));
goto __FAILED;
}
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
timeout.tv_sec = 0;
timeout.tv_usec = MAX_SELECT_TIMEOUT;
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,
(socklen_t)sizeof(struct timeval));
// bind ethernet driver
SAMPLE_COMM_ECHO(ETHERNET_DRIVER "bind", ETHERNET_DEVICE, (strlen(ETHERNET_DEVICE)));
#if 1
// open etherner device
system("ifconfig eth0 up");
// reset local ip, gateway and dns resolvation
system("killall -9 udhcpc"); // restart udhcpc
system("route del default gw 0.0.0.0"); // delete default gateway
system("cat /dev/null > /etc/resolv.conf"); // reset DNS resolvation
system("udhcpc -i eth0 -T 1 -A 0 -b -q"); // find a new ip address for eth0
#endif
// wait for bind success
// FIXME:
// there has some bug for select()
// ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
memset(&buf, 0, sizeof(buf));
while ((ret = read(fd, buf, sizeof(buf))) > 0) {
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) {
if (nh->nlmsg_type == NLMSG_DONE) {
printf("[%s()] NLMSG_DONE\n", __func__);
goto __FAILED;
}
if (nh->nlmsg_type == NLMSG_ERROR) {
printf("[%s()] NLMSG_ERROR\n", __func__);
goto __FAILED;
}
if (nh->nlmsg_type != RTM_NEWLINK) {
printf("[%s()] not RTM_NEWLINK, ignore\n", __func__);
continue;
}
ifinfo = NLMSG_DATA(nh);
if_indextoname(ifinfo->ifi_index, name);
// printf("[%s()] %s: up %s, lower up %s, running %s, value 0X%X\n", __func__
// , name
// , (ifinfo->ifi_flags & IFF_UP) ? "true" : "false"
// , (ifinfo->ifi_flags & IFF_LOWER_UP) ? "true" : "false"
// , (ifinfo->ifi_flags & IFF_RUNNING) ? "true" : "false"
// , ifinfo->ifi_flags
// );
if ((ifinfo->ifi_flags & IFF_RUNNING) && (ifinfo->ifi_flags & IFF_LOWER_UP) &&
(ifinfo->ifi_flags & IFF_UP)) {
printf("[%s()] ethernet bind success!\n", __func__);
goto __SUCCESS;
}
}
}
if (ret < 0)
goto __FAILED;
__SUCCESS:
if (fd >= 0)
close(fd);
printf("[%s()] Exit\n", __func__);
return RK_SUCCESS;
__FAILED:
if (fd >= 0)
close(fd);
printf("[%s()] Exit Error\n", __func__);
return RK_FAILURE;
}
int SAMPLE_COMM_AOV_UnbindEthernet() {
char buf[MAX_NL_BUF_SIZE] = {'\0'};
char name[256] = {'\0'};
int ret = 0;
int fd = -1;
int len = MAX_NL_BUF_SIZE;
fd_set read_set;
struct sockaddr_nl addr;
struct timeval timeout;
struct nlmsghdr *nh = NULL;
struct ifinfomsg *ifinfo = NULL;
printf("[%s()] Enter\n", __func__);
if (access(ETHERNET_DRIVER ETHERNET_DEVICE, F_OK) != 0) {
printf("[%s()] ethernet device already unbind!\n", __func__);
goto __FAILED;
}
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK;
addr.nl_pid = getpid();
if (fd < 0) {
printf("[%s()] Failed to open network netlink because %s\n", __func__,
strerror(errno));
return RK_FAILURE;
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
printf("[%s()] bind network netlink addr failed because %s\n", __func__,
strerror(errno));
goto __FAILED;
}
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
timeout.tv_sec = 0;
timeout.tv_usec = MAX_SELECT_TIMEOUT;
// close ethernet device
system("ifconfig eth0 0.0.0.0");
system("ifconfig eth0 down");
// unbind ethernet driver
SAMPLE_COMM_ECHO(ETHERNET_DRIVER "unbind", ETHERNET_DEVICE,
(strlen(ETHERNET_DEVICE)));
// wait for unbind done
__RETRY:
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
if (ret > 0) {
memset(&buf, 0, sizeof(buf));
ret = read(fd, buf, sizeof(buf));
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) {
if (nh->nlmsg_type == NLMSG_DONE) {
printf("[%s()] NLMSG_DONE\n", __func__);
goto __FAILED;
}
if (nh->nlmsg_type == NLMSG_ERROR) {
printf("[%s()] NLMSG_ERROR\n", __func__);
goto __FAILED;
}
ifinfo = NLMSG_DATA(nh);
if_indextoname(ifinfo->ifi_index, name);
// printf("[%s()] %s: up %s, lower up %s, running %s, value 0X%X\n", __func__
// , name
// , (ifinfo->ifi_flags & IFF_UP) ? "true" : "false"
// , (ifinfo->ifi_flags & IFF_LOWER_UP) ? "true" : "false"
// , (ifinfo->ifi_flags & IFF_RUNNING) ? "true" : "false"
// , ifinfo->ifi_flags
// );
if (!(ifinfo->ifi_flags & IFF_RUNNING) &&
!(ifinfo->ifi_flags & IFF_LOWER_UP) && !(ifinfo->ifi_flags & IFF_UP)) {
printf("[%s()] ethernet unbind success!\n", __func__);
goto __SUCCESS;
}
}
// printf("[%s()] Bind msg: %s\n", __func__, buf);
goto __RETRY; // drop all message
} else {
printf("[%s()] select error: %s\n", __func__, strerror(errno));
goto __FAILED;
}
__SUCCESS:
close(fd);
// open etherner device
printf("[%s()] Exit\n", __func__);
return RK_SUCCESS;
__FAILED:
close(fd);
printf("[%s()] Exit Error\n", __func__);
return RK_FAILURE;
}
#define SDCARD_ADDR_STR "ffaa0000.mmc"
#define SDCARD_NODE_BIND "/sys/bus/platform/drivers/dwmmc_rockchip/bind"
#define SDCARD_NODE_UNBIND "/sys/bus/platform/drivers/dwmmc_rockchip/unbind"
#define SDCARD_NODE_DEVICE "/sys/bus/platform/drivers/dwmmc_rockchip/ffaa0000.mmc"
#define SDCARD_BIND_DONE "bind@/devices/platform/ffaa0000.mmc/mmc_host/mmc1/mmc1"
#define SDCARD_UNBIND_DONE "unbind@/devices/platform/ffaa0000.mmc"
int SAMPLE_COMM_AOV_BindSdcard() {
int ret = 0;
int fd = -1;
char buf[MAX_NL_BUF_SIZE] = {'\0'};
fd_set read_set;
struct timeval timeout;
struct sockaddr_nl addr;
if (access(SDCARD_NODE_DEVICE, F_OK) == 0) {
printf("[%s()] sdcard device already bind!\n", __func__);
return RK_SUCCESS;
}
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
addr.nl_pid = 0;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (fd < 0) {
printf("[%s()] Failed to open sdcard netlink because %s\n", __func__,
strerror(errno));
return RK_FAILURE;
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
printf("[%s()] bind sdcard netlink addr failed because %s\n", __func__,
strerror(errno));
goto __FAILED;
}
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
timeout.tv_sec = 0;
timeout.tv_usec = MAX_SELECT_TIMEOUT;
// bind sdcard
SAMPLE_COMM_ECHO(SDCARD_NODE_BIND, SDCARD_ADDR_STR, (sizeof(SDCARD_ADDR_STR)));
// wait for bind success
__RETRY:
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
if (ret > 0) {
memset(&buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf));
buf[MAX_NL_BUF_SIZE - 1] = '\0';
// printf("[%s()] bind msg: %s\n", __func__, buf);
if (strncmp(buf, SDCARD_BIND_DONE, strlen(SDCARD_BIND_DONE)) == 0) {
printf("[%s()] Bind success: %s\n", __func__, buf);
goto __SUCCESS;
}
goto __RETRY; // drop all message
} else {
printf("[%s()] select error %s\n", __func__, strerror(errno));
goto __FAILED;
}
__SUCCESS:
close(fd);
return RK_SUCCESS;
__FAILED:
close(fd);
return RK_FAILURE;
}
int SAMPLE_COMM_AOV_UnbindSdcard() {
int ret = 0;
int fd = -1;
char buf[MAX_NL_BUF_SIZE] = {'\0'};
fd_set read_set;
struct timeval timeout;
struct sockaddr_nl addr;
if (access(SDCARD_NODE_DEVICE, F_OK) != 0) {
printf("[%s()] sdcard device already unbind!\n", __func__);
return RK_SUCCESS;
}
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
addr.nl_pid = 0;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (fd < 0) {
printf("[%s()] Failed to open sdcard netlink because %s\n", __func__,
strerror(errno));
return RK_FAILURE;
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
printf("[%s()] bind sdcard netlink addr failed because %s\n", __func__,
strerror(errno));
goto __FAILED;
}
memset(&buf, 0, sizeof(buf));
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
timeout.tv_sec = 0;
timeout.tv_usec = MAX_SELECT_TIMEOUT;
// unbind sdcard
SAMPLE_COMM_ECHO(SDCARD_NODE_UNBIND, SDCARD_ADDR_STR, (sizeof(SDCARD_ADDR_STR)));
// wait for unbind success
__RETRY:
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
if (ret > 0) {
memset(&buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf));
buf[MAX_NL_BUF_SIZE - 1] = '\0';
// printf("[%s()] unbind msg: %s\n", __func__, buf);
if (strcmp(buf, SDCARD_UNBIND_DONE) == 0) {
printf("[%s()] Unbind success: %s\n", __func__, buf);
goto __SUCCESS;
}
goto __RETRY; // drop all message
} else {
printf("[%s()] select error %s\n", __func__, strerror(errno));
goto __FAILED;
}
__SUCCESS:
close(fd);
return RK_SUCCESS;
__FAILED:
close(fd);
return RK_FAILURE;
}
static int SAMPLE_COMM_AOV_CheckSDcardMount(void) {
FILE *file = fopen("/proc/mounts", "r");
int ret = RK_FAILURE;
if (file == NULL) {
printf("Failed to open file\n");
return ret;
}
char line[256];
while (fgets(line, sizeof(line), file)) {
if (strstr(line, "/mnt/sdcard")) {
printf("Found '/mnt/sdcard' in line: %s", line);
ret = RK_SUCCESS;
}
}
fclose(file);
return ret;
} /* ----- end of function SAMPLE_COMM_AOV_CheckSDcardMount ----- */
int SAMPLE_COMM_AOV_CopyStreamToSdcard(int venc_chn_id, char *data, int data_size,
char *data2, int data2_size) {
int ret = 0;
pthread_mutex_lock(&g_wakeup_run_mutex);
SAMPLE_COMM_AOV_BindSdcard();
// mount sd
if (access("/dev/mmcblk1p1", F_OK) == 0) {
// system("mount -t vfat /dev/mmcblk1p1 /mnt/sdcard/");
ret = mount("/dev/mmcblk1p1", "/mnt/sdcard", "vfat", 0, NULL);
if (ret != 0)
printf("[%s()] mount failed because %s\n", __func__, strerror(errno));
else
printf("[%s()] mount success\n", __func__);
} else if (access("/dev/mmcblk1", F_OK) == 0) {
// system("mount -t vfat /dev/mmcblk1 /mnt/sdcard/");
ret = mount("/dev/mmcblk1", "/mnt/sdcard", "vfat", 0, NULL);
if (ret != 0)
printf("[%s()] mount failed because %s\n", __func__, strerror(errno));
else
printf("[%s()] mount success\n", __func__);
} else {
printf("[%s()] bad mount path!\n", __func__);
goto SAMPLE_COMM_AOV_CopyStreamToSdcard_end;
}
if (0 != SAMPLE_COMM_AOV_CheckSDcardMount()) {
printf("Not found mount sdcard on /mnt/sdcard\n");
goto SAMPLE_COMM_AOV_CopyStreamToSdcard_end;
}
static int count_t = 0;
static char dstPath[256];
int s32fd = 0;
char dst[256];
// 首次进来存储遍历目录是否可用最多100个目录
if (count_t == 0) {
int i = 0;
for (i = 0; i < 100; i++) {
sprintf(dstPath, "/mnt/sdcard/wakeup_frame_%d", i);
struct stat st;
if (stat(dstPath, &st) == -1) {
if (mkdir(dstPath, 0777) == -1)
printf("mkdir %s failed\n", dstPath);
break;
}
}
}
sprintf(dst, "%s/venc_chn%d_%d.h265", dstPath, venc_chn_id, count_t);
FILE *fp = fopen(dst, "wb");
if (fp != NULL) {
fwrite(data, 1, data_size, fp);
if (data2)
fwrite(data2, 1, data2_size, fp);
s32fd = fileno(fp);
fsync(s32fd);
fclose(fp);
count_t++;
}
// unmount sdcard
umount2("/mnt/sdcard", MNT_DETACH);
SAMPLE_COMM_AOV_CopyStreamToSdcard_end:
SAMPLE_COMM_AOV_UnbindSdcard();
pthread_mutex_unlock(&g_wakeup_run_mutex);
return RK_SUCCESS;
}
void SAMPLE_COMM_AOV_DumpPtsToTMP(uint32_t seq, uint64_t pts, int max_dump_pts_count) {
static int line_count = 0;
static FILE *file;
const char *file_path = "/tmp/pts.txt";
if (line_count >= max_dump_pts_count) {
return;
}
if (line_count == 0) {
file = fopen(file_path, "w");
if (file == NULL) {
perror("Error opening file");
return;
}
}
if (file != NULL)
fprintf(file, "seq: %u, pts: %llums\n", seq, (unsigned long long)pts / 1000);
line_count++;
if (line_count >= max_dump_pts_count) {
printf("Closed file after writing %d lines.\n", max_dump_pts_count);
fclose(file);
file = NULL;
}
}
// Return true is there has input event happened.
bool SAMPLE_COMM_AOV_GetGpioIrqStat() {
bool input_event_happened = false;
struct input_event event;
if (g_input_device_fd < 0) {
// printf("[%s()] unsupport input event detector\n", __func__);
return input_event_happened;
}
// The read() operation is non-block, so the loop would
// return EGAGIN if there has no any new input event.
while (read(g_input_device_fd, &event, sizeof(event)) > 0) {
// printf("[%s()] detect event type %d, code %d, value %d\n"
// , __func__
// , event.type
// , event.code
// , event.value
// );
// Translate ISP state if gpio-key is pressed between
// sleeping time.
if (event.type == EV_KEY && event.code == KEY_POWER && event.value == 1)
input_event_happened = true;
}
return input_event_happened;
}
#define SOUND_BIND_DONE "bind@/devices/platform/acodec-sound"
#define SOUND_UNBIND_DONE "unbind@/devices/platform/ffae0000.i2s"
#define I2S_DRIVER "/sys/bus/platform/drivers/rockchip-i2s-tdm/"
#define ACODEC_DRIVER "/sys/bus/platform/drivers/rv1106-acodec/"
#define ASOC_DRIVER "/sys/bus/platform/drivers/asoc-simple-card/"
#define I2S_DEVICE "ffae0000.i2s"
#define ACODEC_DEVICE "ff480000.acodec"
#define ASOC_DEVICE "acodec-sound"
int SAMPLE_COMM_AOV_BindSoundcard() {
int ret = 0;
int fd = -1;
char buf[MAX_NL_BUF_SIZE] = {'\0'};
fd_set read_set;
struct timeval timeout;
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
addr.nl_pid = 0;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (fd < 0) {
printf("[%s()] Failed to open netlink because %s\n", __func__, strerror(errno));
return RK_FAILURE;
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
printf("[%s()] bind netlink addr failed because %s\n", __func__, strerror(errno));
goto __FAILED;
}
memset(&buf, 0, sizeof(buf));
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
timeout.tv_sec = 0;
timeout.tv_usec = MAX_SELECT_TIMEOUT;
SAMPLE_COMM_ECHO(I2S_DRIVER "bind", I2S_DEVICE, (sizeof(I2S_DEVICE)));
SAMPLE_COMM_ECHO(ACODEC_DRIVER "bind", ACODEC_DEVICE, (sizeof(ACODEC_DEVICE)));
SAMPLE_COMM_ECHO(ASOC_DRIVER "bind", ASOC_DEVICE, (sizeof(ASOC_DEVICE)));
__RETRY:
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
if (ret > 0) {
memset(&buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf));
buf[MAX_NL_BUF_SIZE - 1] = '\0';
// printf("[%s()] msg: %s\n", __func__, buf);
if (strncmp(buf, SOUND_BIND_DONE, strlen(SOUND_BIND_DONE)) == 0) {
printf("[%s()] Bind success: %s\n", __func__, buf);
goto __SUCCESS;
}
goto __RETRY; // drop all message
} else {
printf("[%s()] select error %s\n", __func__, strerror(errno));
goto __FAILED;
}
__SUCCESS:
close(fd);
return RK_SUCCESS;
__FAILED:
close(fd);
return RK_FAILURE;
}
int SAMPLE_COMM_AOV_UnbindSoundcard() {
int ret = 0;
int fd = -1;
char buf[MAX_NL_BUF_SIZE] = {'\0'};
fd_set read_set;
struct timeval timeout;
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
addr.nl_pid = 0;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (fd < 0) {
printf("[%s()] Failed to open netlink because %s\n", __func__, strerror(errno));
return RK_FAILURE;
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
printf("[%s()] bind netlink addr failed because %s\n", __func__, strerror(errno));
goto __FAILED;
}
memset(&buf, 0, sizeof(buf));
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
timeout.tv_sec = 0;
timeout.tv_usec = MAX_SELECT_TIMEOUT;
SAMPLE_COMM_ECHO(ASOC_DRIVER "unbind", ASOC_DEVICE, (sizeof(ASOC_DEVICE)));
SAMPLE_COMM_ECHO(ACODEC_DRIVER "unbind", ACODEC_DEVICE, (sizeof(ACODEC_DEVICE)));
SAMPLE_COMM_ECHO(I2S_DRIVER "unbind", I2S_DEVICE, (sizeof(I2S_DEVICE)));
__RETRY:
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
if (ret > 0) {
memset(&buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf));
buf[MAX_NL_BUF_SIZE - 1] = '\0';
// printf("[%s()] msg: %s\n", __func__, buf);
if (strncmp(buf, SOUND_UNBIND_DONE, strlen(SOUND_UNBIND_DONE)) == 0) {
printf("[%s()] Unbind success: %s\n", __func__, buf);
goto __SUCCESS;
}
goto __RETRY; // drop all message
} else {
printf("[%s()] select error %s\n", __func__, strerror(errno));
goto __FAILED;
}
__SUCCESS:
close(fd);
return RK_SUCCESS;
__FAILED:
close(fd);
return RK_FAILURE;
}