前面使用udev机制实现了U盘插拔状态检测,甚至后面与epoll机制结合,满足一些领域的需求,尤其是近似中断机制实现。
但是也有自己的局限性,首先,udev机制与usbip机制无法共存,其次,中断机制在网络传输中不如循环机制,最后在嵌入式开发中,udev检测所有U盘插拔状态有点冗余,单纯scan某个usb的设备节点,效率更高。
下面是一个通过scan特定usb设备节点方式检测U盘插拔检测,这里使用数组检测比直接指定数组下标来检测灵活一些。
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "scan_udisk.h"
#define MAX_UDISK_ACTIONACTION_SIZE (16)
#define MAX_UDISK_BUSIDBUSID_SIZE (16)
typedef enum
{
SCAN_UDISK_MODE_NONE = -1,
SCAN_UDISK_MODE_ADD,
SCAN_UDISK_MODE_REMOVE,
SCAN_UDISK_MODE_MAX
} SCAN_UDISK_MODE_ST;
int main(int argc, char *argv[])
{
char usbip_action[MAX_UDISK_ACTIONACTION_SIZE] = "";
char usbip_busid[MAX_UDISK_BUSIDBUSID_SIZE] = "";
int while_sleep_second = 1;
int ret = 1;
int run_cnt = 1;
int udisk_scan_mode = SCAN_UDISK_MODE_NONE;
printf("[%s +%d %s] \n", __FILE__, __LINE__, __func__);
while(1)
{
memset(usbip_action, '\0', MAX_UDISK_ACTIONACTION_SIZE);
memset(usbip_busid, '\0', MAX_UDISK_BUSIDBUSID_SIZE);
printf("[%s +%d %s] run_cnt=%d\n", __FILE__, __LINE__, __func__, run_cnt++);
ret = scan_udisk_mode(usbip_action, usbip_busid);
if(1 == ret)
{
if(SCAN_UDISK_MODE_ADD == udisk_scan_mode)
{
printf("[%s +%d %s] scan udisk add twice:usbip_action=%s usbip_busid=%s\n", __FILE__, __LINE__, __func__, usbip_action, usbip_busid);
}
else
{
udisk_scan_mode = SCAN_UDISK_MODE_ADD;
printf("[%s +%d %s] scan udisk add successful:usbip_action=%s usbip_busid=%s\n", __FILE__, __LINE__, __func__, usbip_action, usbip_busid);
}
}
else if(2 == ret)
{
if(SCAN_UDISK_MODE_REMOVE == udisk_scan_mode)
{
printf("[%s +%d %s] scan udisk remove twice:usbip_action=%s usbip_busid=%s\n", __FILE__, __LINE__, __func__, usbip_action, usbip_busid);
}
else
{
udisk_scan_mode = SCAN_UDISK_MODE_REMOVE;
printf("[%s +%d %s] scan udisk remove successful:usbip_action=%s usbip_busid=%s\n", __FILE__, __LINE__, __func__, usbip_action, usbip_busid);
}
}
else
{
printf("[%s +%d %s] can not scan udisk mode then continute scan\n", __FILE__, __LINE__, __func__);
}
sleep(while_sleep_second);
}
return 0;
}
scan_udisk.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include "scan_udisk.h"
#define MAIN_VERSION 0
#define MINIOR_VERSION 1
#define REVISION_VERSION 1
#define CONSTRUCTION_VERSION 1
#define VERSION_STR(s) #s
#define SC_VERSION(a, b, c, d) ("loop scan udisk " VERSION_STR(a) "." VERSION_STR(b) "." VERSION_STR(c) "." VERSION_STR(d))
const char g_libVersion[] = SC_VERSION(MAIN_VERSION, MINIOR_VERSION, REVISION_VERSION, CONSTRUCTION_VERSION);
#define ELF_NUM_VERSION ((MAIN_VERSION<<24) | (MINIOR_VERSION<<16) | (REVISION_VERSION<<8) | (CONSTRUCTION_VERSION<<0))
int get_elf_num_version(void)
{
//printf("[%s +%d %s] ELF_NUM_VERSION=0x%x\n", __FILE__, __LINE__, __func__, ELF_NUM_VERSION);
return ELF_NUM_VERSION;
}
char *get_elf_str_version(void)
{
//printf("[%s +%d %s] (char *)g_libVersion=%s\n", __FILE__, __LINE__, __func__, (char *)g_libVersion);
return (char *)g_libVersion;
}
#define MAX_SYSTEM_CMD_STR_SIZE (64)
#define MAX_UDISK_NAMES_NUM (32)
#define MAX_UDISK_NAMES_SIZE (16)
#define DEFAULT_UDISK_CNT (4)
int g_udisk_plug_flag = 0;
char udisk_add_name[MAX_UDISK_NAMES_SIZE];
char dt450_action_busid_dir[] = "/sys/devices/pci0000:00/0000:00:14.0/usb2";
char g_udisk_names[MAX_UDISK_NAMES_NUM][MAX_UDISK_NAMES_SIZE] = {};
char g_default_udisk_names[MAX_UDISK_NAMES_NUM][MAX_UDISK_NAMES_SIZE] = {
"ep_00",
"power",
"2-8",
"2-7"
};
int check_name_in_array(char *name, int default_cnt)
{
int j = 0;
for(j = 0; j < default_cnt; j++)
{
//printf("[%s +%d %s] name=%s g_default_udisk_names[j=%d]=%s\n", __FILE__, __LINE__, __func__, name, j, g_default_udisk_names[j]);
if(0 == strcmp(name, g_default_udisk_names[j]))
{
//printf("[%s +%d %s] g_default_udisk_names[j=%d]=%s\n", __FILE__, __LINE__, __func__, j, g_default_udisk_names[j]);
break;
}
}
//printf("[%s +%d %s] j=%d default_cnt=%d\n", __FILE__, __LINE__, __func__, j, default_cnt);
if(j == default_cnt)
{
return -1;
}
else
{
return 0;
}
}
int get_names_from_array(int default_cnt, int get_cnt)
{
int i = 0;
int flag = 0;
//printf("[%s +%d %s] default_cnt=%d get_cnt=%d\n", __FILE__, __LINE__, __func__, default_cnt, get_cnt);
for(i = 0; i < get_cnt; i++)
{
if(0 != check_name_in_array(g_udisk_names[i], default_cnt))
{
flag = 1;
break;
}
}
if(1 == flag)
{
//printf("[%s +%d %s] i=%d\n", __FILE__, __LINE__, __func__, i);
return i;
}
return -1;
}
static int get_dir_filenames(char *dir_fullname)
{
DIR *dir = opendir(dir_fullname);
if (dir == NULL) {
perror("opendir");
return 0;
}
struct dirent *entry;
int count = 0;
//printf("[%s +%d %s] count=%d DEFAULT_UDISK_CNT=%d\n", __FILE__, __LINE__, __func__, count, DEFAULT_UDISK_CNT);
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
//printf("[%d] entry->d_name[%d]=%s g_udisk_plug_flag=%d\n", __LINE__, count, entry->d_name, g_udisk_plug_flag);
if((MAX_UDISK_NAMES_NUM > count) && (2 < strlen(entry->d_name)) && (6 > strlen(entry->d_name)))
{
//printf("[%d] entry->d_name[%d]=%s g_udisk_plug_flag=%d\n", __LINE__, count, entry->d_name, g_udisk_plug_flag);
strcpy(g_udisk_names[count], entry->d_name);
count++;
}
if(MAX_UDISK_NAMES_NUM <= count)
{
printf("[%d] MAX_UDISK_NAMES_NUM(%d) <= count(%d)\n", __LINE__, MAX_UDISK_NAMES_NUM, count);
}
}
}
//printf("[%s +%d %s] count=%d DEFAULT_UDISK_CNT=%d\n", __FILE__, __LINE__, __func__, count, DEFAULT_UDISK_CNT);
closedir(dir);
return count;
}
int scan_udisk_mode(char *action, char *busid)
{
int count = 0;
//printf("[%s +%d %s] scan_udisk_mode action=%s usbip_busid=%s\n", __FILE__, __LINE__, __func__, action, busid);
count = get_dir_filenames(dt450_action_busid_dir);
//printf("[%s +%d %s] DEFAULT_UDISK_CNT=%d count=%d\n", __FILE__, __LINE__, __func__, DEFAULT_UDISK_CNT, count);
if((DEFAULT_UDISK_CNT + 1) == count)
{
//printf("[%s +%d %s] scan_udisk_mode udisk_add_name=%s g_udisk_plug_flag=%d\n", __FILE__, __LINE__, __func__, udisk_add_name, g_udisk_plug_flag);
count = get_names_from_array(DEFAULT_UDISK_CNT, count);
if(-1 == count)
{
return 0;
}
strcpy(action, "add");
strcpy(busid, g_udisk_names[count]);
strcpy(udisk_add_name, g_udisk_names[count]);
g_udisk_plug_flag = 1;
//printf("[%s +%d %s] add action=%s usbip_busid=%s\n", __FILE__, __LINE__, __func__, action, busid);
//printf("[%s +%d %s] add udisk_add_name=%s g_udisk_plug_flag=%d\n", __FILE__, __LINE__, __func__, udisk_add_name, g_udisk_plug_flag);
return 1;
}
//printf("[%s +%d %s] scan_udisk_mode udisk_add_name=%s g_udisk_plug_flag=%d\n", __FILE__, __LINE__, __func__, udisk_add_name, g_udisk_plug_flag);
if(DEFAULT_UDISK_CNT != get_dir_filenames(dt450_action_busid_dir))
{
printf("[%s +%d %s] scan_udisk_mode udisk_add_name=%s g_udisk_plug_flag=%d\n", __FILE__, __LINE__, __func__, udisk_add_name, g_udisk_plug_flag);
return 0;
}
if((0 != strlen(udisk_add_name)) && (1 == g_udisk_plug_flag))
{
strcpy(action, "remove");
strcpy(busid, udisk_add_name);
g_udisk_plug_flag = 0;
//printf("[%s +%d %s] remove udisk_add_name=%s g_udisk_plug_flag=%d\n", __FILE__, __LINE__, __func__, udisk_add_name, g_udisk_plug_flag);
return 2;
}
return 0;
}
scan_udisk.h
#pragma once
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
int get_elf_num_version(void);
char *get_elf_str_version(void);
int scan_udisk_mode(char *action, char *busid);
#ifdef __cplusplus
}
#endif
Makefile
# 设置编译器
CC := gcc
#CFLAGS = -Wall -g -O3 -DUSED_FFMPEG -std=c++11 -lpthread -lavcodec -lavutil -lavformat -lswscale -lshallowcompress -L. -I.
#CFLAGS = -Wall -g -O3 -std=c++11 -lpthread -lavcodec -lavutil -lavformat -lswscale -lcompress_transmit -L. -I.
CFLAGS = -Wall -g -O0 -lpthread -L. -I.
# 设置生成的目标文件
current_dir_name := $(notdir $(shell pwd))
TARGET := $(current_dir_name).elf
# 获取所有的.c文件
SRCS := $(wildcard *.c)
# 获取所有的.h文件
DEPS := $(wildcard *.h)
# 将.c文件编译成.o文件
OBJS := $(SRCS:.c=.o)
# 编译规则
$(TARGET): $(OBJS)
$(CC) -o $@ $(OBJS) $(CFLAGS)
# 依赖规则
%.o: %.c $(DEPS)
$(CC) -c $< -o $@ $(CFLAGS)
# 清理规则
clean:
rm -f $(TARGET) $(OBJS)
build.sh
#!/bin/bash
currentDir=${PWD}
echo "currentDir=" ${currentDir}
current_basedir=$(basename $currentDir)
echo "rm =" ${current_basedir}
ELFNAME=".elf"
ELFNAME=${current_basedir}${ELFNAME}
echo "ELFNAME=" ${ELFNAME}
if [ -e ${ELFNAME} ]; then
rm ${ELFNAME}
fi
make clean;make
#./${ELFNAME}
#./$ELFNAME 1 inputParameterFIle.txt 0
#sudo ./$ELFNAME 192.168.70.54 172.17.5.55 0
sudo ./$ELFNAME 192.168.70.54 192.168.70.64 0
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。