improve serial

This commit is contained in:
lixianjing 2022-06-29 16:22:27 +08:00
parent f73aecb023
commit 8e97168136
4 changed files with 54 additions and 17 deletions

View File

@ -2,6 +2,7 @@
2022/06/29 2022/06/29
* 完善 edit 中 hook_children_button 的逻辑((感谢雨欣提供补丁)) * 完善 edit 中 hook_children_button 的逻辑((感谢雨欣提供补丁))
* 完善 Windows 的串口。
2022/06/27 2022/06/27
* 增加 fs\_copy\_dir\_ex * 增加 fs\_copy\_dir\_ex

View File

@ -78,6 +78,12 @@ ret_t tk_istream_serial_wait_for_data(tk_istream_t* stream, uint32_t timeout_ms)
return serial_wait_for_data(s->fd, timeout_ms); return serial_wait_for_data(s->fd, timeout_ms);
} }
static bool_t tk_istream_serial_eos(tk_istream_t* stream) {
tk_istream_serial_t* s = TK_ISTREAM_SERIAL(stream);
return serial_handle_get_dev(s->fd) == 0;
}
tk_istream_t* tk_istream_serial_create(serial_handle_t fd) { tk_istream_t* tk_istream_serial_create(serial_handle_t fd) {
tk_object_t* obj = NULL; tk_object_t* obj = NULL;
tk_istream_serial_t* istream_serial = NULL; tk_istream_serial_t* istream_serial = NULL;
@ -88,6 +94,7 @@ tk_istream_t* tk_istream_serial_create(serial_handle_t fd) {
return_value_if_fail(istream_serial != NULL, NULL); return_value_if_fail(istream_serial != NULL, NULL);
istream_serial->fd = fd; istream_serial->fd = fd;
TK_ISTREAM(obj)->eos = tk_istream_serial_eos;
TK_ISTREAM(obj)->read = tk_istream_serial_read; TK_ISTREAM(obj)->read = tk_istream_serial_read;
TK_ISTREAM(obj)->flush = tk_istream_serial_flush; TK_ISTREAM(obj)->flush = tk_istream_serial_flush;
TK_ISTREAM(obj)->wait_for_data = tk_istream_serial_wait_for_data; TK_ISTREAM(obj)->wait_for_data = tk_istream_serial_wait_for_data;

View File

@ -126,7 +126,7 @@ serial_handle_t serial_open(const char* port) {
handle->mutex = tk_mutex_create(); handle->mutex = tk_mutex_create();
handle->thread = tk_thread_create(serial_thread_entry, handle); handle->thread = tk_thread_create(serial_thread_entry, handle);
if (handle->cond == NULL || handle->mutex == NULL || handle->thread == NULL || if (!SetCommMask(dev, EV_RXCHAR) || handle->cond == NULL || handle->mutex == NULL || handle->thread == NULL ||
tk_socketpair(socks) < 0) { tk_socketpair(socks) < 0) {
serial_close(handle); serial_close(handle);
return NULL; return NULL;
@ -375,10 +375,6 @@ ret_t serial_config(serial_handle_t handle, uint32_t baudrate, bytesize_t bytesi
return RET_FAIL; return RET_FAIL;
} }
if (!SetCommMask(dev, EV_RXCHAR)) {
log_debug("Error setting RX event.");
return RET_FAIL;
}
return RET_OK; return RET_OK;
} }
@ -433,7 +429,7 @@ int serial_close(serial_handle_t handle) {
if (handle->cond != NULL) { if (handle->cond != NULL) {
tk_cond_destroy(handle->cond); tk_cond_destroy(handle->cond);
} }
memset(handle, 0x0, sizeof(*handle));
TKMEM_FREE(handle); TKMEM_FREE(handle);
} }
return 0; return 0;
@ -446,6 +442,10 @@ int32_t serial_read(serial_handle_t handle, uint8_t* buff, uint32_t max_size) {
bool_t has_signal = FALSE; bool_t has_signal = FALSE;
serial_dev_t dev = serial_handle_get_dev(handle); serial_dev_t dev = serial_handle_get_dev(handle);
if (serial_wait_for_data(handle, 0) != RET_OK) {
return 0;
}
if (!ReadFile(dev, buff, max_size, &bytes, &handle->read_overlapped)) { if (!ReadFile(dev, buff, max_size, &bytes, &handle->read_overlapped)) {
err = GetLastError(); err = GetLastError();
if (err == ERROR_IO_PENDING) { if (err == ERROR_IO_PENDING) {
@ -455,7 +455,7 @@ int32_t serial_read(serial_handle_t handle, uint8_t* buff, uint32_t max_size) {
} }
} }
tk_mutex_lock(handle->mutex); tk_mutex_lock(handle->mutex);
if (bytes > 0 && !handle->has_signal) { if (!handle->has_signal) {
if (recv(handle->client_fd, tmp_buff, sizeof(tmp_buff), 0) > 0) { if (recv(handle->client_fd, tmp_buff, sizeof(tmp_buff), 0) > 0) {
handle->has_signal = has_signal = TRUE; handle->has_signal = has_signal = TRUE;
} }
@ -485,8 +485,9 @@ int32_t serial_write(serial_handle_t handle, const uint8_t* buff, uint32_t max_s
static ret_t serial_wait_for_data_impl(serial_handle_t handle, uint32_t timeout_ms) { static ret_t serial_wait_for_data_impl(serial_handle_t handle, uint32_t timeout_ms) {
DWORD err = 0; DWORD err = 0;
DWORD mask = 0;
COMSTAT cstate = {0};
ret_t ret = RET_FAIL; ret_t ret = RET_FAIL;
DWORD mask = EV_RXCHAR;
serial_dev_t dev = serial_handle_get_dev(handle); serial_dev_t dev = serial_handle_get_dev(handle);
if (!WaitCommEvent(dev, &mask, &handle->read_overlapped)) { if (!WaitCommEvent(dev, &mask, &handle->read_overlapped)) {
err = GetLastError(); err = GetLastError();
@ -500,11 +501,17 @@ static ret_t serial_wait_for_data_impl(serial_handle_t handle, uint32_t timeout_
ret = RET_FAIL; ret = RET_FAIL;
} }
} }
} else {
ret = RET_OK;
} }
/* 清除可能的异常以及其事件,同时获取缓冲区的数据个数 */
ClearCommError(dev, &err, &cstate);
ClearCommError(dev, &err, NULL); if (cstate.cbInQue > 0) {
/* 如果缓冲区有数据的话,应该触发 serial_wait_for_data 让其他取缓冲区的数据。*/
ret = RET_OK;
} else if (ret == RET_OK) {
/* 如果缓冲区没有数据的话,但是却触发了 WaitForSingleObject 触发成功了,说明串口通信有异常,则应该返回 RET_FAIL。*/
ret = RET_FAIL;
}
return ret; return ret;
} }
@ -950,6 +957,7 @@ int serial_close(serial_handle_t handle) {
serial_oflush(handle); serial_oflush(handle);
close(dev); close(dev);
memset(handle, 0x0, sizeof(*handle));
TKMEM_FREE(handle); TKMEM_FREE(handle);
return 0; return 0;

View File

@ -1,8 +1,11 @@
#include "tkc/utils.h" #include "tkc/utils.h"
#include "tkc/platform.h" #include "tkc/platform.h"
#include "tkc/socket_helper.h"
#include "streams/serial/iostream_serial.h" #include "streams/serial/iostream_serial.h"
#include "streams/serial/serial_helper.h" #include "streams/serial/serial_helper.h"
#define TEST_READ_LEN 1
void do_send(tk_iostream_t* iostream, const char* msg) { void do_send(tk_iostream_t* iostream, const char* msg) {
char buff[128]; char buff[128];
int32_t ret = 0; int32_t ret = 0;
@ -13,12 +16,25 @@ void do_send(tk_iostream_t* iostream, const char* msg) {
ret = tk_ostream_write(ostream, (uint8_t*)buff, strlen(buff)); ret = tk_ostream_write(ostream, (uint8_t*)buff, strlen(buff));
log_debug("send ret=%d %s\n", ret, buff); log_debug("send ret=%d %s\n", ret, buff);
#ifdef TEST_READ_LEN
ret = tk_istream_read_line(istream, (uint8_t*)buff, sizeof(buff), 5000); log_debug("---------test tk_istream_read_len ---------------- \r\n");
while (ret > 0) { #else
log_debug("---------test tk_istream_read_line ---------------- \r\n");
#endif
for (uint32_t i = 0; i < 100000; i++) {
memset(buff, 0x0, sizeof(buff));
#ifdef TEST_READ_LEN
ret = tk_istream_read_len(istream, (uint8_t*)buff, sizeof(buff), 5000);
#else
ret = tk_istream_read_line(istream, (uint8_t*)buff, sizeof(buff), 5000); ret = tk_istream_read_line(istream, (uint8_t*)buff, sizeof(buff), 5000);
sleep_ms(100); #endif
if (ret > 0) {
log_debug("read data :%s--- \r\n", buff);
} else {
log_debug("read failed : %d \r\n", ret);
}
} }
tk_istream_flush(istream); tk_istream_flush(istream);
if (ret >= 0) { if (ret >= 0) {
@ -34,13 +50,18 @@ void do_send(tk_iostream_t* iostream, const char* msg) {
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
tk_iostream_t* serial = NULL;
if (argc != 3) { if (argc != 3) {
printf("Usage: %s port msg\n", argv[0]); printf("Usage: %s port msg\n", argv[0]);
return 0; return 0;
} }
TK_ENABLE_CONSOLE(); TK_ENABLE_CONSOLE();
do_send(tk_iostream_serial_create(argv[1]), argv[2]); tk_socket_init();
platform_prepare();
serial = tk_iostream_serial_create(argv[1]);
tk_iostream_serial_config(serial, 115200, eightbits, parity_none, stopbits_one, flowcontrol_none);
do_send(serial, argv[2]);
return 0; return 0;
} }