From 6944827ad2c1936cbf424014da72f680d415f4c1 Mon Sep 17 00:00:00 2001 From: Yan Date: Mon, 19 Feb 2024 18:37:18 +0800 Subject: monitor demo: provide header files provide uart api based on termios provide demo IPC protocol provide makefile that would generate a static lib Change-Id: I1d454d90cde7a5d829af3f410320e1e6412e0359 Signed-off-by: Yan --- include/Makefile | 9 +++ include/debug.h | 15 ++++ include/proto.h | 28 +++++++ include/uart_api.c | 139 +++++++++++++++++++++++++++++++++++ include/uart_api.h | 212 ++++++----------------------------------------------- 5 files changed, 214 insertions(+), 189 deletions(-) create mode 100644 include/Makefile create mode 100644 include/debug.h create mode 100644 include/proto.h create mode 100644 include/uart_api.c mode change 100755 => 100644 include/uart_api.h diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..12f4e25 --- /dev/null +++ b/include/Makefile @@ -0,0 +1,9 @@ +CFLAGS += -Wall -DDEBUG_LOG -g + +libcomfig.a: uart_api.o + $(AR) rcs $@ $^ + rm *.o + mv libcomfig.a ../lib + +uart_api.o: uart_api.c + $(CC) $(CFLAGS) -c $< -o $@ diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 0000000..0858176 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,15 @@ +/* + * File Name: debug.h + * Description: if DEBUG_LOG macro defined, expand the DebugLog definition + */ + +#ifndef __DEMO_DEBUG_H__ +#define __DEMO_DEBUG_H__ + +#ifdef DEBUG_LOG +#define DebugLog(format, ...) printf(format, ##__VA_ARGS__); +#else +#define DebugLog(format, ...) +#endif + +#endif \ No newline at end of file diff --git a/include/proto.h b/include/proto.h new file mode 100644 index 0000000..a9307f0 --- /dev/null +++ b/include/proto.h @@ -0,0 +1,28 @@ +/* + * File Name: proto.h + * Description: demo communication protocal + */ + +#ifndef __DEMO_PROTOCOL__ +#define __DEMO_PROTOCOL__ + +/* demo message queue struct */ +typedef struct demo_mq_struct { + long mtype; + _Bool tswitch; +} MQ_STRUCT; + +/* demo shared memory struct */ +typedef struct zigbee_th_struct { + unsigned short tempNow; + unsigned short humiNow; +} SHM_STRUCT; + +/* resources child threads need */ +typedef struct thread_resource_struct { + int rw_fd; + int shm_id; + int mq_id; +} ARG_STRUCT; + +#endif diff --git a/include/uart_api.c b/include/uart_api.c new file mode 100644 index 0000000..94d8a60 --- /dev/null +++ b/include/uart_api.c @@ -0,0 +1,139 @@ +/* + * File Name: uart_api.c + * Workflow: implementation of the uart apis + * Return Value: open_port return file describer as successful, + * set_comfig return 0 as successful, + * both function would return -1 as erroneaous + */ + +/* Header files */ +#include "uart_api.h" + +/* + * Function Name: open_port + * Workflow: get a file describer that follows the under requests: + * 1, it must be a terminal device + * 2, it is NONBLOCK mode + */ +int open_port(const char *com_port) { + int fd; + int flags; + + /* open port in read/write mode */ + fd = open(com_port, O_RDWR, S_IRUSR | S_IWUSR); + DebugLog("[DEBUG-INFO %s:%d]:Open from \"%s\" get fd: %d\n", __FUNCTION__, + __LINE__, com_port, fd); + + if (fd < 0) { + fprintf(stderr, "[%s:%d] open(): %s", __FUNCTION__, __LINE__, + strerror(errno)); + return -1; + } + + /* check if fd is associated with a terminal */ + if (isatty(fd) == 0) { + fprintf(stderr, "[%s:%d] isatty(): %s", __FUNCTION__, __LINE__, + strerror(errno)); + close(fd); + return -1; + } + + /* file describer is set to non-block mode */ + flags = fcntl(fd, F_GETFL); + + if (flags == -1) { + fprintf(stderr, "[%s:%d] fcntl(): %s", __FUNCTION__, __LINE__, + strerror(errno)); + close(fd); + return -1; + } + + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { + fprintf(stderr, "[%s:%d] fcntl(): %s", __FUNCTION__, __LINE__, + strerror(errno)); + close(fd); + return -1; + } + + return fd; +} + +/* + * Function Name: set_comfig + * Workflow: use termios to set the port under these requests: + * 1, data bit fixed to 8 + * 2, no parity check + * 3, 1 stop bit + * 4, no hardware control flow + * 5, wait 3 seconds OR read 6 bytes, either reaches read + * would return 6, buffer must be clean + */ +int set_comfig(int serial_fd, int baud_rate) { + struct termios term_new, term_old; + + /* save old config */ + if (tcgetattr(serial_fd, &term_old) == -1) { + fprintf(stderr, "[%s:%d] tcgetattr(): %s", __FUNCTION__, __LINE__, + strerror(errno)); + return -1; + } + + /* prepare new config struct to be used */ + cfmakeraw(&term_new); + term_new.c_cflag &= ~CSIZE; + + /* set baud rate */ + switch (baud_rate) { + case 9600: + cfsetispeed(&term_new, B9600); + cfsetospeed(&term_new, B9600); + break; + case 115200: + cfsetispeed(&term_new, B115200); + cfsetospeed(&term_new, B115200); + break; + default: + fprintf(stderr, "[%s:%d] switch(baud_rate): %s", __FUNCTION__, __LINE__, + strerror(errno)); + return -1; + } + + /* set data bit to 8 */ + term_new.c_cflag &= ~CSIZE; + term_new.c_cflag |= CS8; + + /* set no parity check */ + term_new.c_cflag &= ~PARENB; + term_new.c_iflag &= ~INPCK; + + /* set stop bit to 1 */ + term_new.c_cflag &= ~CSTOPB; + + /* disable hardware flow control + * term_new.c_cflag &= ~CRTSCTS; */ + + /* set to line buffered */ + term_new.c_lflag |= ICANON; + + /* set EOF and EOF */ + term_new.c_cc[VEOL] = '\0'; + + /* read() function would wait 3 seconds before return */ + term_new.c_cc[VTIME] = 30; + + /* read() fuction would return if 6 bytes read */ + term_new.c_cc[VMIN] = 6; + + /* flush IO buffer area */ + tcflush(serial_fd, TCIFLUSH); + tcflush(serial_fd, TCOFLUSH); + + /* enable setting */ + if (tcsetattr(serial_fd, TCSANOW, &term_new) == -1) { + fprintf(stderr, "[%s:%d] tcsetattr: %s", __FUNCTION__, __LINE__, + strerror(errno)); + return -1; + } + + return 0; +} diff --git a/include/uart_api.h b/include/uart_api.h old mode 100755 new mode 100644 index cfa6473..5a25689 --- a/include/uart_api.h +++ b/include/uart_api.h @@ -1,189 +1,23 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits) -{ - struct termios new_cfg, old_cfg; - int speed; - - /*save old config*/ - if (tcgetattr(fd, &old_cfg) != 0) - { - perror("tcgetattr"); - return -1; - } - - new_cfg =old_cfg; - - /*enable local connection and read function*/ - new_cfg.c_cflag |= CLOCAL | CREAD; - - /*disable bit mask*/ - new_cfg.c_cflag &= ~CSIZE; - - /*disable hardware dataflow control*/ - new_cfg.c_cflag &= ~CRTSCTS; - - /*ignore parity error*/ - new_cfg.c_iflag |= IGNPAR; - - /*do not transform CR to NL, enable output software data flow control*/ - new_cfg.c_iflag &= ~(ICRNL | IXON); - - /*set baud rate*/ - switch (baud_rate) - { - case 2400: - { - speed = B2400; - break; - } - case 4800: - { - speed = B4800; - break; - } - case 9600: - { - speed = B9600; - break; - } - case 19200: - { - speed = B19200; - break; - } - case 38400: - { - speed = B38400; - break; - } - - default: - case 115200: - { - speed = B115200; - break; - } - } - - cfsetispeed(&new_cfg, speed); - cfsetospeed(&new_cfg, speed); - - /*set data bits*/ - switch (data_bits) - { - case 7: - { - new_cfg.c_cflag |= CS7; - break; - } - - default: - case 8: - { - new_cfg.c_cflag |= CS8; - break; - } - } - - /*set parity*/ - switch (parity) - { - default: - case 'n': - case 'N': - { - new_cfg.c_cflag &= ~PARENB; - new_cfg.c_iflag &= ~INPCK; - break; - } - - case 'o': - case 'O': - { - new_cfg.c_cflag |= (PARODD |PARENB); - new_cfg.c_iflag |= INPCK; - break; - } - - case 'e': - case 'E': - { - new_cfg.c_cflag |= PARENB; - new_cfg.c_cflag &= ~PARODD; - new_cfg.c_iflag |= INPCK; - break; - } - - case 's': - case 'S': - { - new_cfg.c_cflag &= ~PARENB; - new_cfg.c_cflag &= ~CSTOPB; - break; - } - } - - /*set stop bits*/ - switch (stop_bits) - { - default: - case 1: - { - new_cfg.c_cflag &= ~CSTOPB; - break; - } - - case 2: - { - new_cfg.c_cflag |= CSTOPB; - break; - } - } - - new_cfg.c_oflag = 0; - new_cfg.c_lflag = 0; - - if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0) - { - perror("tcsetattr"); - return -1; - } - - return 0; -} - -int open_port(char *com_port) -{ - int fd; - - /*open port*/ - fd = open(com_port, O_RDWR|O_NOCTTY|O_NDELAY); - if (fd < 0) - { - perror("open serial port"); - return -1; - } - - /*jam port*/ - if (fcntl(fd, F_SETFL, 0) < 0) - { - perror("jam port"); - } - - /*check if it is a terminal device*/ - if (isatty(fd) == 0) - { - perror("check terminal device"); - } - - return fd; -} +/* + * File Name: uart_api.h + * Workflow: serial operation function declaration + */ + +/* Header files */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" + +/* open a path, check and return satisfied file describer */ +int open_port(const char *com_port); + +/* set serial config using termios struct, in this API only baud rate is set */ +int set_comfig(int serial_fd, int baud_rate); -- cgit 1.2.3-korg