Linux USB U盘热插拔挂载和卸载

2023-11-09

一、硬件平台

        1、  控制器:MT7620(A9内核)

        2、  RTC芯片:MCP7940

二、软件平台

       1、开发环境:Ubuntu12.04 

       2、SDK内核包:MT7620 SDK软件开发包(MediaTek_ApSoC_SDK_4320_20150414.tar.bz2)

       3、内核版本:linux-2.6.36.x

三、参考资料

      《MTK_APSoC_SDK_User_Manual.pdf》。

      下载链接:http://download.csdn.net/detail/xhoufei2010/9478004

四、USB U盘驱动简介

        USB Mass Storage是一类USB存储设备,这些设备包括USB磁盘、USB硬盘、USB磁带机、USB光驱、U盘、记忆棒、智能卡和一些USB摄像头等,这类设备由USB协议支持。

       对于USB的U盘驱动,已经非常完善,大家只需要简单地配置一下内核,开启U盘的功能即可。

五、U盘配置

       5.1 取消内核自动挂载功能

        由于Linux 内核包默认会自动挂载,且内核初始化的过程中,挂载出现在创建USB节点之前,经常出现自动挂载导致内核崩溃,故取消内核挂载,自己监听USB的热插拔,然后挂载。

        1.开启设置busybox

        进入到内核开发包目录 cd /home/kernel/source

        输入命令 make menuconfig

        Kernel/Library/Defaults Selection  --->Customize Busybox Settings ,选中该选项,如图5-1所示,设置完成之后,保存退出。

        

                                                          图5-1 设置Busybox

       2. 取消USB自动挂载/卸载功能

       在图5-1保存设置之后,会自动跳转到busybox的设置界面,在界面中,进入Linux System Utilities,取消掉Support command execution at device addition/removal 选项,如图5-2所示。

                                                       图5-2 取消USB的自动挂载/卸载

       5.2 开启U盘功能

        在linux-2.6.36.x中,输入命令make menuconfig,进入配置

        Linux Kernel Configuration ---> Device Drivers  ---> USB support ,在配置中,选中USB Mass Storage support,如图5-3所示。

                                                         图5-3 开启USB U盘支持

六、监听USB热插拔程序

       6.1 说明

        对于USB的热插拔,实际就是建立一个socket,采用socket监听USB的插拔信息。

        当监听到USB插入信息,且发现在 /dev目录下,存在 sda1或者sdb1分区(有时候分区节点为其他名称,根据实际分区修改分区的名称判断条件)的时候,就挂载USB分区到 /tmp/usb目录下。

        当监听到USB拔出信息,则卸载 /tmp/usb目录。

        6.2 usb控制器头文件,UsbController.h。

/**
 * @addtogroup module_genericGateway
 * @{
 */

/**
 * @file
 * @brief USB控制器,管理USB插拔及挂载。
 * @details 
 * @version 1.0.0
 * @author sky.houfei
 * @date 2016-3-18
 */


#ifndef _USB_USBCONTROLLER_H_
#define _USB_USBCONTROLLER_H_


#ifdef __cplusplus
extern "C" {
#endif

//******************************************************************************
#include <stdbool.h>


//******************************************************************************
/**
 * @brief USB控制器初始化,准备USB的监听服务。
 * @return ret, int,如果初始化成功,则返回0,否则为-1.
 */
int UsbController_Init(void);


/**
 * @brief USB设备挂载监听。
 * @details 如果USB之前没有挂载且当前可以挂载,则挂载。
 * \n 如果USB之前挂载成功,此时设备已经被拔出,则卸载。
 */
void UsbController_MountMonitor(void);


/**
* @brief 是否已经挂载成功。
* @return bool s_isMounted, USB设备挂载成功,则返回 true, 否则返回false。
*/
bool UsbController_IsMounted(void);


#ifdef __cplusplus
}
#endif


#endif  // _USB_USBCONTROLLER_H_

/** @} */

       6.3 usb控制器监听热插拔c文件, UsbController.c

