修改:信号包独立发包,周期100ms;

布局切换按键,增加开机读取电平状态
This commit is contained in:
xu
2026-09-16 17:00:58 +08:00
parent 3b1e7a7082
commit 8dd17a5b9a
9 changed files with 159 additions and 104 deletions
Binary file not shown.
+13 -7
View File
@@ -22,9 +22,9 @@
#include "confile.h" #include "confile.h"
#include "Util.h" #include "Util.h"
#define KEY_EVENT_DEV0_NAME "/dev/input/event1"
#define KEY_EVENT_DEV0_NAME "/dev/input/event0"
//#define KEY_EVENT_DEV0_NAME "/dev/input/event2" //#define KEY_EVENT_DEV0_NAME "/dev/input/event2"
#define DEFAULT_MD_LEN 4096 #define DEFAULT_MD_LEN 4096
int switch_video; int switch_video;
@@ -123,12 +123,18 @@ int main(int argc, char **argv)
int flag_down=0; int flag_down=0;
key_fd = open(KEY_EVENT_DEV0_NAME, O_RDONLY); key_fd = open(KEY_EVENT_DEV0_NAME, O_RDONLY);
if(key_fd <= 0) // if(key_fd <= 0)
// {
// printf("---open /dev/input/event2 device error!---\n");
// return ret;
// }
if(key_fd < 0)
{ {
printf("---open /dev/input/event0 device error!---\n"); perror("open " KEY_EVENT_DEV0_NAME); // 这一行能直接告诉你 errno
return ret; return -1; // 原来 return ret; ret 未初始化,是未定义行为
} }
light_mode = switch_memory_open(); light_mode = switch_memory_open();
get_parameter(&param); get_parameter(&param);
//printf("---\n"); //printf("---\n");
@@ -161,7 +167,7 @@ int main(int argc, char **argv)
}else if(key_event.type == EV_KEY && key_event.value == 0){ }else if(key_event.type == EV_KEY && key_event.value == 0){
if(flag_down == 1){ //短按 if(flag_down == 1){ //短按
if((key_event.code == 0x67) && (count_down < 25)) if((key_event.code == 0x66) && (count_down < 25))
{ {
//key_value = 0x01; //light down //key_value = 0x01; //light down
count=count+400; count=count+400;
@@ -170,7 +176,7 @@ int main(int argc, char **argv)
} }
}else if((key_event.code == 0x66) && (count_down < 25)){ }else if((key_event.code == 0x67) && (count_down < 25)){
count=count-400; count=count-400;
if(count <= 0){ if(count <= 0){
+51 -7
View File
@@ -19,12 +19,17 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <sys/ioctl.h>
#include "confile.h" #include "confile.h"
#include "Util.h" #include "Util.h"
#define KEY_EVENT_DEV1_NAME "/dev/input/event1" #define KEY_EVENT_DEV1_NAME "/dev/input/event1"
#define KEY_EVENT_DEV0_NAME "/dev/input/event0" #define KEY_EVENT_DEV0_NAME "/dev/input/event0"
#define KEY_CODE_LAYOUT 0x68 /* 布局开关按键 */
#define SHM_LAYOUT_NAME "/video_switch" /* [1] = 布局开关状态,ctrl_pnl 上报面板 byte27 */
#define DEFAULT_MD_LEN 4096 #define DEFAULT_MD_LEN 4096
int switch_video; int switch_video;
unsigned char key_value; unsigned char key_value;
@@ -79,17 +84,26 @@ void* pkts_worker(void *arg)
} }
} }
#endif #endif
int *switch_memory_open(void) { // int *switch_memory_open(void) {
char buf[128]; // char buf[128];
int fd; // int fd;
sprintf(buf, "/switch_mode"); // sprintf(buf, "/switch_mode");
fd = shm_open(buf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); // fd = shm_open(buf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
// if(fd < 0) { perror("shm_open"); exit(1); }
// if (ftruncate(fd, 4096) == -1) { perror("ftruncate"); exit(1); }
// int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// return retval;
// }
int *switch_memory_open(const char *name) {
int fd = shm_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if(fd < 0) { perror("shm_open"); exit(1); } if(fd < 0) { perror("shm_open"); exit(1); }
if (ftruncate(fd, 4096) == -1) { perror("ftruncate"); exit(1); } if (ftruncate(fd, 4096) == -1) { perror("ftruncate"); exit(1); }
int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
return retval; return retval;
} }
int get_parameter(struct decoce_param *pparam) int get_parameter(struct decoce_param *pparam)
{ {
if(confile_init()) { if(confile_init()) {
@@ -102,6 +116,21 @@ int get_parameter(struct decoce_param *pparam)
return 0; return 0;
} }
/* 开机时按键可能已经按住,输入层不会上报"电平没变"的事件,只能主动查一次 */
static int key_is_down(int fd, unsigned int code)
{
unsigned long keybits[(KEY_MAX / 8 / sizeof(unsigned long)) + 1];
memset(keybits, 0, sizeof(keybits));
if(ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits) < 0)
{
printf("---EVIOCGKEY error!---\n");
return 0;
}
return (keybits[code / (8 * sizeof(unsigned long))] >>
(code % (8 * sizeof(unsigned long)))) & 1UL;
}
int main(int argc, char **argv) int main(int argc, char **argv)
@@ -112,7 +141,7 @@ int main(int argc, char **argv)
struct input_event key_event = {0}; struct input_event key_event = {0};
int ret; int ret;
int port; int port;
int *light_mode; int *video_mode;
int len; int len;
pthread_attr_t attr; pthread_attr_t attr;
@@ -121,7 +150,7 @@ int main(int argc, char **argv)
int count_down=0; int count_down=0;
int flag_down=0; int flag_down=0;
key_fd = open(KEY_EVENT_DEV0_NAME, O_RDONLY); key_fd = open(KEY_EVENT_DEV1_NAME, O_RDONLY);
if(key_fd <= 0) if(key_fd <= 0)
{ {
printf("---open %s device error!---\n",KEY_EVENT_DEV1_NAME); printf("---open %s device error!---\n",KEY_EVENT_DEV1_NAME);
@@ -129,6 +158,11 @@ int main(int argc, char **argv)
} }
//light_mode = switch_memory_open(); //light_mode = switch_memory_open();
video_mode = switch_memory_open(SHM_LAYOUT_NAME);
video_mode[1] = key_is_down(key_fd, KEY_CODE_LAYOUT);
get_parameter(&param); get_parameter(&param);
//printf("---\n"); //printf("---\n");
//switch_mode[0] = 0x01; //switch_mode[0] = 0x01;
@@ -149,6 +183,13 @@ int main(int argc, char **argv)
{ {
//printf("key_event.type %d EV_KEY %d \n",key_event.type,EV_KEY); //printf("key_event.type %d EV_KEY %d \n",key_event.type,EV_KEY);
//printf("key_event.value %d key_event.code %d count_down %d\n",key_event.value, key_event.code,count_down); //printf("key_event.value %d key_event.code %d count_down %d\n",key_event.value, key_event.code,count_down);
/* 布局开关:直接跟按键电平,按下=1 松开=0,不做翻转、不留状态 */
if(key_event.type == EV_KEY && key_event.code == KEY_CODE_LAYOUT){
video_mode[1] = key_event.value ? 1 : 0;
}
if(key_event.type == EV_KEY && key_event.value == 1 ) if(key_event.type == EV_KEY && key_event.value == 1 )
{ {
flag_down=1; flag_down=1;
@@ -186,7 +227,10 @@ int main(int argc, char **argv)
sprintf(buf,"./pwm.sh %d",count); sprintf(buf,"./pwm.sh %d",count);
system(buf); system(buf);
printf("----%s \n",buf); printf("----%s \n",buf);
} }
#if 0 #if 0
if((count_down > 50) && (key_event.code == 0x67)){ if((count_down > 50) && (key_event.code == 0x67)){
printf("long\n"); printf("long\n");
+2 -2
View File
@@ -99,7 +99,7 @@ int main(int argc, char **argv)
else if(switch_video == 2 && switch_video_pre==2) /* 右屏通道1全屏 */ else if(switch_video == 2 && switch_video_pre==2) /* 右屏通道1全屏 */
{ if(switch_mode[3] == 0x55){ { if(switch_mode[3] == 0x55){
printf("+++++++++++++++++++++++++22 time out\n"); printf("+++++++++++++++++++++++++22 time out\n");
sprintf(buf_kill_rtsp,"./kill_rtsp.sh %d",2); sprintf(buf_kill_rtsp,"./kill_rtsp.sh %d",3);
system(buf_kill_rtsp); system(buf_kill_rtsp);
sprintf(buf,"./start_rtsp.sh %d",3); sprintf(buf,"./start_rtsp.sh %d",3);
system(buf); system(buf);
@@ -118,7 +118,7 @@ int main(int argc, char **argv)
else if(switch_video == 4 && switch_video_pre==4) /* 右放大左隐藏 */ else if(switch_video == 4 && switch_video_pre==4) /* 右放大左隐藏 */
{ if(switch_mode[3] == 0x55){ { if(switch_mode[3] == 0x55){
printf("+++++++++++++++++++++++++44 time out\n"); printf("+++++++++++++++++++++++++44 time out\n");
sprintf(buf_kill_rtsp,"./kill_rtsp.sh %d",2); sprintf(buf_kill_rtsp,"./kill_rtsp.sh %d",3);
system(buf_kill_rtsp); system(buf_kill_rtsp);
sprintf(buf,"./start_rtsp.sh %d",5); sprintf(buf,"./start_rtsp.sh %d",5);
system(buf); system(buf);
+66 -63
View File
@@ -13,6 +13,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <errno.h> #include <errno.h>
#include <time.h> /* 新增:clock_gettime / clock_nanosleep */
#include <pthread.h> #include <pthread.h>
#include "serial.h" #include "serial.h"
#include "uartinf.h" #include "uartinf.h"
@@ -49,6 +50,7 @@
static int *shm_msg = NULL; static int *shm_msg = NULL;
static int *buffer_param = NULL; /* 新增:/param.txt 共享内存,供信号线程读 RSSI */
char _rx_data[200]; char _rx_data[200];
@@ -88,29 +90,6 @@ static int *switch_memory_open(void) {
return retval; return retval;
} }
/* 读 GPIO71(0/1),失败返回默认值 1 */
static int read_gpio72(void)
{
char val = 0;
int fd = open("/sys/class/gpio/gpio71/value", O_RDONLY);
if (fd < 0)
return 0; /* 失败默认 0 */
if (read(fd, &val, 1) != 1) {
close(fd);
return 0; /* 失败默认 0 */
}
close(fd);
return (val == '0') ? 1 : 0; /* 反相:GPIO=1 → 0,GPIO=0 → 1 */
}
static long elapsed_ms(struct timeval *start, struct timeval *end)
{
return (end->tv_sec - start->tv_sec) * 1000L
+ (end->tv_usec - start->tv_usec) / 1000L;
}
int init_net_recv(int port){ int init_net_recv(int port){
@@ -274,40 +253,90 @@ void *net_recv(void *arg)
#endif #endif
/* 独立信号包线程:与串口收包完全解耦,固定 SIGNAL_INTERVAL_MS 周期发送。
* 用绝对时间 clock_nanosleep 对齐发送时刻,避免 sendto/printf 开销累积成漂移。 */
void *signal_send(void *arg)
{
char sig_frame[NET_FRAME_LEN];
struct timespec next;
int k, sum;
clock_gettime(CLOCK_MONOTONIC, &next);
while (1) {
memset(sig_frame, 0, NET_FRAME_LEN);
sig_frame[0] = (char)FRAME_HEAD; /* byte0 = 0x11 */
/* byte25/26 = 视频流0/1无信号,byte27 = 布局开关(light_pwm_lvds 的 0x68 按键) */
sig_frame[BYTE_NOSIG0] = (shm_msg && shm_msg[2] == 0x55) ? 1 : 0;
sig_frame[BYTE_NOSIG1] = (shm_msg && shm_msg[3] == 0x55) ? 1 : 0;
sig_frame[27] = (shm_msg && shm_msg[1]) ? 1 : 0;
printf("layout byte27 = %d\n", sig_frame[27]);
if (buffer_param) {
sig_frame[BYTE_RSSI1] = (char)buffer_param[1];
sig_frame[BYTE_RSSI2] = (char)buffer_param[2];
}
sig_frame[PAYLOAD_LEN] = (char)FRAME_TAIL; /* byte30 = 0x22 */
sum = 0;
for (k = 0; k <= CHECKSUM_END; k++)
sum += (unsigned char)sig_frame[k];
sig_frame[CHECKSUM_END + 1] = (char)(sum & 0xFF);
sendto(socket_descriptor, sig_frame, NET_FRAME_LEN, 0,
(struct sockaddr *)&address, sizeof(address));
/* 下一个发送时刻 = 本次时刻 + 周期,与实际执行耗时无关 */
next.tv_nsec += (long)SIGNAL_INTERVAL_MS * 1000000L;
while (next.tv_nsec >= 1000000000L) {
next.tv_sec++;
next.tv_nsec -= 1000000000L;
}
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
}
return NULL;
}
int pthread_init() int pthread_init()
{ {
int ret; int ret;
pthread_t sig_thread;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
ret = pthread_create(&pkts_thread, &attr, net_recv, NULL); ret = pthread_create(&pkts_thread, &attr, net_recv, NULL);
pthread_attr_destroy(&attr);
if(ret){ if(ret){
printf("create pthread1 error\n"); printf("create pthread1 error\n");
pthread_attr_destroy(&attr);
return 1; return 1;
} }
ret = pthread_create(&sig_thread, &attr, signal_send, NULL);
if(ret){
printf("create pthread2 error\n");
pthread_attr_destroy(&attr);
return 1;
}
pthread_attr_destroy(&attr);
return 0;
} }
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
int n_read; int n_read;
int i; int i;
int count=0; int count=0;
int *buffer_param;
char buffer_send[100]; char buffer_send[100];
int buffer_len; int buffer_len;
struct timeval tv_sig = {0, 0}, tv_now;
char sig_frame[NET_FRAME_LEN];
n_read = uart_init(ROUTE_UART, "/dev/ttyAMA4", 115200, 'N'); n_read = uart_init(ROUTE_UART, "/dev/ttyAMA4", 115200, 'N');
if(n_read <=0 ) { if(n_read <=0 ) {
printf("open /dev/ttyAMA4 failed\n"); printf("open /dev/ttyAMA4 failed\n");
@@ -325,7 +354,11 @@ int main (int argc, char *argv[])
shm_msg = switch_memory_open(); shm_msg = switch_memory_open();
buffer_param = param_memory_open(); buffer_param = param_memory_open();
pthread_init(); if (pthread_init()) {
printf("pthread_init failed\n");
return -1;
}
while(1){ while(1){
@@ -366,36 +399,6 @@ int main (int argc, char *argv[])
sendto(socket_descriptor, _rx_data, NET_FRAME_LEN, 0, (struct sockaddr *)&address, sizeof(address)); sendto(socket_descriptor, _rx_data, NET_FRAME_LEN, 0, (struct sockaddr *)&address, sizeof(address));
} }
/* 独立信号包:与串口数据无关,每 SIGNAL_INTERVAL_MS 发一次;其余字节填 0 */
gettimeofday(&tv_now, NULL);
if (tv_sig.tv_sec == 0 || elapsed_ms(&tv_sig, &tv_now) >= SIGNAL_INTERVAL_MS) {
int k, sum = 0;
memset(sig_frame, 0, NET_FRAME_LEN);
sig_frame[0] = (char)FRAME_HEAD; /* byte0 = 0x11 */
/* byte25/26 = 视频流0/1无信号,byte27 = GPIO */
sig_frame[BYTE_NOSIG0] = (shm_msg && shm_msg[2] == 0x55) ? 1 : 0;
sig_frame[BYTE_NOSIG1] = (shm_msg && shm_msg[3] == 0x55) ? 1 : 0;
sig_frame[27] = (char)read_gpio72();
if (buffer_param) {
sig_frame[BYTE_RSSI1] = (char)buffer_param[1];
sig_frame[BYTE_RSSI2] = (char)buffer_param[2];
//打印发出的信号值
printf("signal: RSSI1=%d RSSI2=%d\n", buffer_param[1], buffer_param[2]);
}
sig_frame[PAYLOAD_LEN] = (char)FRAME_TAIL; /* byte30 = 0x22 */
for (k = 0; k <= CHECKSUM_END; k++)
sum += (unsigned char)sig_frame[k];
sig_frame[CHECKSUM_END + 1] = (char)(sum & 0xFF);
sendto(socket_descriptor, sig_frame, NET_FRAME_LEN, 0, (struct sockaddr *)&address, sizeof(address));
tv_sig = tv_now;
}
} }
} }
Binary file not shown.
+8 -6
View File
@@ -48,7 +48,7 @@
#define REF_NUM 2 #define REF_NUM 2
#define DISPLAY_NUM 2 #define DISPLAY_NUM 2
#if 1 #if 0
#define NOSIGNAL_YUV_PATH "./nosignal.yuv" #define NOSIGNAL_YUV_PATH "./nosignal.yuv"
@@ -333,6 +333,8 @@ static td_s32 sample_start_vpss(ot_vpss_grp *vpss_grp, td_u32 vpss_grp_num, td_b
vpss_chn_attr[1].depth = 0; vpss_chn_attr[1].depth = 0;
vpss_chn_attr[1].mirror_en = TD_FALSE; //TD_TRUE; //180 vpss_chn_attr[1].mirror_en = TD_FALSE; //TD_TRUE; //180
vpss_chn_attr[1].flip_en = TD_FALSE; //TD_TRUE; //180 vpss_chn_attr[1].flip_en = TD_FALSE; //TD_TRUE; //180
// vpss_chn_attr[1].mirror_en = TD_TRUE; //TD_TRUE; //180
// vpss_chn_attr[1].flip_en = TD_TRUE; //TD_TRUE; //180
vpss_chn_attr[1].border_en = TD_FALSE; vpss_chn_attr[1].border_en = TD_FALSE;
vpss_chn_attr[1].aspect_ratio.mode = OT_ASPECT_RATIO_NONE; vpss_chn_attr[1].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
} }
@@ -565,7 +567,7 @@ static td_s32 sample_start_vdec(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_n
return ret; return ret;
} }
#if 0
/* ==================== no-signal 占位图 ==================== */ /* ==================== no-signal 占位图 ==================== */
/* 启动时调用:读源图 nosignal.yuv(1920x1200) 到 VB,填成 user pic frame_info */ /* 启动时调用:读源图 nosignal.yuv(1920x1200) 到 VB,填成 user pic frame_info */
@@ -681,7 +683,7 @@ td_s32 vdec_set_nosignal_userpic(ot_vdec_chn chn)
return ret; return ret;
} }
#endif
void* h265_vdec_vpss_vo() void* h265_vdec_vpss_vo()
{ {
@@ -716,9 +718,9 @@ void* h265_vdec_vpss_vo()
} }
/* 新增:启动读源图并 set user pic(set 前必须先 disable) */ /* 新增:启动读源图并 set user pic(set 前必须先 disable) */
if (load_nosignal_src() != TD_SUCCESS) { // if (load_nosignal_src() != TD_SUCCESS) {
printf("[nosignal] load src fail, nosignal disabled\n"); // printf("[nosignal] load src fail, nosignal disabled\n");
} // }
/************************************************ /************************************************
+19 -19
View File
@@ -26,7 +26,7 @@
#include "sample_comm.h" #include "sample_comm.h"
extern td_s32 vdec_set_nosignal_userpic(ot_vdec_chn chn); // extern td_s32 vdec_set_nosignal_userpic(ot_vdec_chn chn);
@@ -223,7 +223,7 @@ void *net_recv1(void *arg)
int len = sizeof(clientAddr); int len = sizeof(clientAddr);
unsigned char buf[2048]; unsigned char buf[2048];
static int count_time_out=0; static int count_time_out=0;
static int nosignal_on = 0; //nosignal satuts // static int nosignal_on = 0; //nosignal satuts
ot_vdec_stream stream; ot_vdec_stream stream;
int ret; int ret;
@@ -231,16 +231,16 @@ void *net_recv1(void *arg)
i = recvfrom(socket_descriptor[0],buf, 1472, 0, (struct sockaddr*)&clientAddr, &len); i = recvfrom(socket_descriptor[0],buf, 1472, 0, (struct sockaddr*)&clientAddr, &len);
if(i>0){ if(i>0){
switch_video[2] = 0xAA; switch_video[2] = 0xAA;
if (nosignal_on == 1) { // if (nosignal_on == 1) {
ret = ss_mpi_vdec_disable_user_pic(0); // ret = ss_mpi_vdec_disable_user_pic(0);
printf("[nosignal] disable_user_pic ret=%#x\n", ret); // printf("[nosignal] disable_user_pic ret=%#x\n", ret);
ret = ss_mpi_vdec_start_recv_stream(0); // ret = ss_mpi_vdec_start_recv_stream(0);
printf("[nosignal] start_recv_stream ret=%#x\n", ret); // printf("[nosignal] start_recv_stream ret=%#x\n", ret);
nosignal_on = 0; // nosignal_on = 0;
printf("[nosignal] -> back to normal decode\n"); // printf("[nosignal] -> back to normal decode\n");
} // }
#if 0 #if 0
stream.pts = 0; stream.pts = 0;
stream.addr = buf; stream.addr = buf;
stream.len = i; stream.len = i;
@@ -252,17 +252,17 @@ void *net_recv1(void *arg)
ret = ss_mpi_vdec_send_stream(0, &stream, 0); ret = ss_mpi_vdec_send_stream(0, &stream, 0);
// usleep(1000); // usleep(1000);
} while (ret != TD_SUCCESS); } while (ret != TD_SUCCESS);
#endif #endif
assemble_nal1(buf,i); assemble_nal1(buf,i);
} }
if(i<=0){ if(i<=0){
if (nosignal_on == 0) { // if (nosignal_on == 0) {
ss_mpi_vdec_stop_recv_stream(0); // ss_mpi_vdec_stop_recv_stream(0);
ss_mpi_vdec_disable_user_pic(0); /* 文档:set 前先 disable */ // ss_mpi_vdec_disable_user_pic(0); /* 文档:set 前先 disable */
vdec_set_nosignal_userpic(0); /* 通道已停,此时 set 才合法 */ // vdec_set_nosignal_userpic(0); /* 通道已停,此时 set 才合法 */
ss_mpi_vdec_enable_user_pic(0, 1); /* 立即显示占位图 */ // ss_mpi_vdec_enable_user_pic(0, 1); /* 立即显示占位图 */
nosignal_on = 1; // nosignal_on = 1;
} // }
switch_video[2] = 0x55; switch_video[2] = 0x55;
printf("net1 recv timeout %d\n",i); printf("net1 recv timeout %d\n",i);
} }
Binary file not shown.