目录

一 . UFS Hibernate简介

二 . UFS Hibernate系统上的行为

1.Auto-Hibernation

2. Clk-gate with hibernate

3.suspend with hibernate


一 . UFS Hibernate简介

1. 系统 Soc上的UFS Host  Controller 模块处理完成命令和数据后,就会进入UFS Idle状态,也就是空闲状态, 也会调用UFS相关的PM Runtime的回调接口,执行对应的操作,进入UFS Idle之后,又会通过发送DME_HIBERNATE_ENTER命令让Link进入Hibernate状态,受影响的是本地和对等 UniPort(UniPro L1.5-L4 和 M-PHY)。

2. 当系统Soc上的UFS Host  Controller收到命令和数据请求后,又会会进入UFS Active状态,进入UFS Active状态之后,通过发送 DME_HIBERNATE_EXIT命令让Link出Hibernate状态。

Note: Link(链路)指的是也是本地端和远程端的数据通道,也可以理解为M-PHY层的M-TX和M-RX。
5.6.1 UniPro Link Management
869 An available Lane is a Lane that is implemented in the PHY. A Lane can
be either connected or unconnected, depending of the interconnection between
the local PHY and the remote PHY. The connection state is automatically
discovered during the Link Startup Sequence. An active Lane is used for
data transfers while an inactive or unused Lane is not. The number of active
Lanes is set by PA_ActiveTxDataLanes and PA_ActiveRxDataLanes

二 . UFS Hibernate系统上的行为

UFS Hibernate在系统上有3种行为,分别为 Auto-Hibernate, Clk-gate with hibernate, suspend with hibernate(其中suspend分为runtime suspend和runtime suspend).

1. Auto-Hibernate

Auto-Hibernation是UFS Host Controller的一个功能,可以通过UFS Host Controller Register Offset 00h: CAP - Controller Capabilities Bit[23]的值来判断释放支持该功能,Bit[23] Vaue为1,说明支持 Auto-Hibernate功能,为0说明不支持 Auto-Hibernate.

 Auto-Hibernate功能完全是通过硬件去实现的,

主要过程:当UFS Host Controller处理完成命令和数据后,会间隔AHIT时间通过硬件层面给UFS Device发送DME_HIBERNATE_ENTER命令,全程系统软件无感知,所以通过Event Trace也抓不到对应的Event事件,想要验证这个过程,可以通过PA协议分析仪去做实验,分析Unipro协议包会有Hibernate的整个流程。

上文的AHIT指的是UFS Host Controller处理完成命令和数据后,会间隔一段时间,才发送DME_HIBERNATE_ENTER命令,这个间隔的时间指的就是AHIT

(1)这个AHIT可以通过系统软件去配置,

(2)这个AHIT值可以通过Sys节点去查询(不同的系统软件节点位置可能有差异)

# cat /sys/device/platform/soc/1d84000.ufshc/auto_hibern8
1000

UFS Hibernate实现相关:

ufshcd_init:初始化UFS Hibernate相关信息,设置Auto Hibernate的时间位1ms,即当UFS Host控制器空闲后,间隔1ms就会通过硬件下发DME_HIBERNATE_ENTER命令给UFS Device让Link处于Hibernate状态。