/**
 * @addtogroup module_genericGateway
 * @{
 */

/**
 * @file
 * @brief USB控制器,管理USB插拔及挂载。
 * @details 
 * @version 1.0.0
 * @author sky.houfei
 * @date 2016-3-18
 */

//******************************************************
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <sys/un.h> 
#include <sys/ioctl.h> 
#include <sys/socket.h> 
#include <linux/types.h> 
#include <linux/netlink.h> 
#include <errno.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include "UsbController.h"

//******************************************************
#define UEVENT_BUFFER_SIZE 2048 

//******************************************************
static bool isUsbConnected = false;
static int s_hotplugSock = 0;
static bool s_isMounted = false;

 //******************************************************
static void* UsbController_HotPlugMonitor(void);  // USB监听,监听USB的插拔事件,并进行挂载和卸载USB设备。


//******************************************************
static int UsbController_HotplugSockInit(void) 
{ 
    const int buffersize = 1024; 
    int ret; 

    struct sockaddr_nl snl; 
    bzero(&snl, sizeof(struct sockaddr_nl)); 
    snl.nl_family = AF_NETLINK; 
    snl.nl_pid = getpid(); 
    snl.nl_groups = 1; 

    int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); 
    if (s == -1)  
    { 
        perror("socket"); 
        return -1; 
    } 
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); 

    ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); 
    if (ret < 0)  
    { 
        perror("bind"); 
        close(s); 
        return -1; 
    } 

    return s; 
} 


/**
 * @brief USB控制器初始化,准备USB的监听服务。
 * @return ret, int,如果初始化成功,则返回0,否则为-1.
 */
int UsbController_Init(void)
{
	const int buffersize = 1024; 
    int ret; 
	pthread_t id;

    struct sockaddr_nl snl; 
    bzero(&snl, sizeof(struct sockaddr_nl)); 
    snl.nl_family = AF_NETLINK; 
    snl.nl_pid = getpid(); 
    snl.nl_groups = 1; 

	if (access("/dev/sda1", 0) == 0)
	{
		// USB已经连接成功
		isUsbConnected = true;
	}


	UsbController_MountMonitor();	// 首次检查USB是否挂载
    s_hotplugSock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); 
    if (s_hotplugSock == -1)  
    { 
        perror("socket error"); 
        return -1; 
    } 
    setsockopt(s_hotplugSock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); 

    ret = bind(s_hotplugSock, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); 
    if (ret < 0)  
    { 
        perror("bind error"); 
        close(s_hotplugSock); 
        return -1; 
    } 

	ret = pthread_create(&id, NULL, UsbController_HotPlugMonitor, NULL);  
    if (ret != 0)   
    {  
        printf("pthread_create error = %d\n", ret);  
    }  

	return 0;
}


/**
 * @brief USB监听热插拔,监听USB的插拔事件,并进行挂载和卸载USB设备。
 */
static void* UsbController_HotPlugMonitor(void)
{ 
	pthread_detach(pthread_self());
	char *result = NULL;
    char buf[UEVENT_BUFFER_SIZE * 2] = {0};     //  Netlink message buffer  
	
	while (1)
	{
	    recv(s_hotplugSock, &buf, sizeof(buf), 0); // 获取 USB 设备的插拔会出现字符信息,
		result = strtok(buf, "@");                // 查看 USB的插入还是拔出信息
		if (result != NULL)
		{
			if ((strcmp(result, "add") == 0))
			{
				if (isUsbConnected == false)
				{
					isUsbConnected = true;
				}

			}
			else if ((strcmp(result, "remove") == 0))
			{
				if (isUsbConnected == true)
				{
					isUsbConnected = false;
				}
			}
		}
		memset(buf, 0, UEVENT_BUFFER_SIZE * 2);
	}
}


/**
* @brief 是否连接成功。
* @return bool isConnnected, USB设备连接成功,则返回 true, 否则返回false。
*/
static bool UsbController_IsConnected(void)
{
	return isUsbConnected;
}


