diff options
-rw-r--r-- | include/Makefile | 9 | ||||
-rw-r--r-- | include/debug.h | 15 | ||||
-rw-r--r-- | include/proto.h | 28 | ||||
-rw-r--r-- | include/uart_api.c | 139 | ||||
-rw-r--r--[-rwxr-xr-x] | include/uart_api.h | 212 |
5 files changed, 214 insertions, 189 deletions
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 index cfa6473..5a25689 100755..100644 --- a/include/uart_api.h +++ b/include/uart_api.h @@ -1,189 +1,23 @@ -#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <termios.h>
-
-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 <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <termios.h> +#include <unistd.h> + +#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); |