static void ufshcd_init_hibern8(struct ufs_hba *hba)
{struct ufs_hibern8_on_idle *h8 = &hba->hibern8_on_idle;/* initialize the state variable here */h8->state = HIBERN8_EXITED;if (!ufshcd_is_hibern8_on_idle_allowed(hba) &&!ufshcd_is_auto_hibern8_supported(hba))return;if (ufshcd_is_auto_hibern8_supported(hba)) {/* Set the default auto-hiberate idle timer value to 1 ms */hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 1) |FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3);h8->state = AUTO_HIBERN8;/** Disable SW hibern8 enter on idle in case* auto hibern8 is supported*/hba->caps &= ~UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;} else {h8->delay_ms = 10;INIT_DELAYED_WORK(&hba->hibern8_on_idle.enter_work,ufshcd_hibern8_enter_work);INIT_WORK(&hba->hibern8_on_idle.exit_work,ufshcd_hibern8_exit_work);h8->is_enabled = true;h8->delay_attr.show = ufshcd_hibern8_on_idle_delay_show;h8->delay_attr.store = ufshcd_hibern8_on_idle_delay_store;sysfs_attr_init(&h8->delay_attr.attr);h8->delay_attr.attr.name = "hibern8_on_idle_delay_ms";h8->delay_attr.attr.mode = 0644;if (device_create_file(hba->dev, &h8->delay_attr))dev_err(hba->dev, "Failed to create sysfs for hibern8_on_idle_delay\n");h8->enable_attr.show = ufshcd_hibern8_on_idle_enable_show;h8->enable_attr.store = ufshcd_hibern8_on_idle_enable_store;sysfs_attr_init(&h8->enable_attr.attr);h8->enable_attr.attr.name = "hibern8_on_idle_enable";h8->enable_attr.attr.mode = 0644;if (device_create_file(hba->dev, &h8->enable_attr))dev_err(hba->dev, "Failed to create sysfs for hibern8_on_idle_enable\n");}
}

ufshcd_probe_hba:将设置Auto Hibernate的时间写入AHIT寄存器

static void ufshcd_set_auto_hibern8_timer(struct ufs_hba *hba)
{unsigned long flags;if (!ufshcd_is_auto_hibern8_supported(hba))return;spin_lock_irqsave(hba->host->host_lock, flags);ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER);/* Make sure the timer gets applied before further operations */mb();spin_unlock_irqrestore(hba->host->host_lock, flags);
}

2. Clk-gate with hibernate

接触过内核驱动的同学们应该都知道,一个进程在访问对应的驱动设备的之前需要先Hold住驱动设备,获取到对应的资源,资源包括驱动设备的访问请求,CLK资源等, CPU资源等, 保证此设备只允许本进程访问,避免出现多进程同时访问此驱动设备出现不可预知的问题。访问完成之后需要释放对应的资源。

其中CLK资源是内核驱动比较重要的资源,在UFS控制器驱动中,在访问UFS控制器之前,需要先让LInk 推出Hibernate状态,然后获取并使能CLK资源,访问完成UFS控制器后,需要先让Link进入Hibernate状态,然后将CLK资源关闭,可以节省功耗。

总的来说,UFS控制器处理完成命令和数据之后,就会进入UFS Idle,进入UFS Idle之后,就会发起Clk gate的动作,从 __ufshcd_release开始计时,间隔delay_ms给UFS Devices发送DME_HIBERNATE_ENTER命令。

其中间隔时间delay_ms是在UFS初始化里面设置的:分为性能模式和省电模式

delay_ms分为三个阶段:

UFS初始化阶段:默认设置为性能模式,delay_ms设置为50ms, 即UFS Idle之后50ms进行CLK Gate流程。

UFS Gear Scale UP阶段:设置为性能模式,delay_ms设置为50ms, 即UFS Idle之后50ms进行CLK Gate流程。

UFS Gear Scale Down阶段:设置为省电模式,delay_ms设置为10ms, 即UFS Idle之后10ms进行CLK Gate流程。

#define UFSHCD_CLK_GATING_DELAY_MS_PWR_SAVE    10
#define UFSHCD_CLK_GATING_DELAY_MS_PERF        50

CLK Gate系统相关的接口:

# cat /sys/device/platform/soc/1d84000.ufshc/clkgate_delay_ms_perf
50# cat /sys/device/platform/soc/1d84000.ufshc/clkgate_delay_ms_pwr_save10

UFS CLK Gate整体流程:

__ufshcd_transfer_req_compl UFS命令和数据处理完成的处理函数
__ufshcd_release UFS控制器驱动处理完成请求之后,释放相关的资源,比如CLK资源

