<修改> 1、优化libcomm公共库
This commit is contained in:
parent
0a7a3c49b3
commit
08039e4f2d
|
|
@ -0,0 +1,170 @@
|
|||
# libcomm 修补计划
|
||||
|
||||
> **目标**: 修复 UART send 不完整、TCP 空轮询、无 destroy 接口、stru_comm 冗余函数指针 四个问题
|
||||
|
||||
**涉及文件**:
|
||||
- 修改: `src/public/libcomm/src/comm_uart.cpp` — 恢复注释掉的成熟实现
|
||||
- 修改: `src/public/libcomm/src/comm_tcp.cpp` — TCP client select 去掉 100ms 空轮询
|
||||
- 修改: `src/public/libcomm/src/comm.cpp` — 添加 `comm_destroy`
|
||||
- 修改: `src/public/libcomm/inc/comm.h` — 清理 `stru_comm` 冗余字段 + 声明 `comm_destroy`
|
||||
- 修改: `release/inc/myComm.h` — 声明 `comm_destroy`
|
||||
- 更新: `mimo/工程/libcomm模块分析.md`
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 恢复 UART 成熟实现
|
||||
|
||||
**文件**: `src/public/libcomm/src/comm_uart.cpp`
|
||||
|
||||
注释掉的版本(行 361-692)比当前活跃代码更完整:
|
||||
|
||||
| 差异 | 当前活跃 | 注释版本 |
|
||||
|------|---------|---------|
|
||||
| open | `O_RDWR \| O_NOCTTY \| O_NDELAY` | `O_RDWR \| O_NOCTTY`(阻塞模式,由 VTIME 控制超时) |
|
||||
| 原始模式 | **无** | `~ICANON \| ~ECHO \| ~ECHOE \| ~ISIG` |
|
||||
| 输出处理 | **无** | `~OPOST` |
|
||||
| 输入处理 | **无** | `~IXON \| ~IXOFF \| ~IXANY \| ~ICRNL \| ~INLCR \| ~IGNCR` |
|
||||
| VTIME | 0 | **1**(100ms 读超时) |
|
||||
| VMIN | 0 | 0 |
|
||||
|
||||
**操作**: 删除当前活跃代码 + 注释代码(行 69-692),写入新实现。
|
||||
|
||||
新 `uart_send` 封装 `tcflush` + `write` + `tcdrain`,确保发送完整性:
|
||||
|
||||
```c
|
||||
static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
|
||||
{
|
||||
stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
if(NULL == p_uart || NULL == tx || 0 == tx_len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcflush(p_uart->uart_fd, TCOFLUSH);
|
||||
|
||||
int total = 0;
|
||||
while(total < tx_len)
|
||||
{
|
||||
int ret = write(p_uart->uart_fd, tx + total, tx_len - total);
|
||||
if(ret < 0)
|
||||
{
|
||||
LOG_E("write failed, errno:%d", errno);
|
||||
return -1;
|
||||
}
|
||||
total += ret;
|
||||
}
|
||||
|
||||
tcdrain(p_uart->uart_fd);
|
||||
|
||||
if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
|
||||
{
|
||||
p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_send, tx, tx_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: TCP client 去掉 100ms select 空轮询
|
||||
|
||||
**文件**: `src/public/libcomm/src/comm_tcp.cpp:245-246`
|
||||
|
||||
当前:
|
||||
```c
|
||||
struct timeval tmval = {0, 100000};
|
||||
int ret = select(p_tcp->sockfd + 1, &recvfdset, NULL, NULL, &tmval);
|
||||
```
|
||||
|
||||
改为:
|
||||
```c
|
||||
int ret = select(p_tcp->sockfd + 1, &recvfdset, NULL, NULL, NULL);
|
||||
```
|
||||
|
||||
去掉 `tmval` 变量声明。TCP client 线程专用此连接,阻塞 select 零 CPU 空转。
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 添加 `comm_destroy`
|
||||
|
||||
**文件**: `src/public/libcomm/src/comm.cpp`
|
||||
|
||||
在 `comm_state_register` 之后新增:
|
||||
|
||||
```c
|
||||
int comm_destroy(int id)
|
||||
{
|
||||
auto it = g_comm_map.find(id);
|
||||
if(it == g_comm_map.end())
|
||||
{
|
||||
LOG_E("comm id:%d not exist", id);
|
||||
return -1;
|
||||
}
|
||||
stru_comm &comm = it->second;
|
||||
|
||||
switch(comm.type)
|
||||
{
|
||||
case CommType::tcp_client:
|
||||
case CommType::tcp_server:
|
||||
free(comm.p_comm);
|
||||
break;
|
||||
case CommType::udp_client:
|
||||
case CommType::udp_server:
|
||||
free(comm.p_comm);
|
||||
break;
|
||||
case CommType::uart:
|
||||
free(comm.p_comm);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_comm_map.erase(it);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 清理 `stru_comm` 冗余函数指针
|
||||
|
||||
**文件**: `src/public/libcomm/inc/comm.h`
|
||||
|
||||
`stru_comm` 中 6 个函数指针字段从未被填充,所有分派走 `switch(type)`。删除:
|
||||
|
||||
```c
|
||||
int (*comm_connect)(int id);
|
||||
int (*comm_disconnect)(int id);
|
||||
int (*comm_run)(int id);
|
||||
int (*comm_state_register)(int id, comm_state_cb cb);
|
||||
int (*comm_recv_register)(int id, comm_recv_cb cb);
|
||||
int (*comm_send)(int id, const char *data, uint16_t len);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 头文件声明 `comm_destroy`
|
||||
|
||||
**文件**: `release/inc/myComm.h`
|
||||
|
||||
在 `comm_state_register` 声明后新增:
|
||||
```c
|
||||
int comm_destroy(int id);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 编译 + 更新文档
|
||||
|
||||
1. `./release/build.sh` 编译零错误零警告
|
||||
2. 更新 `mimo/工程/libcomm模块分析.md` 缺点表
|
||||
3. 追加到 `mimo/问题处理文档.md`
|
||||
|
||||
---
|
||||
|
||||
## 验证
|
||||
|
||||
| 步骤 | 命令 | 预期 |
|
||||
|------|------|------|
|
||||
| 全量编译 | `./release/build.sh` | `Build complete`,零错误零警告 |
|
||||
|
|
@ -211,11 +211,13 @@ static void comm_debug_show(str, dir, data, len):
|
|||
|
||||
| 缺点 | 严重度 | 说明 |
|
||||
|------|--------|------|
|
||||
| **TCP 客户端空轮询** | 中 | `tcp_client_connect` 循环中有 100ms select 超时无休眠,连接空闲时每 100ms 唤醒一次消耗 CPU |
|
||||
| **TCP 客户端空轮询** | 中 | ✅ **已修复 (2026-06-15)** — select 去掉 100ms 超时,改为永久阻塞,零 CPU 空转 |
|
||||
| **stru_comm 冗余函数指针** | 中 | ✅ **已修复 (2026-06-15)** — 删除 `stru_comm` 中从未使用的 6 个函数指针字段(comm_connect/comm_disconnect/comm_run/comm_state_register/comm_recv_register/comm_send) |
|
||||
| **UART send 未完整实现** | 高 | ✅ **已修复 (2026-06-15)** — 重写 comm_uart.cpp:恢复原始模式(~ICANON/~ECHO/~OPOST)、VTIME=1 读超时、tcflush+tcdrain 完整发送 |
|
||||
| **无内存释放** | 中 | ✅ **已修复 (2026-06-15)** — 新增 `comm_destroy(id)` API,释放 `p_comm` 内存并从 `g_comm_map` 移除 |
|
||||
| **TCP 服务端阻塞 select** | 低 | select 无超时,服务端空闲时线程永久阻塞,若需同时处理定时任务则无法在同一线程 |
|
||||
| **UDP 接收无超时** | 中 | `recvfrom` 直接阻塞在 `udp_run`,无超时无退出机制 |
|
||||
| **UART send 未完整实现** | 高 | 当前 uart_send 的注释掉代码占 400+ 行(含超时分帧逻辑),实际运行的 send 只是裸 write,无流量控制和错误恢复 |
|
||||
| **无内存释放** | 中 | `comm_create` 分配的 `p_comm` 和注册的回调没有对应的 destroy 接口,长期运行可能泄漏 |
|
||||
| **UDP 接收无超时** | 中 | ✅ **已修复 (2026-06-15)** — `udp_run` 中 `recvfrom` 前加 `select` 1s 超时,超时时 `continue` 继续循环 |
|
||||
| **UDP close 回调 fd 错误** | 低 | ✅ **已修复 (2026-06-15)** — `udp_close` 先保存 `fd` 再 `close`,回调传入正确的旧 fd |
|
||||
| **void* 类型擦除** | 中 | `p_comm` 是 `void*` 再强转为具体类型,编译器无法检测类型错误 |
|
||||
| **uart_connect 直接阻塞** | 低 | 串口打开和配置在工作线程的 `while(1)` 循环中,没有与上层消息分发解耦 |
|
||||
| **TCP client_fd 槽位管理粗糙** | 低 | 最多 16 个客户端,超出直接拒绝,没有等待队列或优雅降级 |
|
||||
|
|
|
|||
|
|
@ -4,6 +4,46 @@
|
|||
|
||||
## 2026-06-15
|
||||
|
||||
### #10 libcomm + 调用者缺陷修复
|
||||
|
||||
**问题**:
|
||||
1. UDP `recvfrom` 永久阻塞,无超时无退出机制
|
||||
2. UDP `close` 后 `state_cb(id, -1, disconnected)`,回调拿到的是已关闭的 -1
|
||||
3. `com_scan`/`self_ptl`/`iec` 三处 send+event 回滚竞态:`msg_queue_send` 成功 → `event_send` 失败 → `try_recv` 可能取出旧消息
|
||||
4. `com_channel_recv_cb` 中 `comm_send` 到已断开的 TCP_C_0 不检查 fd
|
||||
|
||||
**修复**:
|
||||
1. `udp_run` 中 `recvfrom` 前加 `select` 1s 超时
|
||||
2. `udp_close` 先保存 fd 再 close,回调传入正确值
|
||||
3. 三处改为先 `event_send` 再 `msg_queue_send`,消除回滚竞态
|
||||
4. `com_channel_recv_cb` 在 `comm_send` 前检查 `socket_fd >= 0`
|
||||
|
||||
**状态**:✅ 已完成
|
||||
**涉及文件**:`comm_udp.cpp`, `com_scan.cpp`, `self_ptl.cpp`, `iec.cpp`, `com_channel.cpp`
|
||||
**验证**:`./release/build.sh` 编译通过
|
||||
|
||||
---
|
||||
|
||||
### #9 libcomm 模块修补
|
||||
|
||||
**问题**:
|
||||
1. UART send 不完整:裸 write 无流量控制,缺少原始模式终端设置(~ICANON/~ECHO/~OPOST)
|
||||
2. TCP client select 100ms 空轮询,空闲时 CPU 空转
|
||||
3. 无 `comm_destroy` 接口,内存泄漏
|
||||
4. `stru_comm` 结构体中 6 个函数指针字段从未使用,冗余
|
||||
|
||||
**修复**:
|
||||
1. 重写 `comm_uart.cpp`:恢复原始模式 + VTIME=1 读超时 + tcflush/tcdrain 完整发送
|
||||
2. TCP client select 去掉超时参数,永久阻塞
|
||||
3. 新增 `comm_destroy(id)` API
|
||||
4. 删除 `stru_comm` 中 6 个未使用字段
|
||||
|
||||
**状态**:✅ 已完成
|
||||
**涉及文件**:`comm_uart.cpp`, `comm_tcp.cpp`, `comm.cpp`, `comm.h`, `myComm.h`
|
||||
**验证**:`./release/build.sh` 编译通过
|
||||
|
||||
---
|
||||
|
||||
### #8 libtask 事件/消息队列缺陷修复
|
||||
|
||||
**问题**:
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ int comm_disconnect(int id);
|
|||
int comm_send(int id, int fd, const uint8_t *data, uint16_t len);
|
||||
int comm_recv_register(int id, comm_recv_cb cb);
|
||||
int comm_state_register(int id, comm_state_cb cb);
|
||||
int comm_destroy(int id);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -41,15 +41,6 @@ typedef struct
|
|||
void *p_comm;
|
||||
comm_debug_show_cb debug_show_cb;
|
||||
|
||||
int (*comm_connect)(int id);
|
||||
int (*comm_disconnect)(int id);
|
||||
int (*comm_run)(int id);
|
||||
|
||||
int (*comm_state_register)(int id, comm_state_cb cb);
|
||||
int (*comm_recv_register)(int id, comm_recv_cb cb);
|
||||
|
||||
int (*comm_send)(int id, const char *data, uint16_t len);
|
||||
|
||||
}stru_comm;
|
||||
|
||||
#endif
|
||||
|
|
@ -406,6 +406,28 @@ int comm_state_register(int id, comm_state_cb cb)
|
|||
}
|
||||
|
||||
|
||||
int comm_destroy(int id)
|
||||
{
|
||||
std::map<int, stru_comm>::iterator it = g_comm_map.find(id);
|
||||
if(it == g_comm_map.end())
|
||||
{
|
||||
LOG_E("comm id:%d not exist", id);
|
||||
return -1;
|
||||
}
|
||||
stru_comm &comm = it->second;
|
||||
|
||||
if(NULL != comm.p_comm)
|
||||
{
|
||||
free(comm.p_comm);
|
||||
comm.p_comm = NULL;
|
||||
}
|
||||
|
||||
g_comm_map.erase(it);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
|
|
|||
|
|
@ -243,12 +243,11 @@ static int tcp_client_connect(int id, void *p_this)
|
|||
}
|
||||
|
||||
fd_set recvfdset;
|
||||
struct timeval tmval = {0, 100000};
|
||||
|
||||
FD_ZERO(&recvfdset);
|
||||
FD_SET(p_tcp->sockfd, &recvfdset);
|
||||
|
||||
int ret = select(p_tcp->sockfd + 1, &recvfdset, NULL, NULL, &tmval);
|
||||
int ret = select(p_tcp->sockfd + 1, &recvfdset, NULL, NULL, NULL);
|
||||
if(ret > 0 && FD_ISSET(p_tcp->sockfd, &recvfdset))
|
||||
{
|
||||
uint8_t buffer[1024] = {0};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "comm_uart.h"
|
||||
#include "myLog.h"
|
||||
|
|
@ -20,7 +21,7 @@ static void uart_sleep(int ticks)
|
|||
rqtp.tv_sec = ticks / 1000;
|
||||
rqtp.tv_nsec = (ticks % 1000) * 1000000L;
|
||||
|
||||
while (nanosleep(&rqtp, &rmtp) == -1 && errno == EINTR)
|
||||
while(nanosleep(&rqtp, &rmtp) == -1 && errno == EINTR)
|
||||
{
|
||||
rqtp = rmtp;
|
||||
}
|
||||
|
|
@ -74,18 +75,21 @@ static int uart_create(stru_comm_uart *p_uart)
|
|||
return -1;
|
||||
}
|
||||
|
||||
p_uart->uart_fd = open(p_uart->p_para->device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
if (p_uart->uart_fd < 0) {
|
||||
LOG_E("open %s failed\r\n", p_uart->p_para->device.c_str());
|
||||
p_uart->uart_fd = open(p_uart->p_para->device.c_str(), O_RDWR | O_NOCTTY);
|
||||
if(0 > p_uart->uart_fd)
|
||||
{
|
||||
LOG_E("open %s failed", p_uart->p_para->device.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct termios newtio, oldtio;
|
||||
struct termios newtio;
|
||||
|
||||
if(0 != tcgetattr(p_uart->uart_fd, &oldtio))
|
||||
if(0 != tcgetattr(p_uart->uart_fd, &newtio))
|
||||
{
|
||||
LOG_E("tcgetattr failed !\n");
|
||||
return (-1);
|
||||
LOG_E("tcgetattr failed");
|
||||
close(p_uart->uart_fd);
|
||||
p_uart->uart_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bzero(&newtio, sizeof(newtio));
|
||||
|
|
@ -98,67 +102,54 @@ static int uart_create(stru_comm_uart *p_uart)
|
|||
case 600:
|
||||
cfsetispeed(&newtio, B600);
|
||||
cfsetospeed(&newtio, B600);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 1200:
|
||||
cfsetispeed(&newtio, B1200);
|
||||
cfsetospeed(&newtio, B1200);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 2400:
|
||||
cfsetispeed(&newtio, B2400);
|
||||
cfsetospeed(&newtio, B2400);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 4800:
|
||||
cfsetispeed(&newtio, B4800);
|
||||
cfsetospeed(&newtio, B4800);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 9600:
|
||||
cfsetispeed(&newtio, B9600);
|
||||
cfsetospeed(&newtio, B9600);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 19200:
|
||||
cfsetispeed(&newtio, B19200);
|
||||
cfsetospeed(&newtio, B19200);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 38400:
|
||||
cfsetispeed(&newtio, B38400);
|
||||
cfsetospeed(&newtio, B38400);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 57600:
|
||||
cfsetispeed(&newtio, B57600);
|
||||
cfsetospeed(&newtio, B57600);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 115200:
|
||||
cfsetispeed(&newtio, B115200);
|
||||
cfsetospeed(&newtio, B115200);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 500000:
|
||||
cfsetispeed(&newtio, B500000);
|
||||
cfsetospeed(&newtio, B500000);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 1000000:
|
||||
cfsetispeed(&newtio, B1000000);
|
||||
cfsetospeed(&newtio, B1000000);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
case 2500000:
|
||||
cfsetispeed(&newtio, B2500000);
|
||||
cfsetospeed(&newtio, B2500000);
|
||||
LOG_I("baudrate = %d\n", p_uart->p_para->baudrate);
|
||||
break;
|
||||
default:
|
||||
cfsetispeed(&newtio, B115200);
|
||||
cfsetospeed(&newtio, B115200);
|
||||
LOG_I("default baudrate = %d\n", 115200);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -190,43 +181,45 @@ static int uart_create(stru_comm_uart *p_uart)
|
|||
|
||||
switch(p_uart->p_para->parity)
|
||||
{
|
||||
case 'n':
|
||||
case 'N':
|
||||
newtio.c_cflag &= ~PARENB; // Clear parity enable
|
||||
newtio.c_iflag &= ~INPCK; // Enable parity checking
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
newtio.c_cflag |= (PARODD | PARENB); // 设置为奇校验
|
||||
newtio.c_iflag |= INPCK; // Enable parity checking
|
||||
newtio.c_cflag |= (PARODD | PARENB);
|
||||
newtio.c_iflag |= INPCK;
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
newtio.c_cflag |= PARENB; // Enable parity
|
||||
newtio.c_cflag &= ~PARODD; // 设置为偶校验
|
||||
newtio.c_iflag |= INPCK; // Enable parity checking
|
||||
newtio.c_cflag |= PARENB;
|
||||
newtio.c_cflag &= ~PARODD;
|
||||
newtio.c_iflag |= INPCK;
|
||||
break;
|
||||
default:
|
||||
newtio.c_cflag &= ~PARENB; // Clear parity enable
|
||||
newtio.c_iflag &= ~INPCK; // Enable parity checking
|
||||
newtio.c_cflag &= ~PARENB;
|
||||
newtio.c_iflag &= ~INPCK;
|
||||
break;
|
||||
}
|
||||
|
||||
newtio.c_cc[VTIME] = 0;
|
||||
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||
newtio.c_oflag &= ~OPOST;
|
||||
newtio.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | INLCR | IGNCR);
|
||||
|
||||
newtio.c_cc[VTIME] = 1;
|
||||
newtio.c_cc[VMIN] = 0;
|
||||
|
||||
tcflush(p_uart->uart_fd, TCIFLUSH);
|
||||
|
||||
if((tcsetattr(p_uart->uart_fd, TCSANOW, &newtio)) != 0)
|
||||
if(0 != tcsetattr(p_uart->uart_fd, TCSANOW, &newtio))
|
||||
{
|
||||
LOG_E("tcsetattr failed !\n");
|
||||
return (-1);
|
||||
LOG_E("tcsetattr failed");
|
||||
close(p_uart->uart_fd);
|
||||
p_uart->uart_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_I("tcsetattr success ! %s, %d, %d, %d, %c\n",
|
||||
p_uart->p_para->device.c_str(), p_uart->p_para->baudrate, p_uart->p_para->data_bits,
|
||||
p_uart->p_para->stop_bits, p_uart->p_para->parity);
|
||||
return (0);
|
||||
LOG_I("uart init success: %s, %d, %d, %d, %c",
|
||||
p_uart->p_para->device.c_str(), p_uart->p_para->baudrate,
|
||||
p_uart->p_para->data_bits, p_uart->p_para->stop_bits, p_uart->p_para->parity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -252,7 +245,8 @@ static int uart_connect(int id, void *p_this)
|
|||
}
|
||||
|
||||
uint8_t rx_buffer[1024];
|
||||
while (1)
|
||||
|
||||
while(1)
|
||||
{
|
||||
int len = read(p_uart->uart_fd, rx_buffer, sizeof(rx_buffer));
|
||||
if(len > 0)
|
||||
|
|
@ -261,43 +255,49 @@ static int uart_connect(int id, void *p_this)
|
|||
{
|
||||
p_uart->recv_cb(id, p_uart->uart_fd, rx_buffer, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("recv_cb is null");
|
||||
}
|
||||
|
||||
if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
|
||||
{
|
||||
p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_recv, rx_buffer, len);
|
||||
}
|
||||
}
|
||||
else if(0 == len)
|
||||
{
|
||||
uart_sleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
uart_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
|
||||
{
|
||||
stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
if(NULL == p_uart)
|
||||
if(NULL == p_uart || NULL == tx || 0 == tx_len)
|
||||
{
|
||||
LOG_E("p_uart is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(NULL == tx || tx_len <= 0)
|
||||
{
|
||||
LOG_E("tx is null or len is invalid");
|
||||
return -1;
|
||||
}
|
||||
tcflush(p_uart->uart_fd, TCOFLUSH);
|
||||
|
||||
int ret = write(p_uart->uart_fd, tx, tx_len);
|
||||
int total = 0;
|
||||
while(total < tx_len)
|
||||
{
|
||||
int ret = write(p_uart->uart_fd, tx + total, tx_len - total);
|
||||
if(ret < 0)
|
||||
{
|
||||
LOG_E("write failed");
|
||||
LOG_E("write failed, errno:%d", errno);
|
||||
return -1;
|
||||
}
|
||||
total += ret;
|
||||
}
|
||||
|
||||
tcdrain(p_uart->uart_fd);
|
||||
|
||||
if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
|
||||
{
|
||||
|
|
@ -307,6 +307,7 @@ static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uart_close(void *p_this)
|
||||
{
|
||||
if(NULL == p_this)
|
||||
|
|
@ -317,12 +318,8 @@ static int uart_close(void *p_this)
|
|||
|
||||
stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
|
||||
if(p_uart->uart_fd < 0)
|
||||
if(p_uart->uart_fd >= 0)
|
||||
{
|
||||
LOG_E("uart_fd is invalid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(p_uart->uart_fd);
|
||||
p_uart->uart_fd = -1;
|
||||
|
||||
|
|
@ -330,10 +327,12 @@ static int uart_close(void *p_this)
|
|||
{
|
||||
p_uart->state_cb(0, p_uart->uart_fd, CommState::disconnected);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int comm_uart_create(stru_comm_uart *p_uart)
|
||||
{
|
||||
if(NULL == p_uart)
|
||||
|
|
@ -356,337 +355,3 @@ int comm_uart_create(stru_comm_uart *p_uart)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// #include <stdio.h>
|
||||
// #include <stdlib.h>
|
||||
// #include <string.h>
|
||||
// #include <termios.h>
|
||||
// #include <fcntl.h>
|
||||
// #include <sys/ioctl.h>
|
||||
// #include <sys/stat.h>
|
||||
// #include <strings.h>
|
||||
// #include <time.h>
|
||||
// #include <unistd.h>
|
||||
// #include <errno.h>
|
||||
|
||||
// #include "comm_uart.h"
|
||||
// #include "myLog.h"
|
||||
|
||||
// // 20ms 帧超时判断
|
||||
// #define FRAME_IDLE_TIMEOUT_MS 10
|
||||
// // 接收缓冲区最大长度
|
||||
// #define UART_MAX_FRAME_LEN 4096
|
||||
|
||||
// static void uart_sleep(int ticks)
|
||||
// {
|
||||
// struct timespec rqtp;
|
||||
// struct timespec rmtp;
|
||||
|
||||
// rqtp.tv_sec = ticks / 1000;
|
||||
// rqtp.tv_nsec = (ticks % 1000) * 1000000L;
|
||||
|
||||
// while (nanosleep(&rqtp, &rmtp) == -1 && errno == EINTR)
|
||||
// {
|
||||
// rqtp = rmtp;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 获取当前时间 ms
|
||||
// static long long get_current_ms(void)
|
||||
// {
|
||||
// struct timespec ts;
|
||||
// clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
// return ts.tv_sec * 1000LL + ts.tv_nsec / 1000000;
|
||||
// }
|
||||
|
||||
// static int uart_state_register(void *p_this, comm_state_cb cb)
|
||||
// {
|
||||
// if(NULL == p_this || NULL == cb)
|
||||
// {
|
||||
// LOG_E("p_this or cb is null");
|
||||
// return -1;
|
||||
// }
|
||||
// stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
// p_uart->state_cb = cb;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int uart_debug_show_register(void *p_this, comm_debug_show_cb cb)
|
||||
// {
|
||||
// if(NULL == p_this || NULL == cb)
|
||||
// {
|
||||
// LOG_E("p_this or cb is null");
|
||||
// return -1;
|
||||
// }
|
||||
// stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
// p_uart->debug_show_cb = cb;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int uart_recv_register(void *p_this, comm_recv_cb cb)
|
||||
// {
|
||||
// if(NULL == p_this || NULL == cb)
|
||||
// {
|
||||
// LOG_E("p_this or cb is null");
|
||||
// return -1;
|
||||
// }
|
||||
// stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
// p_uart->recv_cb = cb;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int uart_create(stru_comm_uart *p_uart)
|
||||
// {
|
||||
// if(NULL == p_uart)
|
||||
// {
|
||||
// LOG_E("uart is null");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// p_uart->uart_fd = open(p_uart->p_para->device.c_str(), O_RDWR | O_NOCTTY);
|
||||
// if (p_uart->uart_fd < 0) {
|
||||
// LOG_E("open %s failed\r\n", p_uart->p_para->device.c_str());
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// struct termios newtio;
|
||||
// if(0 != tcgetattr(p_uart->uart_fd, &newtio))
|
||||
// {
|
||||
// LOG_E("tcgetattr failed !\n");
|
||||
// close(p_uart->uart_fd);
|
||||
// p_uart->uart_fd = -1;
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// bzero(&newtio, sizeof(newtio));
|
||||
// newtio.c_cflag |= CLOCAL | CREAD;
|
||||
// newtio.c_cflag &= ~CSIZE;
|
||||
|
||||
// // 波特率配置(保留你原来的)
|
||||
// switch(p_uart->p_para->baudrate)
|
||||
// {
|
||||
// case 600:cfsetispeed(&newtio, B600);cfsetospeed(&newtio, B600);break;
|
||||
// case 1200:cfsetispeed(&newtio, B1200);cfsetospeed(&newtio, B1200);break;
|
||||
// case 2400:cfsetispeed(&newtio, B2400);cfsetospeed(&newtio, B2400);break;
|
||||
// case 4800:cfsetispeed(&newtio, B4800);cfsetospeed(&newtio, B4800);break;
|
||||
// case 9600:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;
|
||||
// case 19200:cfsetispeed(&newtio, B19200);cfsetospeed(&newtio, B19200);break;
|
||||
// case 38400:cfsetispeed(&newtio, B38400);cfsetospeed(&newtio, B38400);break;
|
||||
// case 57600:cfsetispeed(&newtio, B57600);cfsetospeed(&newtio, B57600);break;
|
||||
// case 115200:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;
|
||||
// case 500000:cfsetispeed(&newtio, B500000);cfsetospeed(&newtio, B500000);break;
|
||||
// case 1000000:cfsetispeed(&newtio, B1000000);cfsetospeed(&newtio, B1000000);break;
|
||||
// case 2500000:cfsetispeed(&newtio, B2500000);cfsetospeed(&newtio, B2500000);break;
|
||||
// default:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;
|
||||
// }
|
||||
|
||||
// // 数据位
|
||||
// switch(p_uart->p_para->data_bits)
|
||||
// {
|
||||
// case 7: newtio.c_cflag |= CS7; break;
|
||||
// case 8: newtio.c_cflag |= CS8; break;
|
||||
// default: newtio.c_cflag |= CS8; break;
|
||||
// }
|
||||
|
||||
// // 停止位
|
||||
// switch(p_uart->p_para->stop_bits)
|
||||
// {
|
||||
// case 1: newtio.c_cflag &= ~CSTOPB; break;
|
||||
// case 2: newtio.c_cflag |= CSTOPB; break;
|
||||
// default: newtio.c_cflag &= ~CSTOPB; break;
|
||||
// }
|
||||
|
||||
// // 校验位
|
||||
// switch(p_uart->p_para->parity)
|
||||
// {
|
||||
// case 'n':case 'N':
|
||||
// newtio.c_cflag &= ~PARENB;
|
||||
// newtio.c_iflag &= ~INPCK;
|
||||
// break;
|
||||
// case 'o':case 'O':
|
||||
// newtio.c_cflag |= (PARODD | PARENB);
|
||||
// newtio.c_iflag |= INPCK;
|
||||
// break;
|
||||
// case 'e':case 'E':
|
||||
// newtio.c_cflag |= PARENB;
|
||||
// newtio.c_cflag &= ~PARODD;
|
||||
// newtio.c_iflag |= INPCK;
|
||||
// break;
|
||||
// default:
|
||||
// newtio.c_cflag &= ~PARENB;
|
||||
// newtio.c_iflag &= ~INPCK;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// // 原始模式 + 超时设置
|
||||
// newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||
// newtio.c_oflag &= ~OPOST;
|
||||
// newtio.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | INLCR | IGNCR);
|
||||
|
||||
// // ===================== 关键:串口读取超时 =====================
|
||||
// newtio.c_cc[VTIME] = 1; // 读超时 100ms
|
||||
// newtio.c_cc[VMIN] = 0; // 最小读取 0 字节
|
||||
|
||||
// tcflush(p_uart->uart_fd, TCIFLUSH);
|
||||
// if((tcsetattr(p_uart->uart_fd, TCSANOW, &newtio)) != 0)
|
||||
// {
|
||||
// LOG_E("tcsetattr failed !\n");
|
||||
// close(p_uart->uart_fd);
|
||||
// p_uart->uart_fd = -1;
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// LOG_I("uart init success: %s, %d, %d, %d, %c\n",
|
||||
// p_uart->p_para->device.c_str(), p_uart->p_para->baudrate,
|
||||
// p_uart->p_para->data_bits, p_uart->p_para->stop_bits, p_uart->p_para->parity);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// // ===================== 核心:超时分帧接收 =====================
|
||||
// static int uart_connect(int id, void *p_this)
|
||||
// {
|
||||
// if(NULL == p_this)
|
||||
// {
|
||||
// LOG_E("p_this is null");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
// if(0 != uart_create(p_uart))
|
||||
// {
|
||||
// LOG_E("uart_create failed");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if(p_uart->state_cb)
|
||||
// p_uart->state_cb(id, p_uart->uart_fd, CommState::connected);
|
||||
|
||||
// // 动态帧缓冲区
|
||||
// uint8_t *frame_buf = (uint8_t *)malloc(UART_MAX_FRAME_LEN);
|
||||
// if(!frame_buf)
|
||||
// {
|
||||
// LOG_E("malloc failed");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// int frame_len = 0;
|
||||
// long long last_recv_ms = get_current_ms();
|
||||
|
||||
// uint8_t read_buf[1024];
|
||||
// while (1)
|
||||
// {
|
||||
// int len = read(p_uart->uart_fd, read_buf, sizeof(read_buf));
|
||||
// if(len > 0)
|
||||
// {
|
||||
// if(p_uart->recv_cb)
|
||||
// p_uart->recv_cb(id, p_uart->uart_fd, read_buf, len);
|
||||
|
||||
// if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
|
||||
// p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_recv, read_buf, len);
|
||||
// }
|
||||
|
||||
// uart_sleep(10);
|
||||
// // if(len > 0)
|
||||
// // {
|
||||
// // // 收到数据,拼帧
|
||||
// // if(frame_len + len < UART_MAX_FRAME_LEN)
|
||||
// // {
|
||||
// // memcpy(frame_buf + frame_len, read_buf, len);
|
||||
// // frame_len += len;
|
||||
// // last_recv_ms = get_current_ms();
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // LOG_E("frame overflow, reset");
|
||||
// // frame_len = 0;
|
||||
// // }
|
||||
// // }
|
||||
// // else if(len == 0)
|
||||
// // {
|
||||
// // // 超时,判断是否满足 20ms 空闲
|
||||
// // long long now = get_current_ms();
|
||||
// // if(frame_len > 0 && (now - last_recv_ms >= FRAME_IDLE_TIMEOUT_MS))
|
||||
// // {
|
||||
// // // ===================== 一帧接收完成 =====================
|
||||
// // if(p_uart->recv_cb)
|
||||
// // p_uart->recv_cb(id, p_uart->uart_fd, frame_buf, frame_len);
|
||||
|
||||
// // if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
|
||||
// // p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_recv, frame_buf, frame_len);
|
||||
|
||||
// // frame_len = 0; // 重置
|
||||
// // }
|
||||
// // uart_sleep(1); // 小延时降低 CPU
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // uart_sleep(1);
|
||||
// // }
|
||||
// }
|
||||
|
||||
// free(frame_buf);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int uart_send(void *p_this, const uint8_t *tx, uint16_t tx_len)
|
||||
// {
|
||||
// stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
// if(NULL == p_uart || NULL == tx || tx_len <= 0)
|
||||
// {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// int ret = write(p_uart->uart_fd, tx, tx_len);
|
||||
// if(ret < 0)
|
||||
// {
|
||||
// LOG_E("write failed");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if(p_uart->debug_show_cb && p_uart->debug_show == CommDebugShow::on)
|
||||
// {
|
||||
// p_uart->debug_show_cb(p_uart->p_para->device.c_str(), CommDir::dir_send, tx, tx_len);
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int uart_close(void *p_this)
|
||||
// {
|
||||
// if(NULL == p_this)
|
||||
// {
|
||||
// LOG_E("p_this is null");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// stru_comm_uart *p_uart = (stru_comm_uart *)p_this;
|
||||
// if(p_uart->uart_fd >= 0)
|
||||
// {
|
||||
// close(p_uart->uart_fd);
|
||||
// p_uart->uart_fd = -1;
|
||||
// }
|
||||
|
||||
// if(p_uart->state_cb)
|
||||
// {
|
||||
// p_uart->state_cb(0, p_uart->uart_fd, CommState::disconnected);
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int comm_uart_create(stru_comm_uart *p_uart)
|
||||
// {
|
||||
// if(NULL == p_uart)
|
||||
// {
|
||||
// LOG_E("uart is null");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// p_uart->uart_fd = -1;
|
||||
// p_uart->uart_state_register = uart_state_register;
|
||||
// p_uart->uart_debug_show_register = uart_debug_show_register;
|
||||
// p_uart->uart_recv_register = uart_recv_register;
|
||||
// p_uart->uart_connect = uart_connect;
|
||||
// p_uart->uart_send = uart_send;
|
||||
// p_uart->uart_close = uart_close;
|
||||
// return 0;
|
||||
// }
|
||||
|
|
@ -59,6 +59,22 @@ static void udp_run(int id, const char *udp_type, int sockfd, stru_comm_udp *p_u
|
|||
|
||||
while (1)
|
||||
{
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sockfd, &readfds);
|
||||
|
||||
struct timeval tv = {1, 0};
|
||||
int ret = select(sockfd + 1, &readfds, NULL, NULL, &tv);
|
||||
if(0 > ret)
|
||||
{
|
||||
LOG_E("select failed, errno:%d", errno);
|
||||
break;
|
||||
}
|
||||
if(0 == ret)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&src_addr, &addrlen);
|
||||
if(len > 0)
|
||||
{
|
||||
|
|
@ -66,10 +82,6 @@ static void udp_run(int id, const char *udp_type, int sockfd, stru_comm_udp *p_u
|
|||
{
|
||||
p_udp->recv_cb(id, sockfd, buffer, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("recv_cb is null");
|
||||
}
|
||||
|
||||
if(p_udp->debug_show_cb && p_udp->debug_show == CommDebugShow::on)
|
||||
{
|
||||
|
|
@ -263,12 +275,13 @@ static int udp_close(int id, void *p_this)
|
|||
return -1;
|
||||
}
|
||||
|
||||
close(p_udp->sockfd);
|
||||
int fd = p_udp->sockfd;
|
||||
close(fd);
|
||||
p_udp->sockfd = -1;
|
||||
|
||||
if(p_udp->state_cb)
|
||||
{
|
||||
p_udp->state_cb(id, p_udp->sockfd, CommState::disconnected);
|
||||
p_udp->state_cb(id, fd, CommState::disconnected);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -316,6 +316,12 @@ LOCAL void com_channel_recv_cb(int id, int socket_fd, const uint8_t *p_rx, uint1
|
|||
send_id = g_channel_para[ENUM_COMM_TCP_C_0].id;
|
||||
send_socket_fd = g_channel_para[ENUM_COMM_TCP_C_0].socket_fd;
|
||||
|
||||
if(send_socket_fd < 0)
|
||||
{
|
||||
LOG_E("com_channel_recv_cb TCP_C_0 disconnected, drop data");
|
||||
return;
|
||||
}
|
||||
|
||||
comm_send(send_id, send_socket_fd, p_rx, rx_len);
|
||||
}
|
||||
else if(id == g_channel_para[ENUM_COMM_UART_0].id)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ LOCAL int com_scan_send_data_to_app(stru_msg_head *p_head, uint16_t len, uint32_
|
|||
|
||||
if(0 != task_msg_queue_send(p_mq->p_msg_queue, p_head, p_mq->msg_size))
|
||||
{
|
||||
LOG_E("com_scan_send_data_to_app send to iec failed");
|
||||
LOG_E("com_scan_send_data_to_app send to queue failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue