LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Help: cannot change baud rate to s3c2410 seial port via tcsetattr (https://www.linuxquestions.org/questions/linux-software-2/help-cannot-change-baud-rate-to-s3c2410-seial-port-via-tcsetattr-753193/)

lxpwj 09-06-2009 09:49 PM

Help: cannot change baud rate to s3c2410 seial port via tcsetattr
 
Hello,

I am writing a simple serial port programing based on s3c2410. However, I found that I cannot change serial port attributes including baud rate using tcsetattr. I think i have follow "Serial Programming Guid for POSIX operating system" strictly, but why it does not work? the baund rate cannot be changed to 115200?

Below is my program
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <error.h>
#include <string.h>
#define _POSIX_SOURCE 1 /* POSIX compliant source */

int myopen_port(char* port, int rate){
int fd,ret;
struct termios curopt;

fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0){
printf("open_port failed");
return -1;
}else {
//fcntl(fd, F_SETFL, FNDELAY); //non-blocking
fcntl(fd, F_SETFL, 0);
}


bzero(&curopt, sizeof(curopt));
/* Mostly 8N1 */
curopt.c_cflag &= ~PARENB;
curopt.c_cflag &= ~CSTOPB;
curopt.c_cflag &= ~CSIZE;
curopt.c_cflag |= CS8;
curopt.c_cflag |= CLOCAL|CREAD; //disable modem statuc check
/* to disable flow control*/
curopt.c_iflag &= ~( IXON|IXOFF|IXANY);

cfmakeraw(&curopt); //make raw mode
/* Set the baud rate */
printf("rate 0x%x\n",rate);
ret = cfsetispeed(&curopt, rate);
if( ret < 0) printf("error set cfsestispeed\n");
ret = cfsetospeed(&curopt, rate);
if( ret < 0) printf("error set cfsestospeed\n");
/* set blocking reading wait condition*/
curopt.c_cc[VMIN] = 1;
curopt.c_cc[VTIME] = 0;

printf("setting attributes:\n");
printf("c_cflag 0x%x \n", curopt.c_cflag);
printf("c_iflag 0x%x \n", curopt.c_iflag);
printf("c_oflag 0x%x \n", curopt.c_oflag);
printf("c_lflag 0x%x \n", curopt.c_lflag);
tcflush(fd, TCIFLUSH);

ret = tcsetattr(fd, TCSANOW, &curopt);
printf("set attribute results: %d\n", ret);
printf("--------------------------------\n");
printf("reading back attributes:\n");
ret = tcgetattr(fd, &curopt);
printf("reading results %d\n", ret);
printf("c_cflag 0x%x \n", curopt.c_cflag);
printf("c_iflag 0x%x \n", curopt.c_iflag);
printf("c_oflag 0x%x \n", curopt.c_oflag);
printf("c_lflag 0x%x \n", curopt.c_lflag);
return fd;
}

int main(int argc, char *argv[])
{
int fd;
int addr =0, ret,s,t;
unsigned char rbuf[50];

fd = myopen_port(argv[1], B115200);
printf("OPEN PORT %s RESULTS %d ", argv[1], fd);
if (fd > 0)
{
memset(rbuf,0,50);
for (addr=0;addr <50000; addr++)
{
ret = read(fd,rbuf,50);
memset(rbuf,0,50);
usleep(10);
}
myclose_port(fd);
}
return 0;
}

lxpwj 09-06-2009 09:56 PM

more information from kernel printk
1. once I issue command tcsetattr, the kernel will invoke uart_ioctl in the serial_core.c
2. I have checked the s3c2410 uart driver and I think the driver is using s3c24xx_serial_set_termios to do hardware setting for baund rate and other stuffs.

my question is why tcsetattr does not finally call s3c24xx_serial_set_termios to set hardware setting?
Please point out my mistakes if I am wrong. Thank you very much.

lxpwj 09-07-2009 04:08 AM

this issue is closed.

the source code itself is quite OK.
The problem is our cross-compiling enviroment setting. Thanks a lot.


All times are GMT -5. The time now is 11:48 AM.