hrtimer_start(&hba->clk_gating.gate_hrtimer,ms_to_ktime(hba->clk_gating.delay_ms),HRTIMER_MODE_REL);

启动CLK_Gate回调函数
ufshcd_gate_work CLK Gate具体实现,主要是将Link放到Hibernate状态,然后关闭CLK
ufshcd_uic_hibern8_enter 将Link置为Hibernate Mode
ufshcd_disable_clocks 关闭CLK资源

UFS实现相关:

__ufshcd_release:

/* host lock must be held before calling this variant */
static void __ufshcd_release(struct ufs_hba *hba, bool no_sched)
{if (!ufshcd_is_clkgating_allowed(hba))return;hba->clk_gating.active_reqs--;if (hba->clk_gating.active_reqs || hba->clk_gating.is_suspended|| hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL|| hba->lrb_in_use || hba->outstanding_tasks|| hba->active_uic_cmd || hba->uic_async_done|| ufshcd_eh_in_progress(hba) || no_sched)return;hba->clk_gating.state = REQ_CLKS_OFF;trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state);hba->ufs_stats.clk_rel.ts = ktime_get();hrtimer_start(&hba->clk_gating.gate_hrtimer,ms_to_ktime(hba->clk_gating.delay_ms),HRTIMER_MODE_REL);
}

ufshcd_gate_work:

static void ufshcd_gate_work(struct work_struct *work)
{struct ufs_hba *hba = container_of(work, struct ufs_hba,clk_gating.gate_work);unsigned long flags;spin_lock_irqsave(hba->host->host_lock, flags);
#ifdef VENDOR_EDIT
//yh@BSP.Storage.UFS, 2020-1-15 add for fix race condition during hrtimer active(ufshcd_release/ufshcd_gate_work)if (hba->clk_gating.state == CLKS_OFF){goto rel_lock;}
#endif/** In case you are here to cancel this work the gating state* would be marked as REQ_CLKS_ON. In this case save time by* skipping the gating work and exit after changing the clock* state to CLKS_ON.*/if (hba->clk_gating.is_suspended ||(hba->clk_gating.state != REQ_CLKS_OFF)) {hba->clk_gating.state = CLKS_ON;trace_ufshcd_clk_gating(dev_name(hba->dev),hba->clk_gating.state);goto rel_lock;}if (hba->clk_gating.active_reqs|| hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL|| hba->lrb_in_use || hba->outstanding_tasks|| hba->active_uic_cmd || hba->uic_async_done)goto rel_lock;spin_unlock_irqrestore(hba->host->host_lock, flags);if (ufshcd_is_hibern8_on_idle_allowed(hba) &&hba->hibern8_on_idle.is_enabled)/** Hibern8 enter work (on Idle) needs clocks to be ON hence* make sure that it is flushed before turning off the clocks.*/flush_delayed_work(&hba->hibern8_on_idle.enter_work);/* put the link into hibern8 mode before turning off clocks */if (ufshcd_can_hibern8_during_gating(hba)) {if (ufshcd_uic_hibern8_enter(hba)) {hba->clk_gating.state = CLKS_ON;trace_ufshcd_clk_gating(dev_name(hba->dev),hba->clk_gating.state);goto out;}ufshcd_set_link_hibern8(hba);}/** If auto hibern8 is enabled then the link will already* be in hibern8 state and the ref clock can be gated.*/if ((ufshcd_is_auto_hibern8_enabled(hba) ||!ufshcd_is_link_active(hba)) && !hba->no_ref_clk_gating)ufshcd_disable_clocks(hba, true);else/* If link is active, device ref_clk can't be switched off */ufshcd_disable_clocks_keep_link_active(hba, true);/* Put the host controller in low power mode if possible */ufshcd_hba_vreg_set_lpm(hba);/** In case you are here to cancel this work the gating state* would be marked as REQ_CLKS_ON. In this case keep the state* as REQ_CLKS_ON which would anyway imply that clocks are off* and a request to turn them on is pending. By doing this way,* we keep the state machine in tact and this would ultimately* prevent from doing cancel work multiple times when there are* new requests arriving before the current cancel work is done.*/spin_lock_irqsave(hba->host->host_lock, flags);if (hba->clk_gating.state == REQ_CLKS_OFF) {hba->clk_gating.state = CLKS_OFF;trace_ufshcd_clk_gating(dev_name(hba->dev),hba->clk_gating.state);}
rel_lock:spin_unlock_irqrestore(hba->host->host_lock, flags);
out:return;
}

