Created
July 10, 2026 09:25
-
-
Save yashi/b26baf0e1d6912b193ce5cc98dda2c26 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #ifdef USE_TERMIOS2 | |
| #include <asm/termbits.h> | |
| #include <sys/ioctl.h> | |
| typedef struct termios2 termios_t; | |
| static int tcgetattr(int fd, termios_t *tio) | |
| { | |
| return ioctl(fd, TCGETS2, tio); | |
| } | |
| static int tcsetattr(int fd, int actions, const termios_t *tio) | |
| { | |
| unsigned long request; | |
| switch (actions) { | |
| case TCSANOW: | |
| request = TCSETS2; | |
| break; | |
| case TCSADRAIN: | |
| request = TCSETSW2; | |
| break; | |
| case TCSAFLUSH: | |
| request = TCSETSF2; | |
| break; | |
| default: | |
| errno = EINVAL; | |
| return -1; | |
| } | |
| return ioctl(fd, request, tio); | |
| } | |
| static int set_speed(termios_t *tio, unsigned int baudrate) | |
| { | |
| tio->c_cflag &= ~CBAUD; | |
| tio->c_cflag |= BOTHER; | |
| tio->c_ispeed = baudrate; | |
| tio->c_ospeed = baudrate; | |
| return 0; | |
| } | |
| #else | |
| #include <termios.h> | |
| typedef struct termios termios_t; | |
| static int set_speed(termios_t *tio, unsigned int baudrate) | |
| { | |
| speed_t speed; | |
| switch (baudrate) { | |
| case 9600: | |
| speed = B9600; | |
| break; | |
| case 19200: | |
| speed = B19200; | |
| break; | |
| case 38400: | |
| speed = B38400; | |
| break; | |
| case 57600: | |
| speed = B57600; | |
| break; | |
| case 115200: | |
| speed = B115200; | |
| break; | |
| default: | |
| errno = EINVAL; | |
| return -1; | |
| } | |
| if (cfsetispeed(tio, speed) < 0 || cfsetospeed(tio, speed) < 0) | |
| return -1; | |
| return 0; | |
| } | |
| #endif | |
| static int configure_serial(int fd, unsigned int baudrate) | |
| { | |
| termios_t tio; | |
| if (tcgetattr(fd, &tio) < 0) | |
| return -1; | |
| if (set_speed(&tio, baudrate) < 0) | |
| return -1; | |
| tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE); | |
| tio.c_cflag |= CS8 | CLOCAL | CREAD; | |
| tio.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); | |
| tio.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | | |
| PARMRK | INPCK | ISTRIP | IXON); | |
| tio.c_oflag &= ~OPOST; | |
| tio.c_cc[VMIN] = 1; | |
| tio.c_cc[VTIME] = 0; | |
| return tcsetattr(fd, TCSANOW, &tio); | |
| } | |
| int main(int argc, char **argv) | |
| { | |
| char *end; | |
| unsigned long value; | |
| int fd; | |
| int rc; | |
| if (argc != 3) { | |
| fprintf(stderr, "Usage: %s DEVICE BAUDRATE\n", argv[0]); | |
| return EXIT_FAILURE; | |
| } | |
| errno = 0; | |
| value = strtoul(argv[2], &end, 10); | |
| if (errno != 0 || *end != '\0' || value > 0xffffffffUL) { | |
| fprintf(stderr, "Invalid baud rate: %s\n", argv[2]); | |
| return EXIT_FAILURE; | |
| } | |
| fd = open(argv[1], O_RDWR | O_NOCTTY); | |
| if (fd < 0) { | |
| perror("open"); | |
| return EXIT_FAILURE; | |
| } | |
| rc = configure_serial(fd, (unsigned int)value); | |
| if (rc < 0) | |
| perror("configure_serial"); | |
| if (close(fd) < 0) { | |
| perror("close"); | |
| return EXIT_FAILURE; | |
| } | |
| return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment