USB ADB: Corresponding to USB Device Mode
USB OTG: Corresponding to USB Host Mode
USB EAP: Corresponding to USB Network Mode

一、USB OTG / USB Host

Related keyword to search article : USB dwc3,dwc2

enable USB OTG in .dts file:

&usbotg1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_usbotg1>;srp-disable;hnp-disable;adp-disable;power-polarity-active-high;disable-over-current;dr_mode = "otg";status = "okay";
};// kernel\msm-3.18\Documentation\devicetree\bindings\usb\generic.txt
Generic USB Properties
Optional properties:- maximum-speed: tells USB controllers we want to work up to a certain speed. Valid arguments are "super-speed", "high-speed","full-speed" and "low-speed". In case this isn't passed via DT, USB controllers should default to their maximum HW capability.- dr_mode: tells Dual-Role USB controllers that we want to work on a particular mode. Valid arguments are "host","peripheral" and "otg". In case this attribute isn't passed via DT, USB DRD controllers should default to OTG.This is an attribute to a USB controller such as:
dwc3@4a030000 { compatible = "synopsys,dwc3";reg = <0x4a030000 0xcfff>;interrupts = <0 92 4>usb-phy = <&usb2_phy>, <&usb3,phy>;maximum-speed = "super-speed";dr_mode = "otg"; }; 

//\kernel\msm-3.18\drivers\usb\core\hub.c
--0-->static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)--1-->static int hub_configure(struct usb_hub *hub,struct usb_endpoint_descriptor *endpoint)--2-->static void hub_irq(struct urb *urb)--2-->static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)--3-->static void kick_hub_wq(struct usb_hub *hub)--3-->queue_work(hub_wq, &hub->events)--4-->INIT_WORK(&hub->events, hub_event);--4-->static void hub_event(struct work_struct *work)--5-->static void port_event(struct usb_hub *hub, int port1)__must_hold(&port_dev->status_lock)--6-->static void hub_port_connect_change(struct usb_hub *hub, int port1,u16 portstatus, u16 portchange)__must_hold(&port_dev->status_lock)--7-->static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,u16 portchange)--8-->int usb_new_device(struct usb_device *udev)--9-->static int usb_enumerate_device(struct usb_device *udev)--10--> static int usb_enumerate_device_otg(struct usb_device *udev)

1.0 hub_probe

static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
{desc = intf->cur_altsetting;hdev = interface_to_usbdev(intf);/** Hubs have proper suspend/resume support, except for root hubs* where the controller driver doesn't have bus_suspend and* bus_resume methods.*/if (hdev->parent) {        /* normal device */usb_enable_autosuspend(hdev);} else {                /* root hub */const struct hc_driver *drv = bus_to_hcd(hdev->bus)->driver;if (drv->bus_suspend && drv->bus_resume)usb_enable_autosuspend(hdev);}endpoint = &desc->endpoint[0].desc;/* We found a hub */dev_info (&intf->dev, "USB hub found\n");INIT_DELAYED_WORK(&hub->leds, led_work);INIT_DELAYED_WORK(&hub->init_work, NULL);INIT_WORK(&hub->events, hub_event);if (hub_configure(hub, endpoint) >= 0)return 0;
}

1.1 hub_configure

static int hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint)
{hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);ret = get_hub_descriptor(hdev, hub->descriptor);hub->ports = kzalloc(maxchild * sizeof(struct usb_port *), GFP_KERNEL);INIT_WORK(&hub->tt.clear_work, hub_tt_work);ret = hub_hub_status(hub, &hubstatus, &hubchange);hub->urb = usb_alloc_urb(0, GFP_KERNEL);usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, hub, endpoint->bInterval);usb_hub_adjust_deviceremovable(hdev, hub->descriptor);hub_activate(hub, HUB_INIT);
}

1.2 hub_irq