__ufshcd_uic_hibern8_enter

static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
{int ret;struct uic_command uic_cmd = {0};ktime_t start = ktime_get();ufshcd_vops_hibern8_notify(hba, UIC_CMD_DME_HIBER_ENTER, PRE_CHANGE);uic_cmd.command = UIC_CMD_DME_HIBER_ENTER;ret = ufshcd_uic_pwr_ctrl(hba, &uic_cmd);trace_ufshcd_profile_hibern8(dev_name(hba->dev), "enter",ktime_to_us(ktime_sub(ktime_get(), start)), ret);ufsdbg_error_inject_dispatcher(hba, ERR_INJECT_HIBERN8_ENTER, 0, &ret);/** Do full reinit if enter failed or if LINERESET was detected during* Hibern8 operation. After LINERESET, link moves to default PWM-G1* mode hence full reinit is required to move link to HS speeds.*/if (ret || hba->full_init_linereset) {int err;hba->full_init_linereset = false;ufshcd_update_error_stats(hba, UFS_ERR_HIBERN8_ENTER);dev_err(hba->dev, "%s: hibern8 enter failed. ret = %d\n",__func__, ret);/** If link recovery fails then return error code (-ENOLINK)* returned ufshcd_link_recovery().* If link recovery succeeds then return -EAGAIN to attempt* hibern8 enter retry again.*/err = ufshcd_link_recovery(hba);if (err) {dev_err(hba->dev, "%s: link recovery failed\n",__func__);ret = err;} else {ret = -EAGAIN;}} else {ufshcd_vops_hibern8_notify(hba, UIC_CMD_DME_HIBER_ENTER,POST_CHANGE);dev_dbg(hba->dev, "%s: Hibern8 Enter at %lld us\n", __func__,ktime_to_us(ktime_get()));return ret;
}

3.suspend with hibernate

系统为了在空闲的时候可以释放关闭一些不需要的资源,在需要用到的时候开启需要的资源,提供了PM框架,主要是包括深睡deep sleep(也称为system suspend)和浅睡light sleep(也称为runtime suspend), 合理运用PM机制在系统空闲的时候,进入睡眠模式。可以降低功耗,提高续航能力。

我们此篇以浅睡light sleep(runtime suspend)举例说明:

基本流程是UFS控制器处理完成命令和数据后,进入UFS Idle, UFS Idle保持3s后,开始进入ufs runtime suspend流程,给UFS Devices发送DME_HIBERNATE_ENTER命令, 让Link进入Hibernate状态。

相关接口:

# cat /sys/device/platform/soc/1d84000.ufshc/power/autosuspend_delay_ms
3

UFS suspend with hibernate Flow:

相关实现:

ufshcd_suspend:

static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{int ret = 0;enum ufs_pm_level pm_lvl;enum ufs_dev_pwr_mode req_dev_pwr_mode;enum uic_link_state req_link_state;hba->pm_op_in_progress = 1;if (!ufshcd_is_shutdown_pm(pm_op)) {pm_lvl = ufshcd_is_runtime_pm(pm_op) ?hba->rpm_lvl : hba->spm_lvl;req_dev_pwr_mode = ufs_get_pm_lvl_to_dev_pwr_mode(pm_lvl);req_link_state = ufs_get_pm_lvl_to_link_pwr_state(pm_lvl);} else {req_dev_pwr_mode = UFS_POWERDOWN_PWR_MODE;req_link_state = UIC_LINK_OFF_STATE;}#if defined(VENDOR_EDIT) && defined(CONFIG_UFSFEATURE)
/* Hank.liu@TECH.PLAT.Storage, 2019-10-31, add UFS+ hpb and tw driver*/ufsf_hpb_suspend(&hba->ufsf);ufsf_tw_suspend(&hba->ufsf);
#endif/** If we can't transition into any of the low power modes* just gate the clocks.*/WARN_ON(hba->hibern8_on_idle.is_enabled &&hba->hibern8_on_idle.active_reqs);ufshcd_hold_all(hba);hba->clk_gating.is_suspended = true;hba->hibern8_on_idle.is_suspended = true;if (hba->clk_scaling.is_allowed) {cancel_work_sync(&hba->clk_scaling.suspend_work);cancel_work_sync(&hba->clk_scaling.resume_work);ufshcd_suspend_clkscaling(hba);}if (req_dev_pwr_mode == UFS_ACTIVE_PWR_MODE &&req_link_state == UIC_LINK_ACTIVE_STATE) {goto disable_clks;}if ((req_dev_pwr_mode == hba->curr_dev_pwr_mode) &&(req_link_state == hba->uic_link_state))goto enable_gating;/* UFS device & link must be active before we enter in this function */if (!ufshcd_is_ufs_dev_active(hba) || !ufshcd_is_link_active(hba))goto set_vreg_lpm;if (ufshcd_is_runtime_pm(pm_op)) {if (ufshcd_can_autobkops_during_suspend(hba)) {/** The device is idle with no requests in the queue,* allow background operations if bkops status shows* that performance might be impacted.*/ret = ufshcd_urgent_bkops(hba);if (ret)goto enable_gating;} else {/* make sure that auto bkops is disabled */ufshcd_disable_auto_bkops(hba);}ufshcd_wb_toggle_flush(hba);} else if (!ufshcd_is_runtime_pm(pm_op)) {ufshcd_wb_buf_flush_disable(hba);hba->dev_info.keep_vcc_on = false;}if ((req_dev_pwr_mode != hba->curr_dev_pwr_mode) &&((ufshcd_is_runtime_pm(pm_op) && (!hba->auto_bkops_enabled)&& !hba->wb_buf_flush_enabled) ||!ufshcd_is_runtime_pm(pm_op))) {/* ensure that bkops is disabled */ufshcd_disable_auto_bkops(hba);ret = ufshcd_set_dev_pwr_mode(hba, req_dev_pwr_mode);if (ret)goto enable_gating;}ret = ufshcd_link_state_transition(hba, req_link_state, 1);if (ret)goto set_dev_active;if (ufshcd_is_link_hibern8(hba) &&ufshcd_is_hibern8_on_idle_allowed(hba))hba->hibern8_on_idle.state = HIBERN8_ENTERED;set_vreg_lpm:if (!hba->auto_bkops_enabled)ufshcd_vreg_set_lpm(hba);
disable_clks:/** Call vendor specific suspend callback. As these callbacks may access* vendor specific host controller register space call them before the* host clocks are ON.*/ret = ufshcd_vops_suspend(hba, pm_op);if (ret)goto set_link_active;/** Disable the host irq as host controller as there won't be any* host controller transaction expected till resume.*/ufshcd_disable_irq(hba);if (!ufshcd_is_link_active(hba))ret = ufshcd_disable_clocks(hba, false);else/** If link is active, device ref_clk and unipro clock can't be* switched off.*/ret = ufshcd_disable_clocks_keep_link_active(hba, false);if (ret)goto set_link_active;if (ufshcd_is_clkgating_allowed(hba)) {hba->clk_gating.state = CLKS_OFF;trace_ufshcd_clk_gating(dev_name(hba->dev),hba->clk_gating.state);}/* Put the host controller in low power mode if possible */ufshcd_hba_vreg_set_lpm(hba);goto out;set_link_active:ufshcd_enable_irq(hba);if (hba->clk_scaling.is_allowed)ufshcd_resume_clkscaling(hba);ufshcd_vreg_set_hpm(hba);if (ufshcd_is_link_hibern8(hba) && !ufshcd_uic_hibern8_exit(hba)) {ufshcd_set_link_active(hba);} else if (ufshcd_is_link_off(hba)) {ufshcd_update_error_stats(hba, UFS_ERR_VOPS_SUSPEND);ufshcd_host_reset_and_restore(hba);}
set_dev_active:if (!ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE))ufshcd_disable_auto_bkops(hba);
enable_gating:if (hba->clk_scaling.is_allowed)ufshcd_resume_clkscaling(hba);hba->hibern8_on_idle.is_suspended = false;hba->clk_gating.is_suspended = false;ufshcd_release_all(hba);
#if defined(VENDOR_EDIT) && defined(CONFIG_UFSFEATURE)
/* Hank.liu@TECH.PLAT.Storage, 2019-10-31, add UFS+ hpb and tw driver*/ufsf_hpb_resume(&hba->ufsf);ufsf_tw_resume(&hba->ufsf);
#endif
out:hba->pm_op_in_progress = 0;if (ret)ufshcd_update_error_stats(hba, UFS_ERR_SUSPEND);return ret;
}

