TT12-MCU/applications/ttTR/ttTR.c
CSSC-WORK\murmur 98a895fb3e 更新485定时逻辑,不采用mutex
添加默认rtc闹钟,用于更新debug日志文件名
func.c 去掉重复校验逻辑
func.h 添加部分宏定义注释
getinfo.c 修复TT关机后未复位状态信息的bug
log2file.c 添加更新debug日志文件名的功能
ttTR.c 增加msg_pool及TTRx_MSG的大小
增加ULOG_ASYNC_OUTPUT_BUF_SIZE大小
2023-09-08 16:38:30 +08:00

334 lines
7.5 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 (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-05-30 murmur the first version
*/
#include <rtthread.h>
#include <sys/socket.h> /* 使用BSD socket需要包含socket.h头文件 */
#include <netdb.h>
#include <string.h>
#define LOG_TAG "ttTR"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
#include <usrcfg.h>
#include "ttTR.h"
#define BUFSZ 2000
#define RETRYCNT 10
#define URL TTIP
#define PORT 8005
static int sock=0;
volatile int flag=0;
void tcpClose(void)
{
/* 关闭这个连接 */
if (sock) {
closesocket(sock);
}
flag=0;
}
int isTCPok(void)
{
// return sock;
return flag;
}
int tcpInit(void)
{
int ret;
const char *url = URL;
int port = PORT;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
struct hostent *host;
host = gethostbyname(url);
/* 创建一个socket类型是SOCKET_STREAMTCP类型 */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 创建socket失败 */
LOG_E("Socket error");
return RT_ERROR;
}
/* 初始化预连接的服务端地址 */
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *) host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 连接到服务端 */
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
/* 连接失败 */
LOG_E("Connect to TT fail!");
tcpClose();
return RT_ERROR;
}
else
{
// tcpRecMQ();
flag=1;
return RT_EOK;
}
}
static int tcpSend(const rt_uint8_t *send_data, size_t len)
{
// LOG_HEX("send",27,send_data,len);
/* 发送数据到sock连接 */
int ret = send(sock, send_data, len, 0);
if (ret == len)
{
// LOG_D("send %d Bytes ok.",len);
ret = RT_EOK;
}
else
{
LOG_E("Send error, send function return %d", ret);
ret = RT_ERROR;
}
return ret;
}
/**
* 接收TCP数据
* @param recv_data 接收数据缓存最小200字节
* @return 接收到的数据长度,-1表示发生了错误。
*/
int tcpRec(unsigned char *recv_data)
{
int ret=RT_ERROR;
/* 从sock连接中接收最大BUFSZ字节数据 */
int bytes_received = recv(sock, recv_data, BUFSZ, 0);
if (bytes_received) {
return bytes_received;
}
else {
LOG_E("received error.");
return -RT_ERROR;
}
}
struct rt_messagequeue TTrx_mq;
void init_mq(void)
{
static char msg_pool[1024*2];
/* 初始化消息队列 */
int result = rt_mq_init(&TTrx_mq, "TTrx_mq",
msg_pool, /* 存放消息的缓冲区 */
sizeof(TTRx_MSG), /* 一条消息的最大长度 */
sizeof(msg_pool), /* 存放消息的缓冲区大小 */
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
if (result != RT_EOK)
{
rt_kprintf("init message queue failed.\n");
return -1;
}
}
INIT_COMPONENT_EXPORT(init_mq);
/**
* 接收TCP数据通过消息队列发出通知
* @param recv_data 接收数据缓存最小200字节
* @return 接收到的数据长度,-1表示发生了错误。
*/
void tcpRecMQ_thread_entry(void)
{
static TTRx_MSG msg;
while (1)
{
if (!isTCPok()) {
break;
}
rt_memset(&msg, 0, sizeof(msg));
/* 从sock连接中接收最大BUFSZ字节数据 */
msg.size = recv(sock, msg.data, BUFSZ, 0);
// if (msg.size < 0)
// {
// /* 接收失败,关闭这个连接 */
// tcpClose();
// rt_kprintf("\nreceived error,close the socket.\r\n");
//
// /* 释放接收缓冲 */
// break;
// }
// LOG_D("%d Bytes received.",msg.size);
if (msg.size >0 )
{
// LOG_D("%d Bytes received.",msg.size);
// LOG_HEX("tcpTT", 16, msg.data, msg.size);
// resetTM();
int result = rt_mq_send(&TTrx_mq, &msg, sizeof(msg));
if (result == -RT_EFULL)
{
/* 消息队列满 */
LOG_W("message queue full.");
}
}
else
{
msg.size=0;//收到数据长度为0表示tcp断开
rt_mq_send(&TTrx_mq, &msg, sizeof(msg));
LOG_W("tcp closed.");
tcpClose();
break;
}
}
}
/**
* 创建接收线程。发生错误后自动退出。
*/
void tcpRecMQ(void)
{
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("tcpRecMQ", tcpRecMQ_thread_entry, RT_NULL, 1024*10, 25, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
LOG_E("thread 'tcpRecMQ' create failure.");
}
}
//INIT_COMPONENT_EXPORT(tcpRecMQ);
/**
* 发送数据时TT的ack信号
* @return
*/
static int tcpAck()
{
/* 分配用于存放接收数据的缓冲 */
char *recv_data;
recv_data = rt_malloc(BUFSZ);
if (recv_data == RT_NULL)
{
LOG_E("No memory.");
return RT_ENOMEM;
}
int ret=RT_ERROR;
size_t cnt = RETRYCNT;//尝试次数
while (cnt--)
{
/* 从sock连接中接收最大BUFSZ - 1字节数据 */
int bytes_received = recv(sock, recv_data, BUFSZ, 0);
if (bytes_received) {
LOG_HEX("rec data",16,recv_data,bytes_received);
//check response
rt_uint8_t rec_good[] = { 0x88, 0xAA, 0xBB, 0x88 };//前四字节
if (rt_memcmp(recv_data, rec_good, 4))
{
ret = RT_EOK;
/* 释放接收缓冲 */
rt_free(recv_data);
break;
}
}
else {
LOG_E("received error.");
/* 释放接收缓冲 */
rt_free(recv_data);
break;
}
rt_thread_delay(100);
}
return ret;
}
/**
* 发送一维数组
* @param msg 待发数据
* @param len 数组长度
* @return 成功返回0
*/
int sendMsg(const rt_uint8_t *msg, size_t len)
{
if (tcpSend(msg, len) != RT_EOK)
{
// tcpClose();
return RT_ERROR;
}
//#define CHK_ACK
#ifdef CHK_ACK
if (tcpAck() != RT_EOK)
{
return RT_ERROR;
// break;
};
#endif
// return RT_EOK;
//已发送数据存入log文件
char str[600];
bytes2str(msg, len, 16, " ", str);
trDataTolog(str, strlen(str), 1);
return RT_EOK;
}
/**
* 发送二维数组
* @param msg 待发二维数组
* @param s 各纬度数组长度
* @param row 数组长度
* @return 成功返回0
*/
int sendMsgs(const rt_uint8_t (*msg)[200], char *s, size_t row)
{
int ret = RT_EOK;
if (tcpInit() != RT_EOK)
{
ret = RT_ERROR;
return ret;
}
for (size_t var = 0; var < row; var++)
{
if (tcpSend(msg[var], s[row]) != RT_EOK)
{
ret = RT_ERROR;
break;
}
#ifdef CHK_ACK
if (tcpAck() != RT_EOK)
{
ret = RT_ERROR;
break;
};
#endif
}
tcpClose();
return ret;
}