/* completion function, fires on port status changes and various faults */
static void hub_irq(struct urb *urb)
{bits = 0;for (i = 0; i < urb->actual_length; ++i)bits |= ((unsigned long) ((*hub->buffer)[i]))<< (i*8);hub->event_bits[0] = bits;/* Something happened, let hub_wq figure it out */kick_hub_wq(hub);
}

1.3 hub_activate

static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
{HUB_INIT:if (type != HUB_RESUME) { if (hdev->parent && hub_is_superspeed(hdev)) ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), HUB_SET_DEPTH, USB_RT_HUB, hdev->level - 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);if (type == HUB_INIT) {hub_power_on(hub, false); // 上电, 不需要延时queue_delayed_work(system_power_efficient_wq, &hub->init_work, msecs_to_jiffies(delay));/* Suppress autosuspend until init is done */usb_autopm_get_interface_no_resume( to_usb_interface(hub->intfdev) );return;       /* Continues at init2: below */} else if (type == HUB_RESET_RESUME) {/* The internal host controller state for the hub device* may be gone after a host power loss on system resume.* Update the device's info so the HW knows it's a hub.*/hcd = bus_to_hcd(hdev->bus);if (hcd->driver->update_hub_device) {ret = hcd->driver->update_hub_device(hcd, hdev,&hub->tt, GFP_NOIO);if (ret < 0) {dev_err(hub->intfdev, "Host not ""accepting hub info ""update.\n");dev_err(hub->intfdev, "LS/FS devices ""and hubs may not work ""under this hub\n.");}}hub_power_on(hub, true);} else {hub_power_on(hub, true);}}init2:if (need_debounce_delay) {delay = HUB_DEBOUNCE_STABLE;/* Don't do a long sleep inside a workqueue routine */if (type == HUB_INIT2) {INIT_DELAYED_WORK(&hub->init_work, hub_init_func3);queue_delayed_work(system_power_efficient_wq,&hub->init_work,msecs_to_jiffies(delay));device_unlock(hub->intfdev);return;        /* Continues at init3: below */}init3:hub->quiescing = 0;status = usb_submit_urb(hub->urb, GFP_NOIO);if (hub->has_indicators && blinkenlights)queue_delayed_work(system_power_efficient_wq, &hub->leds, LED_CYCLE_PERIOD);/* Scan all ports that need attention */kick_hub_wq(hub);
}

1.4 kick_hub_wq

static void kick_hub_wq(struct usb_hub *hub)
{struct usb_interface *intf;if (hub->disconnected || work_pending(&hub->events))return;/** Suppress autosuspend until the event is proceed.** Be careful and make sure that the symmetric operation is* always called. We are here only when there is no pending* work for this hub. Therefore put the interface either when* the new work is called or when it is canceled.*/intf = to_usb_interface(hub->intfdev);usb_autopm_get_interface_no_resume(intf);kref_get(&hub->kref);if (queue_work(hub_wq, &hub->events))return;/* the work has already been scheduled */usb_autopm_put_interface_async(intf);kref_put(&hub->kref, hub_release);
}

1.5 hub_event

static void hub_event(struct work_struct *work)
{hub = container_of(work, struct usb_hub, events);hdev = hub->hdev;hub_dev = hub->intfdev;intf = to_usb_interface(hub_dev);/* Autoresume */ret = usb_autopm_get_interface(intf);/* deal with port status changes */for (i = 1; i <= hdev->maxchild; i++) {struct usb_port *port_dev = hub->ports[i - 1];if (test_bit(i, hub->event_bits)|| test_bit(i, hub->change_bits) || test_bit(i, hub->wakeup_bits)) {/** The get_noresume and barrier ensure that if the port was in the process of resuming, we* flush that work and keep the port active for the duration of the port_event().  However,* if the port is runtime pm suspended (powered-off), we leave it in that state, run* an abbreviated port_event(), and move on. */pm_runtime_get_noresume(&port_dev->dev);pm_runtime_barrier(&port_dev->dev);usb_lock_port(port_dev);port_event(hub, i);usb_unlock_port(port_dev);pm_runtime_put_sync(&port_dev->dev);}}
}

