配置Linux下USB串口驱动
在linux源码根目录下输入make menuconfig,并按下“/”键进行搜索,搜索到下图所示的内容,并通过该内容的指引,将相应的串口驱动配置成下图的状态。
CH341:
PL2303:
CP210X:
添加Linux设备树代码
在Linux设备树源码目录下找到对应开发板的设备树文件,用vim进行编辑,在设备树root的最后添加如下代码:(参考代码为EXIYNOS-FS4412开发板的适配代码,可根据实际情况进行修改)
usbphy: usbphy@125B0000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "samsung,exynos4x12-usb2phy";
reg = <0x125B0000 0x100>;
ranges;
clocks = <&clock 2>, <&clock 305>;
clock-names = "xusbxti", "otg";
usbphy-sys {
reg = <0x10020704 0x8 0x1001021c 0x4>;
};
};
ehci@12580000 {
status = "okay";
usbphy = <&usbphy>;
};
usb3503@08 {
compatible = "smsc,usb3503";
reg = <0x08 0x4>;
connect-gpios = <&gpm3 3 1>;
intn-gpios = <&gpx2 3 1>;
reset-gpios = <&gpm2 4 1>;
initial-mode = <1>;
};
最后不要忘记make uImage和make dtbs
Linux操作系统USB串口测试代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include "data_global.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;
/*保存原有串口配置*/
if (tcgetattr(fd, &old_cfg) != 0){
perror("tcgetattr");
return -1;
}
new_cfg =old_cfg;
/*配置为原始模式*/
cfmakeraw(&new_cfg);
new_cfg.c_cflag &= ~CSIZE;
/*设置波特率*/
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 115000:{
speed = B115200;
break;
}
}
cfsetispeed(&new_cfg, speed);
cfsetospeed(&new_cfg, speed);
/*设置数据位*/
switch (data_bits)
{
case 7:{
new_cfg.c_cflag |= CS7;
break;
}
default:
case 8:{
new_cfg.c_cflag |= CS8;
break;
}
}
/*设置奇偶校验位*/
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;
}
}
/*设置停止位*/
switch (stop_bits)
{
default:
case 1:{
new_cfg.c_cflag &= ~CSTOPB;
break;
}
case 2:{
new_cfg.c_cflag |= CSTOPB;
break;
}
}
/*设置等待时间和最小接收字符*/
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 1;
tcflush(fd, TCIFLUSH);
if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
{
perror("tcsetattr");
return -1;
}
return 0;
}
int open_port(char *com_port)
{
int fd;
/*打开串口*/
fd = open(com_port, O_RDWR|O_NOCTTY|O_NDELAY);
if (fd < 0){
perror("open serial port");
return -1;
}
/*恢复串口阻塞状态*/
if (fcntl(fd, F_SETFL, 0) < 0){
perror("fcntl F_SETFL\n");
}
/*判断是否为终端设备*/
if (isatty(fd) == 0){
perror("This is not a terminal device");
}
return fd;
}
/*--------------------CH340Ƥ׃---------------------------*/
void USB_UART_Config(char* path, int baud_rate)
{
int fd;
fd = open_port(path);
if(fd < 0){
printf("open %s failed\n",path);
return ;
}
if (set_com_config(fd, baud_rate, 8, 'N', 1) < 0)
{
perror("set_com_config");
return ;
}
close(fd);
return ;
}
int recvDats(int fd,unsigned char *pBuf,int datalen)
{
int curlen= 0;
int reallen= 0;
while(curlen < datalen)
{
reallen = read(fd,pBuf+curlen, datalen-curlen);
if(reallen >= 0){
curlen+=reallen;
}else{
//printf("%s %d:%s\n",__FUNCTION__,__LINE__,"uart recv err");
return -1;
}
}
return 0;
}
int main(int argc,const char *argv[])
{
int fd = open_port("/dev/ttyUSB0");
char buf[80]="";
if(fd < 0){
printf("open failed\n");
return -1;
}
set_com_config(fd, 115200, 8, 'N', 1);
while(1)
{
read(fd,&buf,sizeof(buf));
write(fd,&buf,sizeof(buf));
printf("sizeof(buf) = %d.\n",sizeof(buf));
printf(">>>>>>%s\n",buf);
}
close(fd);
return 0;
}
用arm-linux-gcc -o uarttest uarttest.c编译后,复制到开发板上运行即可。