/**
 * @brief 挂载文件系统。
 * @details 创建文件夹 /tmp/usb,将USB设备挂在在该目录下。尝试挂在 sda1和sdb1,如果都挂在失败,则认为挂载失败。
 * @return 如果挂载成功,则返回0,否则为-1。
 */
static int UsbController_MountFileSystem(void)
{
	const char directory[] = "/tmp/usb";
	int ret = 0;

	printf("Try to mount the usb device\n");
	// 检测是否存在文件夹
	if (access(directory, 0) == -1)
	{
		// 文件夹不存在
		if (mkdir(directory, 0777)) // 创建文件夹
        {
            printf("creat directory(%s) failed!!!", directory);
			return -1;
        }
	}

	if (system("mount -t vfat /dev/sda1  /tmp/usb") < 0)  // 挂载USB的文件系统
	{
		if (system("mount -t vfat /dev/sdb1  /tmp/usb") < 0)
		{
			return -1;
		}
	}

	return 0;
}


/**
 * @brief 卸载文件系统。
 * @return 如果挂载成功,则返回0,否则为-1。
 */
static int UsbController_UnmountFileSystem(void)
{
	int ret = 0;

	if (system("umount /tmp/usb") < 0)  // 挂载USB的文件系统
	{
		printf("Umount the usb device failed\n");
		ret =  -1;
	}

	printf("Umount the usb device success\n");
	return ret;
}


/**
 * @brief USB设备是否可以挂载。
 * @details 设备处于连接状态,且在/dev/目录下创建了sda1或者sdb1节点,则视为可以挂载。
 * @return 如果可以挂在,则返回true,否则为false。
 */
static bool UsbController_IsMountable(void)
{
	bool isMountable = false;
	bool isPartitionExist = false;

	if (access("/dev/sda1", 0) == 0 || access("/dev/sdb1", 0) == 0)
	{
		// 存在分区 /dev/sda1 或者 /dev/sdb1
		isPartitionExist = true;
	}

	if (isUsbConnected == true && isPartitionExist == true)
	{
		isMountable = true;
	}

	return isMountable;
}


/**
 * @brief USB设备挂载监听。
 * @details 如果USB之前没有挂载且当前可以挂载,则挂载。
 * \n 如果USB之前挂载成功,此时设备已经被拔出,则卸载。
 */
void UsbController_MountMonitor(void)
{
	if (s_isMounted == false && UsbController_IsMountable() == true)
	{
		// 之前没有挂载且当前可以挂载,挂载文件系统
		if (0 == UsbController_MountFileSystem())
		{
			printf("Mount success\n");
			s_isMounted = true;
		}
	}
	else if (s_isMounted == true && UsbController_IsConnected() == false)
	{
		// 之前挂载成功,此时设备已经被拔出,卸载设备
		if (0 == UsbController_UnmountFileSystem())
		{
			s_isMounted = false;
		}
	}
}


/**
* @brief 是否已经挂载成功。
* @return bool s_isMounted, USB设备挂载成功,则返回 true, 否则返回false。
*/
bool UsbController_IsMounted(void)
{
	return s_isMounted;
}


/** @} */

       6.4 主函数 main.c

#include <stdio.h>
#include "usb/UsbController.h"

int main(int argc, char** argv)
{
	int secondCount = 0;
	UsbController_Init();
	
	
	while (1)
	{
		sleep(1);
		secondCount++;
		if (secondCount >= 5)
		{
			secondCount = 0;
			UsbController_MountMonitor();
		}
	}
}

    6.5 测试结果

    6.5.1 USB 插入

     1. 查看USB设备

     # ls /dev/sd*
     /dev/sda1  /dev/sda

     2. 插入设备打印信息