1.6 port_event

static void port_event(struct usb_hub *hub, int port1) __must_hold(&port_dev->status_lock)
{connect_change = test_bit(port1, hub->change_bits);if (portchange & USB_PORT_STAT_C_CONNECTION) {usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);connect_change = 1;}if (portchange & USB_PORT_STAT_C_ENABLE) {if (!connect_change)dev_dbg(&port_dev->dev, "enable change, status %08x\n", portstatus);usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);/** EM interference sometimes causes badly shielded USB devices* to be shutdown by the hub, this hack enables them again.* Works at least with mouse driver.*/if (!(portstatus & USB_PORT_STAT_ENABLE)  && !connect_change && udev) {dev_err(&port_dev->dev, "disabled by hub (EMI?), re-enabling...\n");connect_change = 1;}   }if (portchange & USB_PORT_STAT_C_OVERCURRENT) {u16 status = 0, unused;dev_dbg(&port_dev->dev, "over-current change\n");usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_OVER_CURRENT);msleep(100);    /* Cool down */hub_power_on(hub, true);hub_port_status(hub, port1, &status, &unused);if (status & USB_PORT_STAT_OVERCURRENT)dev_err(&port_dev->dev, "over-current condition\n");}if (portchange & USB_PORT_STAT_C_RESET) {dev_dbg(&port_dev->dev, "reset change\n");usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_RESET);}if ((portchange & USB_PORT_STAT_C_BH_RESET)&& hub_is_superspeed(hdev)) {dev_dbg(&port_dev->dev, "warm reset change\n");usb_clear_port_feature(hdev, port1,USB_PORT_FEAT_C_BH_PORT_RESET);}if (portchange & USB_PORT_STAT_C_LINK_STATE) {dev_dbg(&port_dev->dev, "link state change\n");usb_clear_port_feature(hdev, port1,USB_PORT_FEAT_C_PORT_LINK_STATE);}if (hub_handle_remote_wakeup(hub, port1, portstatus, portchange))connect_change = 1;/** Warm reset a USB3 protocol port if it's in* SS.Inactive state.*/if (hub_port_warm_reset_required(hub, port1, portstatus)) {dev_dbg(&port_dev->dev, "do warm reset\n");if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)|| udev->state == USB_STATE_NOTATTACHED) {if (hub_port_reset(hub, port1, NULL,HUB_BH_RESET_TIME, true) < 0)hub_port_disable(hub, port1, 1);} elsereset_device = 1;}if (connect_change)hub_port_connect_change(hub, port1, portstatus, portchange);
}

1.7 hub_port_connect_change

static void hub_port_connect_change(struct usb_hub *hub, int port1,u16 portstatus, u16 portchange)__must_hold(&port_dev->status_lock)
{if (hub->has_indicators) {set_port_led(hub, port1, HUB_LED_AUTO);hub->indicator[port1-1] = INDICATOR_AUTO;}#ifdef   CONFIG_USB_OTG/* during HNP, don't repeat the debounce */if (hub->hdev->bus->is_b_host)portchange &= ~(USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE);#endifhub_port_connect(hub, port1, portstatus, portchange);  // start to connect the port
}

1.8 hub_port_connect

