LINUX USB 多串口通讯之二: 动态获取当前所有 USB 串口设备通道名称

目的:读取 /dev/ 目录下 USB 串口设备名称

提醒: 因 USB 接口松动或其它原因,会导致 USB 设备于 linux 系统中的通道号会改变! 如正确处理异常退出,则 USB 通道号不会增加

硬件: RPI 3B+, NORDIC nRF52840 USB Dongle

系统: Linux raspberrypi 4.19.118-v7+  

个人收获: 重写此模块,再次体会严谨错误处理、功能解藕~~


文件: ttyacm-check.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>

#define DIR_READ_SLEEP_INTERVAL 5
#define TTYACM_NAME_LEN         15

static DIR              *dir;
static struct dirent    *dev_file;

static const char dev_dir[]     = "/dev/";
static const char dev_check[]   = "ttyACM";

void *ttyacm_check(void *p)
{
    char tmp_dev[TTYACM_NAME_LEN];

    while ( 1 )
    {

        if ( (dir=opendir(dev_dir)) == NULL )
        {
            perror( strerror(errno) );
            pthread_exit( &errno );
        }

        errno = 0;
        while ( (dev_file = readdir(dir)) != NULL )
        {
            if ( strstr(dev_file->d_name,dev_check) != NULL )   // get the USB-ttyACM channel
            {
                memset( tmp_dev,0x00,TTYACM_NAME_LEN );
                strcat( tmp_dev,dev_dir );
                strcat( tmp_dev,dev_file->d_name );
                fprintf( stdout,"GOT USB: %s\n",tmp_dev );
        //      ttyacm_channel_operation( tmp_dev );
            }
            errno = 0;
            // signal to normal exit
        }

        if ( errno )
        {
            perror( strerror(errno) );

            if ( closedir(dir) )
            {
                perror( strerror(errno) );
            }

            pthread_exit( &errno );
        }

        if ( closedir(dir) )
        {
            perror( strerror(errno) );
            pthread_exit( &errno );
        }

        fprintf( stdout,"%s(),%s",__FUNCTION__,"circle read dir /dev/.\n" );
        sleep(  DIR_READ_SLEEP_INTERVAL );
    }

     // ?? normal exit by signal ..

    pthread_exit( 0 );
}



测试主文件

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <error.h>
#include <string.h>

#include "chk-ttyacm.h"


int main( int argc,char * argv[] )
{
    pthread_t   tid_rx_ttyacm;

    ttyacm_tid_init();
    int err = pthread_create( &tid_rx_ttyacm,NULL,ttyacm_check,NULL );
    if ( err )
    {
        fprintf( stderr,"%s(): %s\n",__FUNCTION__,strerror(err) );
        exit(1);
    }

    pthread_join( tid_rx_ttyacm,NULL );

    exit(0);

}

Makefile 文件

CC      = gcc
CFLAGS  += -c -Wall -g
OBJS    = usb-ttyacm-communication.o ttyacm-check.o

ttyacm:$(OBJS)
    $(CC) $^ -lpthread -o $@

*.o:*.c
    $(CC) $(CFLAGS) $^

.PHONY:clean
clean:
    $(RM) $(OBJS) ttyacm


相关技术扩展

DIR 结构体

struct __dirstream
   {
    void *__fd;
    char *__data;
    int __entry_data;
    char *__ptr;
    int __entry_ptr;
    size_t __allocation;
    size_t __size;
    __libc_lock_define (, __lock)
   };
typedef struct __dirstream DIR;

dirent 结构体

struct dirent
{
  long d_ino; /* inode number 索引节点号 */
    off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
    unsigned short d_reclen; /* length of this d_name 文件名长 */
    unsigned char d_type; /* the type of d_name 文件类型 */
    char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}

d_type 文件类型
enum
{
    DT_UNKNOWN = 0,         //未知类型
# define DT_UNKNOWN DT_UNKNOWN
    DT_FIFO = 1,            //管道
# define DT_FIFO DT_FIFO
    DT_CHR = 2,             //字符设备
# define DT_CHR DT_CHR
    DT_DIR = 4,             //目录
# define DT_DIR DT_DIR
    DT_BLK = 6,             //块设备
# define DT_BLK DT_BLK
    DT_REG = 8,             //常规文件
# define DT_REG DT_REG
    DT_LNK = 10,            //符号链接
# define DT_LNK DT_LNK
    DT_SOCK = 12,           //套接字
# define DT_SOCK DT_SOCK
    DT_WHT = 14             //链接
# define DT_WHT DT_WHT
};

Bash shell 文件: 间隔 10 秒, 获取当前所有的 USB 通道 (/dev/ttyACM*),并存储于 log-ttyACM.txt

#!/bin/bash

times=0
while true
do
    times=`expr $times + 1`
    echo -ne "item: $times, "   >> log-ttyACM.txt
    date "+%Y-%d-%d %H:%M:%S"   >> log-ttyACM.txt
    ls /dev/ttyACM*             >> log-ttyACM.txt
    sleep 5
done

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值