ufshcd_link_state_transition:

static int ufshcd_link_state_transition(struct ufs_hba *hba,enum uic_link_state req_link_state,int check_for_bkops)
{int ret = 0;if (req_link_state == hba->uic_link_state)return 0;if (req_link_state == UIC_LINK_HIBERN8_STATE) {ret = ufshcd_uic_hibern8_enter(hba);if (!ret)ufshcd_set_link_hibern8(hba);elsegoto out;}/** If autobkops is enabled, link can't be turned off because* turning off the link would also turn off the device.*/else if ((req_link_state == UIC_LINK_OFF_STATE) &&(!check_for_bkops || (check_for_bkops &&!hba->auto_bkops_enabled))) {/** Let's make sure that link is in low power mode, we are doing* this currently by putting the link in Hibern8. Otherway to* put the link in low power mode is to send the DME end point* to device and then send the DME reset command to local* unipro. But putting the link in hibern8 is much faster.*/ret = ufshcd_uic_hibern8_enter(hba);if (ret)goto out;/** Change controller state to "reset state" which* should also put the link in off/reset state*/ufshcd_hba_stop(hba, true);/** TODO: Check if we need any delay to make sure that* controller is reset*/ufshcd_set_link_off(hba);}out:return ret;
}

UFS Hibernate介绍--代码部分相关推荐

  1. Hibernate 介绍与入门

    目录 1.hibernate介绍 2.Hibernate3.6入门程序 ​ 1.hibernate介绍 问题:hibernate是什么,它能做什么? hibernate冬眠Hibernate是一个开放 ...

  2. MATLAB 画三维长方体 介绍+代码

    MATLAB 画三维长方体 介绍+代码 在做机械臂三维避障仿真时可能用到对空间障碍物进行描述,一般用长方体,圆柱体等描述,以下是两种画长方体的程序,第一种是指定长方体的八个顶点坐标,第二种是指定长方体 ...

  3. UFS详细介绍---终章

    UFS详细介绍-终章 UNIVERSAL FLASH STORAGE (UFS),通用闪存存储器.目前最新的标准是UFS4.0:UFS的出现是因为替代eMMC产品的,但是因为价格等,目前没办法做到完全 ...

  4. SSH框架之Hibernate介绍

    什么是Hibernate? Hibernate框架是当今主流的Java持久层框架之一. 持久层最常用的技术有JDBC,DBUtils DBUtils封装的就是JDBC的操作方式,他只是把JDBC的操作 ...

  5. 开始Hibernate介绍

    1.介绍 一个框架 一个Java领域内的持久化框架 一个ORM框架 2.持久化 和数据库相关的各种操作 保存 更新 删除 查询 加载:根据特定的OID,把一个对象从数据库加载到你内存中. OID:为了 ...

  6. 【我看Hibernate】Hibernate 介绍及其简单应用

             作为第一篇关于Hibernate的总结博文,简要说一下Hibernate的基本结构: "Hibernate,是一个开放源代码的对象关系映射框架(ORM),它对JDBC进行了 ...

  7. java分页代码思路,记录--java 分页 思路 (hibernate关键代码)

    有时会脑袋蒙圈,记录下分页的思路 下面代码是hibernate的分页,其分页就是从第几条数据为起点,取几条数据.比如在mysql中的limit(5,10)取的就是第6条到第10条 在下面代码中的pag ...

  8. Hibernate 系列 02 - Hibernate介绍及其环境搭建

    引导目录: Hibernate 系列教程 目录 昨晚喝多了,下午刚清醒,继续搞Hibernate.走起. 觉得还行的话,记得点赞哈,给我这个渣渣点学习的动力.有错误的话也请指出,省的我在错误上走了不归 ...

  9. 十九.激光和惯导LIO-SLAM框架学习之项目工程代码介绍---代码框架和一些文件解释

    专栏系列文章如下: 一:Tixiao Shan最新力作LVI-SAM(Lio-SAM+Vins-Mono),基于视觉-激光-惯导里程计的SLAM框架,环境搭建和跑通过程_goldqiu的博客-CSDN ...

  10. 【介绍+代码实现】使用GradualWarmupScheduler进行学习率预热

    找了一晚上warmup资料,有用的很少,基本都是互相转载,要不就是讲的很空泛,代码没有可使用的价值.但是最后我还是解决了,于是写一个warmup教程造福大家,这里抛砖引玉了. 一.介绍GradualW ...