static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,u16 portchange)
{/* Disconnect any existing devices under this port */if (udev) {if (hcd->usb_phy && !hdev->parent)usb_phy_notify_disconnect(hcd->usb_phy, udev->speed);usb_disconnect(&port_dev->child);}if (portchange & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE)) {status = hub_port_debounce_be_stable(hub, port1);portstatus = status;}/* Return now if debouncing failed or nothing is connected or the device was "removed". */if (!(portstatus & USB_PORT_STAT_CONNECTION) || test_bit(port1, hub->removed_bits)) {/* maybe switch power back on (e.g. root hub was reset) */if (hub_is_port_power_switchable(hub) && !port_is_power_on(hub, portstatus))set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);return;}if (hub_is_superspeed(hub->hdev))unit_load = 150;elseunit_load = 100;for (i = 0; i < SET_CONFIG_TRIES; i++) {/* reallocate for each attempt, since references to the previous one can escape in various ways */udev = usb_alloc_dev(hdev, hdev->bus, port1);usb_set_device_state(udev, USB_STATE_POWERED);   // set usb state poweredudev->bus_mA = hub->mA_per_port;udev->level = hdev->level + 1;   // level + 1udev->wusb = hub_is_wusb(hub);/* Only USB 3.0 devices are connected to SuperSpeed hubs. */if (hub_is_superspeed(hub->hdev))udev->speed = USB_SPEED_SUPER;choose_devnum(udev);status = hub_port_init(hub, udev, port1, i);usb_detect_quirks(udev);/* check for devices running slower than they could */if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200&& udev->speed == USB_SPEED_FULL && highspeed_hubs != 0)check_highspeed (hub, udev, port1);}/* Run it through the hoops (find a driver, etc) */if (!status) {status = usb_new_device(udev);if (status) {port_dev->child = NULL;} else {if (hcd->usb_phy && !hdev->parent)usb_phy_notify_connect(hcd->usb_phy, udev->speed);}}status = hub_power_remaining(hub);if (status)dev_dbg(hub->intfdev, "%dmA power budget left\n", status);return;}
}

1.9 usb_new_device

int usb_new_device(struct usb_device *udev)
{   /* Tell the runtime-PM framework the device is active */pm_runtime_set_active(&udev->dev);pm_runtime_get_noresume(&udev->dev);pm_runtime_use_autosuspend(&udev->dev);pm_runtime_enable(&udev->dev);/* By default, forbid autosuspend for all devices.  It will be allowed for hubs during binding.*/usb_disable_autosuspend(udev);err = usb_enumerate_device(udev);    /* Read descriptors */dev_dbg(&udev->dev, "udev %d, busnum %d, minor = %d\n", udev->devnum, udev->bus->busnum, (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));/* export the usbdev device-node for libusb */udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1)));/* Tell the world! */announce_device(udev);if (udev->serial)add_device_randomness(udev->serial, strlen(udev->serial));if (udev->product)add_device_randomness(udev->product, strlen(udev->product));if (udev->manufacturer)add_device_randomness(udev->manufacturer, strlen(udev->manufacturer));device_enable_async_suspend(&udev->dev);/* check whether the hub or firmware marks this port as non-removable */if (udev->parent)set_usb_port_removable(udev);err = device_add(&udev->dev);========>>>int device_add(struct device *dev){kobject_uevent(&dev->kobj, KOBJ_ADD);bus_probe_device(dev);/* tie the class to the device */klist_add_tail(&dev->knode_class, &dev->class->p->klist_devices);}<<<========(void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);    //create endpoint devusb_mark_last_busy(udev);pm_runtime_put_sync_autosuspend(&udev->dev);return err;
}

1.10 usb_enumerate_device

static int usb_enumerate_device(struct usb_device *udev)
{struct usb_hcd *hcd = bus_to_hcd(udev->bus);err = usb_get_configuration(udev);/* read the standard strings and cache them if present */udev->product = usb_cache_string(udev, udev->descriptor.iProduct);udev->manufacturer = usb_cache_string(udev, udev->descriptor.iManufacturer);udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);err = usb_enumerate_device_otg(udev);usb_detect_interface_quirks(udev);===========>>>static u32 __usb_detect_quirks(struct usb_device *udev, const struct usb_device_id *id){u32 quirks = 0;for (; id->match_flags; id++) {if (!usb_match_device(udev, id))continue;if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) &&!usb_match_any_interface(udev, id))     ---------------// from here to go continue;quirks |= (u32)(id->driver_info);}return quirks;}<<<============
}

1.11 usb_enumerate_device_otg

