UBoot里初始化it66021

This commit is contained in:
xu
2026-09-23 10:57:43 +08:00
parent 8dd17a5b9a
commit 988251e5aa
8 changed files with 932 additions and 32 deletions
+404
View File
@@ -0,0 +1,404 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h> // gettimeofday
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <time.h> /* 新增:clock_gettime / clock_nanosleep */
#include <pthread.h>
#include "serial.h"
#include "uartinf.h"
#include <stdbool.h>
#define RECV_PORT 12000 // UDP接收端口
#define SEND_PORT 12001 // 发送端口(UART转NET)
/* ===================== 网络帧协议定义 ===================== */
#define NET_FRAME_LEN 32 /* 收/发报文固定长度 */
#define NET_TAIL 0xBB /* 帧尾 */
#define PAYLOAD_LEN 30 /* 帧长度 byte0..29 */
#define BYTE_MODE 30 /* 接收帧 mode 字段偏移(0-4) */
#define BYTE_TAIL 31 /* 接收帧帧尾偏移 */
#define CHECKSUM_END 30 /* 校验和覆盖 byte0..byte30(含) */
#define NET_FRAME_MAX_LEN 256 /* recvfrom 缓冲大小 */
#define BYTE_NOSIG0 25 /* byte25 = 视频流0无信号标志(1=无信号,0=有信号) */
#define BYTE_NOSIG1 26 /* byte26 = 视频流1无信号标志(1=无信号,0=有信号) */
#define BYTE_RSSI1 28 /* 信号包=RSSI1;设备包=哨兵 */
#define BYTE_RSSI2 29 /* 信号包=RSSI2;设备包=哨兵 */
#define SIG_MARK 0x5A /* 设备包 byte28/29 哨兵值 */
#define SIGNAL_INTERVAL_MS 100 /* 独立信号包发送间隔(ms) */
#define FRAME_HEAD 0x11 /* 上行帧帧头(byte0),面板校验要求 */
#define FRAME_TAIL 0x22 /* 上行帧帧尾(byte30),面板校验要求 */
#define FRAME_HEAD_TX 0xAA /* 下行帧帧头(byte0),设备→面板 */
/* ===================== 共享内存 ===================== */
#define SHM_MSG_NAME "/video_switch"
#define SHM_MODE_IDX 0 /* switch_mode -> shm[0](即 switch_video[0]) */
static int *shm_msg = NULL;
static int *buffer_param = NULL; /* 新增:/param.txt 共享内存,供信号线程读 RSSI */
char _rx_data[200];
static int socket_descriptor;
static struct sockaddr_in address;
bool first = false;
int socket_descriptor_recv;
struct sockaddr_in address_recv;
pthread_attr_t attr;
pthread_t pkts_thread;
/* 打开共享内存 /param.txt(由 lc6600_uart 进程写入 RSSI) */
static int *param_memory_open(void) {
int fd = shm_open("/param.txt", O_RDWR, 0777);
if (fd < 0) {
fd = shm_open("/param.txt", O_RDWR | O_CREAT, 0777);
if (fd < 0) { perror("shm_open /param.txt"); return NULL; }
if (ftruncate(fd, 4096) == -1) { perror("ftruncate /param.txt"); return NULL; }
}
int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (retval == MAP_FAILED) { perror("mmap /param.txt"); return NULL; }
return retval;
}
static int *switch_memory_open(void) {
char buf[128];
int fd;
sprintf(buf, SHM_MSG_NAME);
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 init_net_recv(int port){
int i;
struct timeval tv;
bzero(&address_recv,sizeof(struct sockaddr_in));
address_recv.sin_family=AF_INET;
address_recv.sin_addr.s_addr=htonl(INADDR_ANY);
address_recv.sin_port=htons(port);
socket_descriptor_recv=socket(AF_INET,SOCK_DGRAM,0);//IPV4
tv.tv_sec = 2;
tv.tv_usec = 0;
if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
printf("socket option SO_RCVTIMEO not support\n");
return -1;
}
if (bind(socket_descriptor_recv, (struct sockaddr *)&address_recv, sizeof(struct sockaddr_in)) < 0)
{
perror("bind");
exit(1);
}
return 0;
}
int udp_init(char *ip, int port){
bzero(&address,sizeof(address));
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr(ip);
address.sin_port=htons(port);
socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4
return 0;
}
#if 0
void *net_recv(void *arg)
{
int i;
struct sockaddr_in clientAddr;
int len = sizeof(clientAddr);
int ret;
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
printf("socket option SO_RCVTIMEO not support\n");
//return -1;
}
char buffer_cmd[200];
while(1){
i = recvfrom(socket_descriptor_recv, buffer_cmd, 200, 0, (struct sockaddr*)&clientAddr, &len);
if(i>0){
uart_write_len(ROUTE_UART,buffer_cmd,i);
}
else{
printf(" time_out to receive data\n");
}
}
}
#endif
#if 1
void *net_recv(void *arg)
{
int i, k;
struct sockaddr_in clientAddr;
socklen_t len;
struct timeval tv;
char buffer_cmd[NET_FRAME_MAX_LEN];
char frame_out[NET_FRAME_MAX_LEN];
int sum;
unsigned char checksum;
tv.tv_sec = 5;
tv.tv_usec = 0;
if (setsockopt(socket_descriptor_recv, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
printf("socket option SO_RCVTIMEO not support\n");
while (1) {
len = sizeof(clientAddr); /* 每次循环重置,recvfrom 会改写 len */
i = recvfrom(socket_descriptor_recv, buffer_cmd, NET_FRAME_MAX_LEN, 0,
(struct sockaddr*)&clientAddr, &len);
if (i <= 0) {
printf(" time_out to receive data\n");
continue;
}
if (i != NET_FRAME_LEN) {
printf("bad frame len=%d\n", i);
continue;
}
/* 帧尾校验 */
if ((unsigned char)buffer_cmd[BYTE_TAIL] != NET_TAIL) {
printf("bad tail=%02x\n", (unsigned char)buffer_cmd[BYTE_TAIL]);
continue;
}
/* 解析 mode -> 写共享内存 */
if (shm_msg) {
static int last_mode = -1;
int mode = (unsigned char)buffer_cmd[BYTE_MODE];
if (mode <= 4) {
if (mode != last_mode) {
shm_msg[SHM_MODE_IDX] = mode; //写入共享内存 viode_switch
last_mode = mode;
printf("write shm: mode=%d\n", mode);
}
}
else {
printf("filed mode=%d\n", mode);
}
}
/* 构造下行帧:byte0=0xAA 帧头,byte1..29 原样,byte30=0xBB 帧尾 */
frame_out[0] = FRAME_HEAD_TX; /* [0] 帧头 0xAA */
memcpy(frame_out + 1, buffer_cmd + 1, PAYLOAD_LEN - 1); /* [1..29] 原样 */
frame_out[PAYLOAD_LEN] = NET_TAIL; /* [30] 帧尾 0xBB */
/* 校验和 = byte0..byte30 求和取低8位,写入 byte31 */
sum = 0;
for (k = 0; k <= CHECKSUM_END; k++)
sum += (unsigned char)frame_out[k];
checksum = sum & 0xFF;
frame_out[PAYLOAD_LEN + 1] = checksum; /* [31] 校验和 */
#if 0
/* 打印发出的包 */
printf(" send to uart %d bytes:", NET_FRAME_LEN);
for (k = 0; k < NET_FRAME_LEN; k++)
printf(" %02x", (unsigned char)frame_out[k]);
printf("\n");
#endif
uart_write_len(ROUTE_UART, frame_out, NET_FRAME_LEN); //发送给串口
}
return NULL;
}
#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 ret;
pthread_t sig_thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
ret = pthread_create(&pkts_thread, &attr, net_recv, NULL);
if(ret){
printf("create pthread1 error\n");
pthread_attr_destroy(&attr);
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 n_read;
int i;
int count=0;
char buffer_send[100];
int buffer_len;
n_read = uart_init(ROUTE_UART, "/dev/ttyAMA4", 115200, 'N');
if(n_read <=0 ) {
printf("open /dev/ttyAMA4 failed\n");
return -1;
}
// udp_init(argv[1], atoi(argv[2]));
// init_net_recv(atoi(argv[3]));
udp_init("127.0.0.1", SEND_PORT); // 发送目标:本机回环 12001
init_net_recv(RECV_PORT); // 接收:0.0.0.0:12000(INADDR_ANY)
shm_msg = switch_memory_open();
buffer_param = param_memory_open();
if (pthread_init()) {
printf("pthread_init failed\n");
return -1;
}
while(1){
n_read = uart_read(ROUTE_UART, _rx_data);
if(n_read > 0 ){
int k, sum = 0;
/* 收包校验:完整 32 字节帧,帧头 0x11、帧尾 0x22、byte31 校验和正确,否则丢弃 */
if (n_read < NET_FRAME_LEN) {
printf("drop bad frame: len=%d\n", n_read);
continue;
}
if ((unsigned char)_rx_data[0] != FRAME_HEAD ||
(unsigned char)_rx_data[CHECKSUM_END] != FRAME_TAIL) {
printf("drop bad frame: head=%02x tail=%02x\n",
(unsigned char)_rx_data[0], (unsigned char)_rx_data[CHECKSUM_END]);
continue;
}
for (k = 0; k <= CHECKSUM_END; k++)
sum += (unsigned char)_rx_data[k];
if ((unsigned char)_rx_data[31] != (sum & 0xFF)) {
printf("drop bad frame: checksum=%02x expect=%02x\n",
(unsigned char)_rx_data[31], (unsigned char)(sum & 0xFF));
continue;
}
/* byte28/29 固定哨兵值,RSSI 改由独立信号包承载 */
_rx_data[BYTE_RSSI1] = (char)SIG_MARK;
_rx_data[BYTE_RSSI2] = (char)SIG_MARK;
/* 和校验:byte0..byte30 求和取低 8 位,写入 byte31 */
sum = 0;
for (k = 0; k <= CHECKSUM_END; k++)
sum += (unsigned char)_rx_data[k];
_rx_data[31] = (char)(sum & 0xFF);
sendto(socket_descriptor, _rx_data, NET_FRAME_LEN, 0, (struct sockaddr *)&address, sizeof(address));
}
}
}