问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C语言如何查找串口列表

创作时间:
作者:
@小白创作中心

C语言如何查找串口列表

引用
1
来源
1.
https://docs.pingcode.com/baike/991486

在C语言中查找串口列表是进行串口通信开发的基础工作。本文将详细介绍三种主要方法:读取系统文件、调用系统API、使用第三方库。其中,调用系统API是最常用的方法,本文将重点介绍Windows和Linux系统中的实现方式。

一、Windows系统中的串口查找

1. SetupAPI函数

在Windows系统中,SetupAPI提供了一组函数,用于枚举和获取设备信息。SetupAPI可以帮助我们列出所有的串口设备。以下是一个简单的实现示例:

#include <windows.h>
#include <setupapi.h>
#include <stdio.h>
#include <initguid.h>
#include <devguid.h>
#include <tchar.h>

void enumerateSerialPorts() {
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i;

    // Create a HDEVINFO with all present devices.
    hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        // Insert error handling here.
        return;
    }

    // Enumerate through all devices in Set.
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) {
        DWORD DataT;
        LPTSTR buffer = NULL;
        DWORD buffersize = 0;

        // Call function with null to begin with, then use the returned buffer size to allocate the buffer. Keep calling until success or an unknown failure.
        while (!SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &DeviceInfoData,
            SPDRP_FRIENDLYNAME,
            &DataT,
            (PBYTE)buffer,
            buffersize,
            &buffersize)) {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                // Change the buffer size.
                if (buffer) LocalFree(buffer);
                buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);
            } else {
                // Insert error handling here.
                break;
            }
        }
        printf("Device: %s\n", buffer);
        if (buffer) LocalFree(buffer);
    }
    SetupDiDestroyDeviceInfoList(hDevInfo);
}

2. 解释和扩展

上述代码通过SetupAPI函数列出所有串口设备,并打印其友好名称。首先,使用SetupDiGetClassDevs函数获取所有当前存在的串口设备信息集合;然后,通过SetupDiEnumDeviceInfo函数枚举每个设备,并使用SetupDiGetDeviceRegistryProperty获取设备的友好名称。最后,清理分配的资源。

扩展:可以添加更多的设备属性查询,例如设备描述、硬件ID等,以获取更详细的串口信息。

二、Linux系统中的串口查找

1. 读取/dev目录

在Linux系统中,串口设备通常以/dev/ttyS*/dev/ttyUSB*命名。我们可以通过读取/dev目录来查找这些设备。以下是一个简单的实现示例:

#include <stdio.h>
#include <dirent.h>
#include <string.h>

void enumerateSerialPorts() {
    struct dirent *entry;
    DIR *dp = opendir("/dev");
    if (dp == NULL) {
        perror("opendir");
        return;
    }
    while ((entry = readdir(dp))) {
        if (strncmp(entry->d_name, "ttyS", 4) == 0 || strncmp(entry->d_name, "ttyUSB", 6) == 0) {
            printf("Device: /dev/%s\n", entry->d_name);
        }
    }
    closedir(dp);
}

2. 解释和扩展

上述代码通过读取/dev目录并匹配设备名称来查找串口设备。首先,使用opendir函数打开/dev目录;然后,通过readdir函数读取目录中的每个条目,并使用strncmp函数匹配设备名称。最后,关闭目录。

扩展:可以通过读取设备的属性文件(如/sys/class/tty/ttyS*)来获取更详细的信息,例如设备的硬件地址、驱动信息等。

三、使用第三方库

1. Libserialport库

Libserialport是一个跨平台的串口库,提供了简单且统一的API,用于列出和操作串口设备。以下是一个简单的实现示例:

#include <libserialport.h>
#include <stdio.h>

void enumerateSerialPorts() {
    struct sp_port ports;
    int result = sp_list_ports(&ports);
    if (result == SP_OK) {
        for (int i = 0; ports[i] != NULL; i++) {
            printf("Device: %s\n", sp_get_port_name(ports[i]));
        }
    } else {
        printf("No serial devices found.\n");
    }
    sp_free_port_list(ports);
}

2. 解释和扩展

上述代码通过Libserialport库列出所有串口设备,并打印其名称。首先,使用sp_list_ports函数获取所有串口设备的列表;然后,通过sp_get_port_name函数获取每个设备的名称。最后,释放分配的资源。

扩展:可以使用Libserialport库提供的其他函数来获取更多设备信息,例如设备的描述、硬件ID、波特率等。

四、总结与推荐

总结:查找串口列表的方法主要包括读取系统文件、调用系统API和使用第三方库。每种方法都有其优缺点,开发者可以根据具体需求选择适合的方法。

推荐:对于跨平台开发,推荐使用Libserialport库,因为它提供了统一的接口,简化了开发过程。如果仅针对Windows系统开发,可以使用SetupAPI函数;如果仅针对Linux系统开发,可以读取/dev目录或使用系统提供的API。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号