commit 8c2cda65fc8f9320521505ed5fbc9ca083baa81e Author: zhaohe <1013909206@qq.com> Date: Wed Dec 29 17:29:47 2021 +0800 update diff --git a/README.md b/README.md new file mode 100644 index 0000000..79ef4e0 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# README + + +``` + +``` \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..1e2fb10 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +aarch64-linux-gnu-g++ uart_write_test_main.cpp uart.c --std=c++11 -o uart_write_test.out -lpthread +aarch64-linux-gnu-g++ uart_read_test_main.cpp uart.c --std=c++11 -o uart_read_test_main.out -lpthread diff --git a/enable_uart.sh b/enable_uart.sh new file mode 100755 index 0000000..686f7d1 --- /dev/null +++ b/enable_uart.sh @@ -0,0 +1,7 @@ +echo 68 > /sys/class/gpio/export +echo "out" > /sys/class/gpio/gpio68/direction +echo 0 > /sys/class/gpio/gpio68/value + +echo 69 > /sys/class/gpio/export +echo "out" > /sys/class/gpio/gpio69/direction +echo 1 > /sys/class/gpio/gpio69/value \ No newline at end of file diff --git a/release/aarch64/uart_read_test_main.out b/release/aarch64/uart_read_test_main.out new file mode 100755 index 0000000..c889546 Binary files /dev/null and b/release/aarch64/uart_read_test_main.out differ diff --git a/release/aarch64/uart_write_test.out b/release/aarch64/uart_write_test.out new file mode 100755 index 0000000..5ca8194 Binary files /dev/null and b/release/aarch64/uart_write_test.out differ diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..938ffb0 --- /dev/null +++ b/uart.c @@ -0,0 +1,196 @@ +/* + * uart.c + * + * Created on: Aug 5, 2019 + * Author: Cristian Fatu + * Implements basic UART functionality, over Uart Lite linux driver, using termios. + * After booting linux, a device like "/dev/ttyUL1" must be present. + * These functions work in both canonic and not canonic modes. + * In the canonic communication mode, the received chars can be retrieved by read only after \n is detected. + * In the non canonic communication mode, the received chars can be retrieved by read as they are received. + */ +#include +#include +#include +#include +#include +#include "uart.h" + +/* +Parameters: + + struct UartDevice* dev - pointer to the UartDevice struct + unsigned char canonic - communication mode + 1 - canonic communication (chars are only received after \n is detected). + 0 - non canonic communication (chars are received as they arrive over UART). + +Return value: + UART_FAILURE -1 failure + UART_SUCCESS 0 success + +Description: + Initializes the UART device. + When calling the function, the device name (usually "/dev/ttyUL1") must be filled in dev->name and the baud rate must be filled in dev->rate. + The canonic function parameter indicates communication mode (canonic or not). + In the canonic communication mode, the received chars can be retrieved by read only after \n is detected. + In the non canonic communication mode, the received chars can be retrieved by read as they are received, as the non canonic mode is configured with no wait. +*/ +int uartStart(struct UartDevice* dev, unsigned char canonic) { + struct termios *tty; + int fd; + int rc; + + fd = open(dev->name, O_RDWR | O_NOCTTY); + if (fd < 0) { + printf("%s: failed to open file descriptor for file %s\r\n", __func__, dev->name); + return UART_FAILURE; + } + + tty = (struct termios*)calloc(1, sizeof(*dev->tty)); + if (!tty) { + printf("%s: failed to allocate tty instance\r\n", __func__); + return UART_FAILURE; + } +// memset(tty, 0, sizeof(struct termios)); + + + /* + BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed. + CRTSCTS : output hardware flow control (only used if the cable has + all necessary lines. See sect. 7 of Serial-HOWTO) + CS8 : 8n1 (8bit,no parity,1 stopbit) + CLOCAL : local connection, no modem contol + CREAD : enable receiving characters + */ + // tty->c_cflag = dev->rate | CRTSCTS | CS8 | CLOCAL | CREAD; + tty->c_cflag = dev->rate | CS8 | CLOCAL | CREAD; + if (canonic) + { + // canonic + + /* + IGNPAR : ignore bytes with parity errors + ICRNL : map CR to NL (otherwise a CR input on the other computer + will not terminate input) + otherwise make device raw (no other input processing) + */ + tty->c_iflag = IGNPAR | ICRNL; + /* + ICANON : enable canonical input + disable all echo functionality, and don't send signals to calling program + */ + tty->c_lflag = ICANON; + } + else + { + // not canonic + /* + IGNPAR : ignore bytes with parity errorsc_cc[VTIME] + */ + tty->c_iflag = IGNPAR; + /* set input mode (non-canonical, no echo,...) */ + tty->c_lflag = 0; + /* Do not wait for data */ + tty->c_cc[VTIME] = 0; /* inter-character timer unused */ + tty->c_cc[VMIN] = 0; /* blocking read until 5 chars received */ + } + + /* + Raw output. + */ + tty->c_oflag = 0; + + + + /* Flush port */ + tcflush(fd, TCIFLUSH); + + /* Apply attributes */ + rc = tcsetattr(fd, TCSANOW, tty); + if (rc) { + printf("%s: failed to set TCSANOW attr\r\n", __func__); + return UART_FAILURE; + } + + dev->fd = fd; + dev->tty = tty; + + return UART_SUCCESS; +} + +/* +Parameters: + + struct UartDevice* dev - pointer to the UartDevice struct + char *data - pointer to the array of chars to be sent over UART + int size + positive value - number of chars to be sent over UART + -1 - indicates that all the chars until string terminator \0 will be sent + +Return value: + number of chars sent over UART + + +Description: + This function sends a number of chars over UART. + If the size function parameter is -1 then all the characters until string terminator \0 will be sent. +*/ +int uartSend(struct UartDevice* dev, char *data, int size) { + int sent = 0; + if(size == -1) + { + size = strlen(data); + } + sent = write(dev->fd, data, size); + +#ifdef DEBUG + printf("%s: sent %d characters\r\n", __func__, sent); +#endif + + return sent; +} + +/* +Parameters: + + struct UartDevice* dev - pointer to the UartDevice struct + char *data - pointer to the array of chars to hold the cars revceived over UART + int size_max - the maximum number of characters to be received + +Return value: + number of chars received over UART + + +Description: + This function receives characters over UART. + In the canonic communication mode, the received chars will be retrieved by read only after \n is detected. + In the non canonic communication mode, the received chars will be retrieved by read as they are received, as the non canonic mode is configured with no wait. +*/ +int uartReceive(struct UartDevice* dev, char* data, int size_max) { + int received = 0; + +#ifdef DEBUG +// printf("%s: receiving characters %d\r\n", __func__, size_max); +#endif + + received = read(dev->fd, data, size_max - 1); + data[received] = '\0'; + +#ifdef DEBUG +// if(received > 0) +// printf("%s: received %d characters\r\n", __func__, received); +// else +// printf("%s: r%d/%d\r\n", __func__, received, size_max); + +#endif + + return received; + +} + +int uartStop(struct UartDevice* dev) { + free(dev->tty); + + return UART_SUCCESS; + +} diff --git a/uart.h b/uart.h new file mode 100644 index 0000000..a2859a6 --- /dev/null +++ b/uart.h @@ -0,0 +1,32 @@ +/* + * uart.h + * + * Created on: Aug 5, 2019 + * Author: cristian + */ + +#include +#include + +#ifndef SRC_UART_H_ +#define SRC_UART_H_ + +#define UART_FAILURE -1 +#define UART_SUCCESS 0 + +#define DEBUG + +struct UartDevice { + char* name; + int rate; + + int fd; + struct termios *tty; +}; + +int uartStart(struct UartDevice* dev, unsigned char canonic); +int uartSend(struct UartDevice* dev, char *data, int size); +int uartReceive(struct UartDevice* dev, char* data, int size_max); +int uartStop(struct UartDevice* dev); + +#endif /* SRC_UART_H_ */ diff --git a/uart_read_test_main.cpp b/uart_read_test_main.cpp new file mode 100644 index 0000000..c368fea --- /dev/null +++ b/uart_read_test_main.cpp @@ -0,0 +1,70 @@ +/* + * Created on: Aug 5, 2019 + * Author: Cristian Fatu + * This project implements a basic UART communication over UART on + * Petalinux, unsing Uart Lite linux driver. The hardware platform implements an + * UART Lite IP core and the device tree (in pl.dtsi) sets the appropriate + * parameters. After booting linux, the "/dev/ttyUL1" must be present. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "uart.h" + +#define MAX_RECV_SIZE 235 + +void openuart(struct UartDevice *device, char *devname, int rate) { + device->name = devname; + device->rate = rate; + + printf("UART open %s\n", device->name); + int rc = uartStart(device, 0); + if (rc) { + printf("uartStart %s fail\n", device->name); + exit(-1); + } +} + +int main(int argc, char *argv[]) { + struct UartDevice dev = {0}; + // struct UartDevice dev2 = {0}; + + if (argc != 2) { + printf("Usage:%s dev1\n", argv[0]); + // printf("Demo:%s /dev/ttyUSB0 /dev/ttyUSB1\n", argv[0]); + exit(-1); + } + + openuart(&dev, argv[1], B9600); + // openuart(&dev, argv[1], B115200); + // openuart(&dev2, argv[2], B9600); + char buf[1024] = {0}; + memset(buf, 0x55, 1024); + for (size_t i = 0;; i++) { + int ret1, ret2; + ret1 = uartReceive(&dev, buf, 2/*接收的字节数2-1*/); // send the received text over UART + if (ret1 != 0) { + // printf("receive %d %x characters %d\n", ret1, buf[0], i); + printf("%x\n", buf[0]); + + if (buf[0] != 0x12 && buf[0] != 0x34 && buf[0] != 0x56 && + buf[0] != 0x78 && buf[0] != 0x9a) { + printf("....................................................%x\n", buf[0]); + } + } + // ret2 = uartSend(&dev2, buf, 1); // send the received text over UART + // usleep(1*1000); + } + + while (1) { + sleep(1); + } + + return 0; +} diff --git a/uart_write_test_main.cpp b/uart_write_test_main.cpp new file mode 100644 index 0000000..1a36db5 --- /dev/null +++ b/uart_write_test_main.cpp @@ -0,0 +1,61 @@ +/* + * Created on: Aug 5, 2019 + * Author: Cristian Fatu + * This project implements a basic UART communication over UART on + * Petalinux, unsing Uart Lite linux driver. The hardware platform implements an + * UART Lite IP core and the device tree (in pl.dtsi) sets the appropriate + * parameters. After booting linux, the "/dev/ttyUL1" must be present. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "uart.h" + +#define MAX_RECV_SIZE 235 + +void openuart(struct UartDevice *device, char *devname, int rate) { + device->name = devname; + device->rate = rate; + + printf("UART open %s\n", device->name); + int rc = uartStart(device, 0); + if (rc) { + printf("uartStart %s fail\n", device->name); + exit(-1); + } +} + +int main(int argc, char *argv[]) { + struct UartDevice dev = {0}; + // struct UartDevice dev2 = {0}; + + if (argc != 2) { + printf("Usage:%s dev1\n", argv[0]); + // printf("Demo:%s /dev/ttyUSB0 /dev/ttyUSB1\n", argv[0]); + exit(-1); + } + + openuart(&dev, argv[1], B9600); + // openuart(&dev2, argv[2], B9600); + char buf[1024] = {0x55}; + memset(buf, 0x55, 1024); + for (size_t i = 0;; i++) { + int ret1, ret2; + ret1 = uartSend(&dev, buf, 1); // send the received text over UART + // ret2 = uartSend(&dev2, buf, 1); // send the received text over UART + printf("send %d %d characters %d\n", ret1, ret2, i); + usleep(1*1000); + } + + while (1) { + sleep(1); + } + + return 0; +}