static int usb_enumerate_device_otg(struct usb_device *udev)
{#ifdef CONFIG_USB_OTGif (desc->bmAttributes & USB_OTG_HNP) {/* enable HNP before suspend, it's simpler */if (port1 == bus->otg_port)bus->b_hnp_enable = 1;err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), USB_REQ_SET_FEATURE, 0, bus->b_hnp_enable ? USB_DEVICE_B_HNP_ENABLE : USB_DEVICE_A_ALT_HNP_SUPPORT,0, NULL, 0, USB_CTRL_SET_TIMEOUT);}
}

1.12 usb_control_msg

// usb_control_msg - Builds a control urb, sends it off and waits for completion
// This function sends a simple control message to a specified endpoint and waits for the message to complete, or timeoutint usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,__u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout)
{dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);dr->bRequestType = requesttype;dr->bRequest = request;dr->wValue = cpu_to_le16(value);dr->wIndex = cpu_to_le16(index);dr->wLength = cpu_to_le16(size);ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);==========>>>urb = usb_alloc_urb(0, GFP_NOIO);usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, len, usb_api_blocking_completion, NULL);retv = usb_start_wait_urb(urb, timeout, &length);======>>>retval = usb_submit_urb(urb, GFP_NOIO);wait_event_timeout(awd.wqh, awd.done, timeout)<<<======<<<==========return ret;
}

1.13 usb_match_device(udev, id)

int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
{if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&id->idVendor != le16_to_cpu(dev->descriptor.idVendor))return 0;if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&id->idProduct != le16_to_cpu(dev->descriptor.idProduct))return 0;/* No need to test id->bcdDevice_lo != 0, since 0 is nevergreater than any unsigned number. */if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&(id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))return 0;if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&(id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))return 0;if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&(id->bDeviceClass != dev->descriptor.bDeviceClass))return 0;if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&(id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))return 0;if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))return 0;return 1;
}

1.14 usb_match_any_interface(udev, id)

static bool usb_match_any_interface(struct usb_device *udev,const struct usb_device_id *id)
{unsigned int i;for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) {struct usb_host_config *cfg = &udev->config[i];unsigned int j;for (j = 0; j < cfg->desc.bNumInterfaces; ++j) {struct usb_interface_cache *cache;struct usb_host_interface *intf;cache = cfg->intf_cache[j];if (cache->num_altsetting == 0)continue;intf = &cache->altsetting[0];if (usb_match_one_id_intf(udev, intf, id))return true;}}return false;
}
usb_gadget_set_statecomposite_setup

二、USB ADB / USB Device

related keyword: USB Device

三、DWC3 Charge

Linux下USB驱动详解(HOST)
https://blog.csdn.net/feng85016578/article/details/52808434
ljzcom的专栏
https://blog.csdn.net/ljzcom/article/category/1067200
USB OTG学习笔记
https://blog.csdn.net/ljzcom/article/details/8843597

【精】USB具体通讯过程(含枚举过程)

从零开始学USB(十七、USB的枚举)