# [  226.340000] usb 1-1: new high speed USB device using rt3xxx-ehci and address 6
[  226.490000] scsi4 : usb-storage 1-1:1.0
[  227.520000] scsi 4:0:0:0: Direct-Access     Kingston DataTraveler 2.0 1.00 PQ: 0 ANSI: 4
[  227.540000] sd 4:0:0:0: [sda] 30310400 512-byte logical blocks: (15.5 GB/14.4 GiB)
[  227.550000] sd 4:0:0:0: [sda] Write Protect is off
[  227.560000] sd 4:0:0:0: [sda] Assuming drive cache: write through
[  227.570000] sd 4:0:0:0: [sda] Assuming drive cache: write through
[  227.580000]  sda: sda1
[  227.590000] sd 4:0:0:0: [sda] Assuming drive cache: write through
[  227.590000] sd 4:0:0:0: [sda] Attached SCSI removable disk
Try to mount the usb device
[  232.110000] FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Mount success

     3. 查看USB挂载后的文件系统

     查看之后,可以正常获取到U盘的内容。

     # ls /tmp/usb/
test       software   computime

         6.5.2 USB 拔出

      1. USB拔出之后,打印信息:

      # [  789.230000] usb 1-1: USB disconnect, address 6
      Umount the usb device success

      2. 查看文件系统

      查看,发现/tmp/usb目录的内容已经被卸载,正常卸载。

      # ls /tmp/usb/
      # 
      # 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux USB U盘热插拔挂载和卸载 的相关文章

  • 如何在 Vim 中突出显示 Bash 脚本?

    我的 Vim 编辑器自动突出显示 PHP 文件 vim file php HTML 文件 vim file html 等等 但是当我输入 vim file在里面写一个Bash脚本 它不会突出显示它 我如何告诉 Vim 将其突出显示为 Bas
  • 如何通过ssh获取远程命令的退出代码

    我正在通过 ssh 从远程计算机运行脚本 ssh some cmd my script 现在 我想在本地计算机上存储 shell 脚本的退出状态 我该怎么做 假设没有任何问题ssh其本身 其退出状态是在远程主机上执行的最后一个命令的退出状态
  • 使用脚本检查 git 分支是否领先于另一个分支

    I have branch1 and branch2我想要某种 git branch1 isahead branch2 这将显示如果branch1已承诺branch2没有 也可能指定这些提交 我无法检查差异原因branch2 is在之前br
  • Vagrant 遇到问题 - “404 - 未找到”

    我正在尝试使用 Vagrant 制作一个 LAMP 盒子 有人告诉我它使用起来非常简单 我对网络和虚拟机完全陌生 对 Linux Ubuntu 的经验也很少 我目前已尝试按照官方文档页面上的教程进行操作 http docs vagrantu
  • 在 scapy 中通过物理环回发送数据包

    我最近发现了 Scapy 它看起来很棒 我正在尝试查看 NIC 上物理环回模块 存根上的简单流量 但是 Scapy sniff 没有给出任何结果 我正在做的发送数据包是 payload data 10 snf sniff filter ic
  • 在ubuntu中打开spyder

    我想在ubuntu中打开spyder Python IDE 通常我会在 shell 中编写 spyder 它会打开spyder IDE 现在 当我在shell中编写spyder时 它只是换行 什么也没有发生 类似于按 enter 我如何找回
  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • 如何从 Bash 命令行在后台 Vim 打开另一个文件?

    我正在从使用 Gvim 过渡到使用控制台 Vim 我在 Vim 中打开一个文件 然后暂停 Vim 在命令行上运行一些命令 然后想返回到 Vim Ctrl Z 在正常模式下 暂停 Vim 并返回到控制台 fg可用于将焦点返回到 Vim job
  • Docker忽略limits.conf(试图解决“打开文件太多”错误)

    我正在运行一个 Web 服务器 该服务器正在处理数千个并发 Web 套接字连接 为了实现这一点 在 Debian linux 我的基本镜像是 google debian wheezy 在 GCE 上运行 上 打开文件的默认数量设置为 100
  • bash while 循环的布尔表达式中的 -lt 意味着什么?

    我猜测它代表小于基于输出 但是我在哪里可以找到有关此语法的文档 bin bash COUNTER 0 while COUNTER lt 10 do echo The counter is COUNTER let COUNTER COUNTE
  • /sys/device/ 和 dmidecode 报告的不同 CPU 缓存大小

    我正在尝试获取系统中不同缓存级别的大小 我尝试了两种技术 a 使用 sys device 中的信息 这是输出 cat sys devices system cpu cpu0 cache index1 size 32K cat sys dev
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent
  • vmsplice() 和 TCP

    在原来的vmsplice 执行 有人建议 http lwn net Articles 181169 如果您的用户态缓冲区是管道中可容纳的最大页面数的 2 倍 则缓冲区后半部分成功的 vmsplice 将保证内核使用缓冲区的前半部分完成 但事
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • SSH,运行进程然后忽略输出

    我有一个命令可以使用 SSH 并在 SSH 后运行脚本 该脚本运行一个二进制文件 脚本完成后 我可以输入任意键 本地终端将恢复到正常状态 但是 由于该进程仍在我通过 SSH 连接的计算机中运行 因此任何时候它都会登录到stdout我在本地终
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下
  • 我们真的应该使用 Chef 来管理 sudoers 文件吗?

    这是我的问题 我担心如果 Chef 破坏了 sudoers 文件中的某些内容 可能是 Chef 用户错误地使用了说明书 那么服务器将完全无法访问 我讨厌我们完全失去客户的生产服务器 因为我们弄乱了 sudoers 文件并且无法再通过 ssh