最新文章

  1. message/maillog日志提示磁盘innode、io错误等,扫描磁盘很多坏道
  2. JavaScript随机生成颜色以及十六进制颜色 与RGB颜色值的相互转换
  3. loadrunner 的脚本语言
  4. 从ncbi下载数据_如何从NCBI下载所有细菌组件
  5. python的scapy_Python Scapy vs dp
  6. 纳达尔复出迎澳网开门红 直落三盘横扫本土选手
  7. 远程使用plsql登陆数据库时,界面提示 ORA-12170 TNS 连接超时
  8. selenium webdriver学习(一)------------快速开始(转载JARVI)
  9. ssm共享图书管理系统毕业设计-附源码151121
  10. ESP-8266wifi模块获取网络实时时间
  11. luoguP4173 残缺的字符串 FFT
  12. 2.11del和pop的区别
  13. 有限元形函数及JuliaFEM中的实现方式
  14. 几种常用的传播木马的方法
  15. Triton服务器部署Yolov5s模型应用
  16. 使用dnsmasq,实现本地的DNS服务
  17. 塞雷三分钟漫画中国史4
  18. 一文读懂“个人经营收款码”和“个人收款码”的区别
  19. 最大化使用51的RAM空间
  20. 手机网站新模式-3G门户HTML5概念版

热门文章

  1. 嵌入式软件工程师岗位要求
  2. 哎 !互联网又偷偷进行了裁员
  3. DotNet 资源大全中文版,内容包括:编译器、压缩、应用框架、应用模板、加密、数据库、反编译、IDE、日志、风格指南等...
  4. Linux 下的桌面指针时钟
  5. 用动画做出一个正方体并且3d旋转,详解
  6. Bada学习-应用模块
  7. 以太坊的区块和存储(二):区块体之叔区块
  8. java 多文字水印_Java如何给Word文档添加多行文字水印
  9. Word 2016使用技巧
  10. 关于计算机的科学思维方法有哪些特点,数学一种科学思维方法有哪些