3. 編程
PC: open/read/write /dev/ttyACM0
板子: open/read/write /dev/ttyGS0
源碼:
#include < stdio.h >
#include < string.h >
#include < sys/types.h >
#include < errno.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < unistd.h >
#include < termios.h >
#include < stdlib.h >
#include < pthread.h >
static struct termios old, current;
/* Initialize new terminal i/o settings */
void initTermios(int echo)
{
tcgetattr(0, &old); /* grab old terminal i/o settings */
current = old; /* make new settings same as old settings */
current.c_lflag &= ~ICANON; /* disable buffered i/o */
if (echo) {
current.c_lflag |= ECHO; /* set echo mode */
} else {
current.c_lflag &= ~ECHO; /* set no echo mode */
}
tcsetattr(0, TCSANOW, ¤t); /* use these new terminal i/o settings now */
}
/* Restore old terminal i/o settings */
void resetTermios(void)
{
tcsetattr(0, TCSANOW, &old);
}
/* set_opt(fd,115200,8,'N',1) */
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio,oldtio;
if ( tcgetattr( fd,&oldtio) != 0) {
perror("SetupSerial 1");
return -1;
}
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
newtio.c_oflag &= ~OPOST; /*Output*/
switch( nBits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
}
switch( nEvent )
{
case 'O':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E':
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N':
newtio.c_cflag &= ~PARENB;
break;
}
switch( nSpeed )
{
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
default:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
}
if( nStop == 1 )
newtio.c_cflag &= ~CSTOPB;
else if ( nStop == 2 )
newtio.c_cflag |= CSTOPB;
newtio.c_cc[VMIN] = 1; /* 讀數(shù)據(jù)時的最小字節(jié)數(shù): 沒讀到這些數(shù)據(jù)我就不返回! */
newtio.c_cc[VTIME] = 0; /* 等待第1個數(shù)據(jù)的時間:
* 比如VMIN設(shè)為10表示至少讀到10個數(shù)據(jù)才返回,
* 但是沒有數(shù)據(jù)總不能一直等吧? 可以設(shè)置VTIME(單位是10秒)
* 假設(shè)VTIME=1,表示:
* 10秒內(nèi)一個數(shù)據(jù)都沒有的話就返回
* 如果10秒內(nèi)至少讀到了1個字節(jié),那就繼續(xù)等待,完全讀到VMIN個數(shù)據(jù)再返回
*/
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error");
return -1;
}
//printf("set done!n");
return 0;
}
int open_port(char *com)
{
int fd;
//fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY);
fd = open(com, O_RDWR|O_NOCTTY);
if (-1 == fd){
return(-1);
}
if(fcntl(fd, F_SETFL, 0)< 0) /* 設(shè)置串口為阻塞狀態(tài)*/
{
printf("fcntl failed!n");
return -1;
}
return fd;
}
static void *my_read_thread_func(void *data)
{
int fd = (int)data;
int iRet;
char c;
while (1)
{
iRet = read(fd, &c, 1);
printf("%c", c);
fflush(stdout);
}
}
/*
* ./serial_send_recv < dev >
*/
int main(int argc, char **argv)
{
int fd;
int iRet;
char c;
pthread_t tid;
/* 1. open */
/* 2. setup
* 115200,8N1
* RAW mode
* return data immediately
*/
/* 3. write and read */
if (argc != 2)
{
printf("Usage: n");
printf("%s < /dev/ttySAC1 or other >n", argv[0]);
return -1;
}
fd = open_port(argv[1]);
if (fd < 0)
{
printf("open %s err!n", argv[1]);
return -1;
}
iRet = set_opt(fd, 115200, 8, 'N', 1);
if (iRet)
{
printf("set port err!n");
return -1;
}
/* 創(chuàng)建一個讀線程 */
iRet = pthread_create(&tid, NULL, my_read_thread_func, (void *)fd);
if (iRet)
{
printf("pthread_create err!n");
return -1;
}
printf("Enter a char: ");
initTermios(1);
// 寫線程
while (1)
{
c = getchar();
iRet = write(fd, &c, 1);
if (iRet != 1)
printf("can not write datan");
}
resetTermios();
return 0;
}
4. 上機(jī)實(shí)驗(yàn)
編譯 2 個版本,有兩條命令:PC、ARM
gcc -o serial_send_recv_pc serial_send_recv.c -lpthread
arm-buildroot-linux-gnueabihf-gcc -o serial_send_recv_arm serial_send_recv.c -lpthread
使用 USB 線連接板子的 OTG 口、PC 的 USB 口,PC 上監(jiān)測到 USB 串口后把它連接到 VMWare,確定:
- 開發(fā)板上有設(shè)備節(jié)點(diǎn):/dev/ttyGS0
- Ubuntu上有設(shè)備節(jié)點(diǎn):/dev/ttyACM0
測試:
- 在 Ubuntu 上執(zhí)行:
sudo ./serial_send_recv_pc /dev/ttyACM0
- 在板子上執(zhí)行:
sudo ./serial_send_recv_arm /dev/ttyGS0
- 雙方即可互發(fā)數(shù)據(jù)
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報(bào)投訴
-
嵌入式
+關(guān)注
關(guān)注
5086文章
19143瀏覽量
306094 -
Linux
+關(guān)注
關(guān)注
87文章
11319瀏覽量
209830 -
編程
+關(guān)注
關(guān)注
88文章
3627瀏覽量
93809
發(fā)布評論請先 登錄
相關(guān)推薦
如何配置USB OTG為Gadget serial device?
現(xiàn)需要將OKA40i-C板子上的OTG下載口配置為虛擬串口,實(shí)現(xiàn)u***串行通信,利用linux已存在的u***轉(zhuǎn)虛擬串口驅(qū)動:USB Gadget Drivers (Serial Gadge
發(fā)表于 01-04 06:47
分享一種將RK3399配置成USB gadget設(shè)備的方法
1、RK3399的USB type-c接口初始化配置RK3399中提供了USB gadget設(shè)備的支持,程序在內(nèi)核中目錄“kernel/drivers/u***/gadget”中,支持
發(fā)表于 05-24 10:35
基于Linux內(nèi)核的Rockchip USB Gadget UAC開發(fā)資料分享
1、Rockchip USB Gadget UAC開發(fā)步驟本文檔提供 Rockchip 平臺基于 Linux 內(nèi)核的 USB Gadget UAC(
發(fā)表于 08-10 16:03
RK3288使用USB GADGET實(shí)現(xiàn)大容量存儲腳本
(){mount -t configfs none /sys/kernel/configmkdir /sys/kernel/config/usb_gadget/rockchip -m
發(fā)表于 11-18 16:33
求助,關(guān)于USB gadget安裝虛擬網(wǎng)口問題求解
1.make linux-menuconfig
USB support ---->
<*>USB Gadget Support ---->
發(fā)表于 09-01 06:14
PL2303 USB to Serial Adapter
The PL2303 USB to Serial adapter is your smart and convenient accessory forconnecting RS-23
發(fā)表于 10-15 17:58
?111次下載
Universal Serial Bus(USB) Devi
Universal Serial Bus Device Class Definition for Printing Devices
The Universal Serial Bus (USB
發(fā)表于 04-11 19:32
?16次下載
PL2303,Edition USB to Serial B
PL2303,Edition USB to Serial Bridge Controller:The PL-2303 operates as a bridge between one USB
發(fā)表于 09-19 07:59
?77次下載
[嵌入式linux]將linux板卡虛擬為USB網(wǎng)卡設(shè)備(Ethernet Gadget)
kernel menuconfig-> Device Drivers ->USB support -> USB Gadget Support 建議最好選成M,作為內(nèi)核驅(qū)動模塊,便于
發(fā)表于 11-02 11:36
?12次下載
AMD Xilinx Linux 2022.1 USB Gadget使用
有客戶使用Linux中的USB Gadget功能,把MPSoC器件做USB從設(shè)備
USB Gadget 應(yīng)用實(shí)例ADB實(shí)現(xiàn)
,定義了多個接口描述符,這是 APP 提出的請求。如果 Gadget 設(shè)備有足夠的端點(diǎn),那么就會在在 functionfs 跟目錄下創(chuàng)建出這些端點(diǎn),比如 ep1、ep2。 ADB 程序的調(diào)用關(guān)系如下
USB Gadget serial應(yīng)用實(shí)例(上)
1. 硬件體驗(yàn) 使用 Linux 自帶的 USB Gadget 驅(qū)動 /drivers/usb/gadget/legacy/serial.c
USB Gadget zero應(yīng)用實(shí)例程序
1. 編寫程序 1.1 編程思路 涉及的程序如下圖所示: PC 端基于 libusb 編寫應(yīng)用程序,開發(fā)板端直接使用 Linux 自帶的 USB Gadget 驅(qū)動 zero.c【/drivers
從硬件軟件角度理解Gadget框架
2. 從硬件軟件角度理解 Gadget 框架 USB 傳輸?shù)暮诵氖?endpoint,使用 endpoint 可以收發(fā)數(shù)據(jù)。在 endpoint 之上,就可以模擬 USB 串口、USB
評論