open_port: Permission denied
"Cannot open /dev/ttyS?: Permission denied"
(2006-09-08 09:37:17)Unless stty is set for clocal, the CD pin may need to be asserted in order to open a serial port. If the physical port is not connected to anything, or if it's connected to something that is not powered on (such an external modem) then there will be no voltage on CD from that device. Thus the "cannot open" message. Either set clocal or connect the serial port connector to something and power it on.
Even if a device is powered on and connected to a port, it may sometimes prevent opening the port. An example of this is where the device has negated CD and the CD pin on your PC is negated (negative voltage).
"Operation not supported by device" for ttyS?
This means that an operation requested by setserial, stty, etc. couldn't be done because the kernel doesn't support doing it. Formerly this was often due to the "serial" module not being loaded. But with the advent of PnP, it may likely mean that there is no modem (or other serial device) at the address where the driver (and setserial) thinks it is. If there is no modem there, commands (for operations) sent to that address obviously don't get done. See What is set in my serial port hardware?
If the "serial" module wasn't loaded but "lsmod" shows you it's now loaded it might be the case that it's loaded now but wasn't loaded when you got the error message. In many cases the module will automatically loaded when needed (if it can be found). To force loading of the "serial" module it may be listed in the file: /etc/modules.conf or /etc/modules. The actual module should reside in: /lib/modules/.../misc/serial.o.
-
下面是一个简单的读取串口数据的例子
#include<stdio.h> /*标准输入输出定义*/
#include<stdlib.h> /*标准函数库定义*/
#include<unistd.h> /*Unix标准函数定义*/
#include<sys/types.h> /**/
#include<sys/stat.h> /**/
#include<fcntl.h> /*文件控制定义*/
#include<termios.h> /*PPSIX终端控制定义*/
#include<errno.h> /*错误号定义*/
#defineFALSE -1
#defineTRUE 0
/***@brief设置串口通信速率
*@paramfd 类型 int 打开串口的文件句柄
*@paramspeed 类型 int 串口速度
*@returnvoid*/
intspeed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
intname_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300, };
voidset_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0)
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
/**
*@brief设置串口数据位,停止位和效验位
*@paramfd 类型 int 打开的串口文件句柄*
*@paramdatabits 类型 int 数据位 取值 为 7 或者8*
*@paramstopbits 类型 int 停止位 取值为 1 或者2*
*@paramparity 类型 int 效验类型 取值为N,E,O,,S
*/
intset_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; // 15 seconds
options.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
/**
*@breif打开串口
*/
intOpenDev(char *Dev)
{
intfd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{ /*设置数据位数*/
perror("Can't Open Serial Port");
return -1;
}
else
return fd;
}
/**
*@breifmain()
*/
intmain(int argc, char **argv)
{
int fd;
int nread;
char buff[512];
char *dev ="/dev/ttyS0";
fd = OpenDev(dev);
if (fd>0)
set_speed(fd,19200);
else
{
printf("Can't Open Serial Port!\n");
exit(0);
}
if (set_Parity(fd,8,1,'N')== FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
while(1)
{
while((nread = read(fd,buff,512))>0)
{
printf("\nLen %d\n",nread);
buff[nread+1]='\0';
printf("\n%s",buff);
}
}
//close(fd);
//exit(0);
}
编译成功后,执行却提示“can'topen serial port:permission denided”
google到上面的帖子,chmod777 ttys0 ,问题迎刃而解。