随机推荐

  • 【Qt编程笔记】采用遍历方式删除QList中全部元素的方法

    QList类是Qt提供的链表模板类 在日常工作和学习中经常会用到 虽然QList操作十分便利 但是在用遍历方式删除全部元素时很可能会因为疏忽造成没有将元素全部删除 从而给程序留下隐患 下面小结一下采用遍历方式删除QList中全部元素的方法
  • 由于找不到d3dx9_43.dll,有什么可靠的修复方法?

    由于找不到d3dx9 43 dll 无法继续执行代码 这种情况大家是否有遇见过 其实就算没遇到过 大家应该也有遇到别的dll文件丢失吧 道理都一样 都是dll文件丢失 我们只需要把它给修复就可以了 不同的dll只是负责的功能不一样而已 下面
  • Css层叠优先级只会这两招还远远不够

    作为一个玩前端的 ps软件中的图层都知道吧 多个图层层叠就可以组成丰富多彩的图片 所以图层就有层叠顺序了 Css的层叠原理也是差不多 只不过Css是通过多个盒子层叠形成丰富多彩的图片 Css层叠优先级设置不就是z index和 import
  • linux 测试网络连通性方法

    一 telnet 方法 telnet 协议是 TCP IP 协议族中的一员 是 Internet 远程登陆服务的标准协议和主要方式 它为用户提供了在本地计算机上完成远程主机工作的能力 因此我们可以使用telnet 来测试远程机器的连通性 t
  • VMware安装RHEL 8.2(红帽)

    一 创建虚拟机 打开VMware 点击 创建新的虚拟机 点击自定义 下一步 选择兼容性 15 x 兼容性选VMware的版本 稍后安装操作系统 选择镜像对应的操作系统类型及版本 系统镜像按自己准备的选择即可 自定义虚拟机名称及安装的位置 名
  • 数组的方法以及特征

    数组变成一个字符串 1 join 可以在每一个元素中加一个字符串 2 toString pop 删除数组最后一个元素 push 增加数组 reverse 反转 slice 从下标开始取 sort 对数组进行排序 splice 删除数组的某几
  • 取消全部呼叫转移代码_中国移动的卡取消呼叫转移的快捷方式是什么?

    展开全部 取消已设置的所有呼转可用手机拨打 002 取62616964757a686964616fe59b9ee7ad9431333365663562消关机或无信号时转移可用手机拨打 62 取消无人接听时转移可用手机拨打 61 取消遇忙音占
  • 即时通讯(IM)开源项目OpenIM对WebAssembly支持,提升web端体验

    WebAssembly 是什么 2019 年 12 月 W3C 标准批准了第四种官方语言 WebAssembly Wasm 这种语言在结构 使用和功能方面与以前的语言有很大不同 WebAssembly 是一种新的编码方式 可以在现代的Web
  • [1138]java中json的使用和解析

    文章目录 1 创建json对象 1 1 创建JSONObject对象 1 2 创建JSONArray对象 2 解析json 2 1 官方json包解析 2 2 fastjson解析 2 3 jackson解析 1 创建json对象 1 1
  • 关于时区的时间的详解,比如UTC\GMT等

    来源 UTC 和 GMT 及 北京时间的关系 UTC和GMT 这两者几乎是同一概念 它们都是指的格林尼治标准时间 只不过UTC的称呼更为正式一点 两者的区别在于前者是一个天文 上的概念 而 后者是基于一个原子钟 在UTC中 每一年或两年会有
  • 移植micropython最小工程到mm32f3270微控制器

    移植micropython最小工程到mm32f3270微控制器 苏勇 2021 08 文章目录 移植micropython最小工程到mm32f3270微控制器 Introduction 初试micropython v1 6 增加MM32的移
  • OpenCV图像梯度(Sobel和Scharr)

    OpenCV图像梯度 Sobel和Scharr 1 图像梯度是什么 2 图像梯度的用途 3 图像梯度的使用 参考 这篇博客将介绍图像渐变以及如何使用OpenCV的cv2 Sobel计算Sobel渐变和Scharr渐变 1 图像梯度是什么 图
  • CMake - 使用 target_sources() 提高源文件处理能力

    翻译自https crascit com 2016 01 31 enhanced source file handling with target sources 使用 target sources 提高源文件处理能力 在CMake项目中
  • JDK8源码阅读(三) java.io.Serializable

    一 类 1 1 类修饰符 A 是一个接口 B 类的可序列化性由实现java io serializable接口的类启用 不实现此接口的类将不具有序列化或反序列化的任何状态 可序列化类的所有子类型本身都是可序列化的 序列化接口没有方法或字段
  • 数据结构——单链表OJ题

    单链表OJ题 前言 一 删除链表中等于给定值 val 的所有节点 二 反转一个单链表 三 返回链表的中间结点 四 输出该链表中倒数第k个结点 五 将两个有序链表合并 六 链表的回文结构 七 将链表分割成两部分 八 找出第一个公共结点 九 判
  • Matlab:交叉验证,索引结果重现,打乱数据

    总会有奇奇怪怪的想法和需求 想要产生的交叉验证的索引可以重现 虽然可以采取保存的方式 目录 一 随机选取 1 产生索引 2 调用数据 打乱数据 二 顺序选择 循环选取 1 数据初始化 样本个数 训练样本个数等 2 产生训练数据的索引 3 存
  • 多线程编程warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 错误解决

    在多线程编程中使用 thread start pthread t thread id THREAD BODY thread workbody void thread arg 创建子线程时因为最后一个参数需要是指向子线程的文件描述符 int类
  • 使用axis2 java2wsdl命令生成wsdl文件

    1 eclipse新建web工程 编写service接口方法 2 axis2环境变量配置 必须配置环境变量 否则执行java2wsdl命令时无法识别路径 如下 新建环境变量 AXIS2 HOME 值为axis2解压路径如 I path ja
  • vim常用配置及ideavim插件静音

    更多详细内容见文章 http www shanxing top p 188http www shanxing top p 188 提示音静音 set noerrorbells set visualbell 语法高亮 syntax enabl
  • Linux USB U盘热插拔挂载和卸载

    一 硬件平台 1 控制器 MT7620 A9内核 2 RTC芯片 MCP7940 二 软件平台 1 开发环境 Ubuntu12 04 2 SDK内核包 MT7620 SDK软件开发包 MediaTek ApSoC SDK 4320 2015