USB OTG(Host) 、 USB ADB(Device)、DWC3 Charge相关推荐

  1. USB OTG to PC USB API简介

    USB OTG to PC USB API简介 本API分为四部分:Linux或Android内核 (主要是gadget驱动).linux端API及其DEMO.Windows 驱动.Windows A ...

  2. RK3566 AndroidR usb otg host和peripheral切换软件手动切换,写/sys/devices/platform/fe8a0000.usb2-phy/otg_mode

    一.先看OTG口USB的原理图,OTG控制器可以做host,也能做device,控制器的角色一般由USB ID电平来决定,会由个USB_OTG0_ID pin识别. 二.通过读取/sys/device ...

  3. android usb otg 查看,android USB OTG功能如何打开及实现

    一.检查HW原理图,确认是否支持OTG功能(vbus是否供上电,IDDIG pin连接是否正确)二.若HW确认支持OTG功能,则按照以下方法分别打开USB OTG功能及实现挂载:如 一.检查HW原理图 ...

  4. rk3328 Android8.1 usb otg host和device切换

  5. Android 系统使用USB OTG功能/打开USB Host API功能

    步骤一:确定 Android 设备是否支持 USB Host 功能,具体可以通过以下步骤进行确认: 1. 查看手机或平板设备参数,或者直接联系厂家咨询: 2. 使用 UsbHostDiagnostic ...

  6. otg android 键盘,使用USB OTG将手机、平板连上键盘、U盘

    偶是比较比较少用智能手机的,一是对于整天待在电脑前的我来讲,智能手机能完成的东西,我在电脑上能随时更方便地处理:二是,智能手机的屏实在太小了,看什么东西翻来翻去的浪费时间:三就是因为输入文字什么的太不 ...

  7. 【单片机】Android手机USB外接STM32单片机通过ADB实现投屏反向控制的功能

    Android手机USB外接STM32单片机通过ADB实现投屏反向控制的功能 前言 一.功能演示 二.实现步骤 1.开发环境 2.代码分析 (1)USBHost处理函数 (2)ADB事务处理函数 (3 ...

  8. otg usb 定位_详解USB OTG工作原理及其应用

    原标题:详解USB OTG工作原理及其应用 1994年,Intel,Compaq等七家软硬件全球知名企业为了突破当时PC使用串口和并口传输速度的限制,成立了通用串行 开发者论坛( Implemente ...

  9. USB OTG(On-The-Go)技术概述

    USB OTG(On-The-Go)技术概述[USB 2.0规范] 摘要:USB OTG(On-The-Go)是USB 2.0规范的补充,它使外设可以在无主机参与的情况下直接互连进行通信工程.本文讨论 ...

最新文章

  1. Eclipse无法编译,提示错误“找不到或者无法加载主类”解决方法
  2. python 离线翻译软件_AI赋能翻译,讯飞这个设备轻松搞定国际交流
  3. Hobbit玩转Zynq MPSoC系列之2:TPG输入+VCU编码+rtp网络传输
  4. 阿里二面:RocketMQ同一个消费组内的消费者订阅量不同tag,会有问题吗?
  5. Python学习 5day__基础知识
  6. 华为模拟器ensp与真实机器连接使用的配置内容二
  7. URL 编码是什么?
  8. 《Nature》论文插图的Matlab复刻第4期—单组多色柱状图(Part2-82)
  9. 电瓶车续航测试软件,谁的续航更真实? 新出行为你测试三款市面上主流电动车...
  10. 开源硬件的舞者--WIZnet
  11. 搜索结果排列html模板,搜索结果页优化-城市模板
  12. [Java][详解]使用jintellitype实现键盘全局监听
  13. c语言字符数组的实际长度,C语言中,当计算字符数组长度时,用sizeof 和strlen 的原理及两者的区别...
  14. [资讯]同济DI出品 | 绝对是史上最萌的机器人教具!!!
  15. 先电iaas云平台搭建(openstack)————搭建过程
  16. 设置Win7虚拟机的内存
  17. 用mac系统怎么连宽带连接服务器吗,苹果电脑怎么连宽带_MAC系统怎么连接有线宽带-win7之家...
  18. 解决MySQl卸载卸不干净问题
  19. 使用Xgboost自带的读取格式DMatrix()
  20. 1588分析和实现总纲

热门文章

  1. CTF-数据分析(二)
  2. 发烧级蓝牙耳机哪款音质最好?200元内性价比高的蓝牙耳机
  3. 采集CSI数据的实验
  4. 京东与淘宝孰优孰劣?
  5. linux内存条故障,linux – 如何从MCE消息中找到故障内存模块?
  6. 学生3D作品---李自立---台式电脑加椅子(Blender 2.8)
  7. perf常用命令(perf top perf record perf stat)
  8. 创新实践部第一次培训---算法入门
  9. 南充一中2021成绩查询高考,2021年南充一中升学率高不高?
  10. 行远自迩,乘势前行 | 菊风再中标中原银行远程银行项目