122.rk3399 uboot(2017.09) 源码分析2-initf_dm(2024-09-09)

这里接着上一篇来吧:

https://blog.csdn.net/zhaozhi0810/article/details/141927053

本文主要是dm_init_and_scan函数的分析,这个内容比较复杂,我也是第一次阅读,错误之处在所难免,请多指教。

uboot的dm框架需要了解一下,看了几行代码发现看不下去了,有点深啊。

(这篇没有写完,有点偷懒了,先发出来,后面再编辑更新吧。因为发现后面的函数都比较简单,要不先把后面的写了。)

我慢慢琢磨一下。

一、c的入口 board_init_f

1.3.11 initf_dm (common/board_f.c)

1.3.11.1 dm_init_and_scan (drivers/core/root.c)

参数 pre_reloc_only 为true

int dm_init_and_scan(bool pre_reloc_only)
{int ret;ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));    //初始化if (ret) {debug("dm_init() failed: %d\n", ret);return ret;}ret = dm_scan_platdata(pre_reloc_only);  //扫描if (ret) {debug("dm_scan_platdata() failed: %d\n", ret);return ret;}if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only);if (ret) {debug("dm_extended_scan_dt() failed: %d\n", ret);return ret;}}ret = dm_scan_other(pre_reloc_only);  //其他设备扫描if (ret)return ret;return 0;
}

1.3.11.1.1  dm_init

参数of_live 等于true

int dm_init(bool of_live)
{int ret;if (gd->dm_root) {   //指针不为空则报出警告,并返回dm_warn("Virtual root driver already exists!\n");return -EINVAL;}INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);   //初始化队列((gd_t *)gd)->uclass_root#if defined(CONFIG_NEEDS_MANUAL_RELOC)  //宏没有定义,略过fix_drivers();fix_uclass();fix_devices();
#endifret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);  //使用名字绑定设备?if (ret)return ret;
#if CONFIG_IS_ENABLED(OF_CONTROL)   //宏有效
# if CONFIG_IS_ENABLED(OF_LIVE)   //宏有效if (of_live)DM_ROOT_NON_CONST->node = np_to_ofnode(gd->of_root);  //执行else
#endifDM_ROOT_NON_CONST->node = offset_to_ofnode(0);
#endifret = device_probe(DM_ROOT_NON_CONST);  //设备探索,这里是个递归函数。貌似比较复杂if (ret)return ret;return 0;
}

1.3.11.1.1.1  device_bind_by_name

从函数名来看,是通过名称来绑定设备。

参数parent = NULL;

pre_reloc_only = false;

info = &root_info

devp = &DM_ROOT_NON_CONST  实际就是 &((((gd_t *)gd)->dm_root))

int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,const struct driver_info *info, struct udevice **devp)
{struct driver *drv;uint platdata_size = 0;drv = lists_driver_lookup_name(info->name);   //参数为“root_driver”if (!drv)return -ENOENT;if (pre_reloc_only && !(drv->flags & DM_FLAG_PRE_RELOC))//pre_reloc_only  为false,不执行return -EPERM;#if CONFIG_IS_ENABLED(OF_PLATDATA)   //宏未定义,跳过platdata_size = info->platdata_size;
#endifreturn device_bind_common(parent, drv, info->name,(void *)info->platdata, 0, ofnode_null(), platdata_size,devp);
}

1.3.11.1.1.1.1 lists_driver_lookup_name函数

参数为:root_driver

这里发现找代码属性段的时候,需要用到的是u-boot.map文件,刚刚也把前面的文章改了过来。

 .u_boot_list_2_driver_1  
                0x00000000002d25c0        0x0 drivers/built-in.o
 .u_boot_list_2_driver_2_analogix_dp
                0x00000000002d25c0       0x78 drivers/built-in.o
                0x00000000002d25c0                _u_boot_list_2_driver_2_analogix_dp
 .u_boot_list_2_driver_2_arasan_sdhci_drv
                0x00000000002d2638       0x78 drivers/built-in.o
                0x00000000002d2638                _u_boot_list_2_driver_2_arasan_sdhci_drv
 .u_boot_list_2_driver_2_clk_fixed_rate
                0x00000000002d26b0       0x78 drivers/built-in.o
                0x00000000002d26b0                _u_boot_list_2_driver_2_clk_fixed_rate
 .u_boot_list_2_driver_2_clk_rk3399
                0x00000000002d2728       0x78 drivers/built-in.o
                0x00000000002d2728                _u_boot_list_2_driver_2_clk_rk3399
 .u_boot_list_2_driver_2_dmc_rk3399
                0x00000000002d27a0       0x78 drivers/built-in.o
                0x00000000002d27a0                _u_boot_list_2_driver_2_dmc_rk3399
 .u_boot_list_2_driver_2_dw_mipi_dsi
                0x00000000002d2818       0x78 drivers/built-in.o
                0x00000000002d2818                _u_boot_list_2_driver_2_dw_mipi_dsi
 .u_boot_list_2_driver_2_ehci_generic
                0x00000000002d2890       0x78 drivers/usb/host/built-in.o
                0x00000000002d2890                _u_boot_list_2_driver_2_ehci_generic
 .u_boot_list_2_driver_2_eth_designware
                0x00000000002d2908       0x78 drivers/net/built-in.o
                0x00000000002d2908                _u_boot_list_2_driver_2_eth_designware
 .u_boot_list_2_driver_2_eth_gmac_rockchip
                0x00000000002d2980       0x78 drivers/net/built-in.o
                0x00000000002d2980                _u_boot_list_2_driver_2_eth_gmac_rockchip
 .u_boot_list_2_driver_2_fixed_regulator
                0x00000000002d29f8       0x78 drivers/power/regulator/built-in.o
                0x00000000002d29f8                _u_boot_list_2_driver_2_fixed_regulator
 .u_boot_list_2_driver_2_generic_syscon
                0x00000000002d2a70       0x78 drivers/built-in.o
                0x00000000002d2a70                _u_boot_list_2_driver_2_generic_syscon
 .u_boot_list_2_driver_2_gpio_rockchip
                0x00000000002d2ae8       0x78 drivers/gpio/built-in.o
                0x00000000002d2ae8                _u_boot_list_2_driver_2_gpio_rockchip
 .u_boot_list_2_driver_2_i2c_generic_chip_drv
                0x00000000002d2b60       0x78 drivers/i2c/built-in.o
                0x00000000002d2b60                _u_boot_list_2_driver_2_i2c_generic_chip_drv
 .u_boot_list_2_driver_2_i2c_rockchip
                0x00000000002d2bd8       0x78 drivers/i2c/built-in.o
                0x00000000002d2bd8                _u_boot_list_2_driver_2_i2c_rockchip
 .u_boot_list_2_driver_2_mmc
                0x00000000002d2c50       0x78 drivers/built-in.o
                0x00000000002d2c50                _u_boot_list_2_driver_2_mmc
 .u_boot_list_2_driver_2_mmc_blk
                0x00000000002d2cc8       0x78 drivers/built-in.o
                0x00000000002d2cc8                _u_boot_list_2_driver_2_mmc_blk
 .u_boot_list_2_driver_2_ns16550_serial
                0x00000000002d2d40       0x78 drivers/serial/built-in.o
                0x00000000002d2d40                _u_boot_list_2_driver_2_ns16550_serial
 .u_boot_list_2_driver_2_ohci_generic
                0x00000000002d2db8       0x78 drivers/usb/host/built-in.o
                0x00000000002d2db8                _u_boot_list_2_driver_2_ohci_generic
 .u_boot_list_2_driver_2_pinconfig_generic
                0x00000000002d2e30       0x78 drivers/built-in.o
                0x00000000002d2e30                _u_boot_list_2_driver_2_pinconfig_generic
 .u_boot_list_2_driver_2_pinctrl_rockchip
                0x00000000002d2ea8       0x78 drivers/built-in.o
                0x00000000002d2ea8                _u_boot_list_2_driver_2_pinctrl_rockchip
 .u_boot_list_2_driver_2_pmic_rk8xx
                0x00000000002d2f20       0x78 drivers/power/pmic/built-in.o
                0x00000000002d2f20                _u_boot_list_2_driver_2_pmic_rk8xx
 .u_boot_list_2_driver_2_psci
                0x00000000002d2f98       0x78 drivers/built-in.o
                0x00000000002d2f98                _u_boot_list_2_driver_2_psci
 .u_boot_list_2_driver_2_psci_sysreset
                0x00000000002d3010       0x78 drivers/built-in.o
                0x00000000002d3010                _u_boot_list_2_driver_2_psci_sysreset
 .u_boot_list_2_driver_2_pwm_backlight
                0x00000000002d3088       0x78 drivers/built-in.o
                0x00000000002d3088                _u_boot_list_2_driver_2_pwm_backlight
 .u_boot_list_2_driver_2_pwm_regulator
                0x00000000002d3100       0x78 drivers/power/regulator/built-in.o
                0x00000000002d3100                _u_boot_list_2_driver_2_pwm_regulator
 .u_boot_list_2_driver_2_rk8xx_buck
                0x00000000002d3178       0x78 drivers/power/regulator/built-in.o
                0x00000000002d3178                _u_boot_list_2_driver_2_rk8xx_buck
 .u_boot_list_2_driver_2_rk8xx_ldo
                0x00000000002d31f0       0x78 drivers/power/regulator/built-in.o
                0x00000000002d31f0                _u_boot_list_2_driver_2_rk8xx_ldo
 .u_boot_list_2_driver_2_rk8xx_switch
                0x00000000002d3268       0x78 drivers/power/regulator/built-in.o
                0x00000000002d3268                _u_boot_list_2_driver_2_rk8xx_switch
 .u_boot_list_2_driver_2_rk_pwm
                0x00000000002d32e0       0x78 drivers/built-in.o
                0x00000000002d32e0                _u_boot_list_2_driver_2_rk_pwm
 .u_boot_list_2_driver_2_rockchip_crypto_v1
                0x00000000002d3358       0x78 drivers/built-in.o
                0x00000000002d3358                _u_boot_list_2_driver_2_rockchip_crypto_v1
 .u_boot_list_2_driver_2_rockchip_display
                0x00000000002d33d0       0x78 drivers/built-in.o
                0x00000000002d33d0                _u_boot_list_2_driver_2_rockchip_display
 .u_boot_list_2_driver_2_rockchip_dw_hdmi
                0x00000000002d3448       0x78 drivers/built-in.o
                0x00000000002d3448                _u_boot_list_2_driver_2_rockchip_dw_hdmi
 .u_boot_list_2_driver_2_rockchip_dwmmc_drv
                0x00000000002d34c0       0x78 drivers/built-in.o
                0x00000000002d34c0                _u_boot_list_2_driver_2_rockchip_dwmmc_drv
 .u_boot_list_2_driver_2_rockchip_efuse
                0x00000000002d3538       0x78 drivers/built-in.o
                0x00000000002d3538                _u_boot_list_2_driver_2_rockchip_efuse
 .u_boot_list_2_driver_2_rockchip_lvds
                0x00000000002d35b0       0x78 drivers/built-in.o
                0x00000000002d35b0                _u_boot_list_2_driver_2_rockchip_lvds
 .u_boot_list_2_driver_2_rockchip_panel
                0x00000000002d3628       0x78 drivers/built-in.o
                0x00000000002d3628                _u_boot_list_2_driver_2_rockchip_panel
 .u_boot_list_2_driver_2_rockchip_reset
                0x00000000002d36a0       0x78 drivers/built-in.o
                0x00000000002d36a0                _u_boot_list_2_driver_2_rockchip_reset
 .u_boot_list_2_driver_2_rockchip_rgb
                0x00000000002d3718       0x78 drivers/built-in.o
                0x00000000002d3718                _u_boot_list_2_driver_2_rockchip_rgb
 .u_boot_list_2_driver_2_rockchip_rk3399_pmuclk
                0x00000000002d3790       0x78 drivers/built-in.o
                0x00000000002d3790                _u_boot_list_2_driver_2_rockchip_rk3399_pmuclk
 .u_boot_list_2_driver_2_rockchip_saradc
                0x00000000002d3808       0x78 drivers/built-in.o
                0x00000000002d3808                _u_boot_list_2_driver_2_rockchip_saradc
 .u_boot_list_2_driver_2_rockchip_usb2phy
                0x00000000002d3880       0x78 drivers/built-in.o
                0x00000000002d3880                _u_boot_list_2_driver_2_rockchip_usb2phy
 .u_boot_list_2_driver_2_rockchip_usb2phy_port
                0x00000000002d38f8       0x78 drivers/built-in.o
                0x00000000002d38f8                _u_boot_list_2_driver_2_rockchip_usb2phy_port
 .u_boot_list_2_driver_2_rockchip_vop
                0x00000000002d3970       0x78 drivers/built-in.o
                0x00000000002d3970                _u_boot_list_2_driver_2_rockchip_vop
 .u_boot_list_2_driver_2_root_driver
                0x00000000002d39e8       0x78 drivers/built-in.o
                0x00000000002d39e8                _u_boot_list_2_driver_2_root_driver
 .u_boot_list_2_driver_2_simple_bus_drv
                0x00000000002d3a60       0x78 drivers/built-in.o
                0x00000000002d3a60                _u_boot_list_2_driver_2_simple_bus_drv
 .u_boot_list_2_driver_2_simple_panel
                0x00000000002d3ad8       0x78 drivers/built-in.o
                0x00000000002d3ad8                _u_boot_list_2_driver_2_simple_panel
 .u_boot_list_2_driver_2_spi_generic_drv
                0x00000000002d3b50       0x78 drivers/spi/built-in.o
                0x00000000002d3b50                _u_boot_list_2_driver_2_spi_generic_drv
 .u_boot_list_2_driver_2_syscon_rk3399
                0x00000000002d3bc8       0x78 arch/arm/mach-rockchip/built-in.o
                0x00000000002d3bc8                _u_boot_list_2_driver_2_syscon_rk3399
 .u_boot_list_2_driver_2_sysreset_rockchip
                0x00000000002d3c40       0x78 drivers/built-in.o
                0x00000000002d3c40                _u_boot_list_2_driver_2_sysreset_rockchip
 .u_boot_list_2_driver_2_sysreset_syscon_reboot
                0x00000000002d3cb8       0x78 drivers/built-in.o
                0x00000000002d3cb8                _u_boot_list_2_driver_2_sysreset_syscon_reboot
 .u_boot_list_2_driver_2_usb_dev_generic_drv
                0x00000000002d3d30       0x78 drivers/usb/host/built-in.o
                0x00000000002d3d30                _u_boot_list_2_driver_2_usb_dev_generic_drv
 .u_boot_list_2_driver_2_usb_generic_hub
                0x00000000002d3da8       0x78 common/built-in.o
                0x00000000002d3da8                _u_boot_list_2_driver_2_usb_generic_hub
 .u_boot_list_2_driver_2_usb_mass_storage
                0x00000000002d3e20       0x78 common/built-in.o
                0x00000000002d3e20                _u_boot_list_2_driver_2_usb_mass_storage
 .u_boot_list_2_driver_2_usb_storage_blk
                0x00000000002d3e98       0x78 common/built-in.o
                0x00000000002d3e98                _u_boot_list_2_driver_2_usb_storage_blk
 .u_boot_list_2_driver_2_vidconsole_normal
                0x00000000002d3f10       0x78 drivers/built-in.o
                0x00000000002d3f10                _u_boot_list_2_driver_2_vidconsole_normal
 .u_boot_list_2_driver_2_xhci_dwc3
                0x00000000002d3f88       0x78 drivers/usb/host/built-in.o
                0x00000000002d3f88                _u_boot_list_2_driver_2_xhci_dwc3
 .u_boot_list_2_driver_3
                0x00000000002d4000        0x0 drivers/built-in.o

.u_boot_list_2_driver_1 是驱动开始标记

.u_boot_list_2_driver_3 是驱动结束标记

.u_boot_list_2_driver_2_xx  就是加入的设备驱动。(粗略数了一下,有56个驱动)。

要查找的root_driver也是存在的!!

结构体的首地址,很有可能就是0x00000000002d39e8

用这几个驱动的地址相减得到的差值0x78来看,应该就是结构体的首地址。

1.3.11.1.1.1.2  device_bind_common 函数

稍微看了一下代码之后,这次这个函数的目的是新建root_driver的设备。

参数:

parent --> NULL

drv --> drv指针,应该就是root_driver 的首地址

name --> root_driver

platdata --> info.platdata --> NULL

driver_data --> 0

node --> 一个空的node (ofnode类型)

of_platdata_size -->platdata_size --> 0

devp --> &(((gd_t *)gd)->dm_root)

static int device_bind_common(struct udevice *parent, const struct driver *drv,const char *name, void *platdata,ulong driver_data, ofnode node,uint of_platdata_size, struct udevice **devp)
{struct udevice *dev;struct uclass *uc;int size, ret = 0;if (devp)   //指针不为空,执行*devp = NULL;   //指向空,在函数最后会赋值if (!name)   //有一个字符串“root_driver”return -EINVAL;ret = uclass_get(drv->id, &uc);  //id也是有的,在结构体中,UCLASS_ROOT,在文件root.c中if (ret) {debug("Missing uclass for driver %s\n", drv->name);return ret;}#ifdef CONFIG_USING_KERNEL_DTB  //这个宏定义了。if (gd->flags & GD_FLG_RELOC) {   //这个flag没有设置,需要到board_r.c的阶段,这个if不执行/* For mmc/nand/spiflash, just update from kernel dtb instead bind again*/if (drv->id == UCLASS_MMC || drv->id == UCLASS_RKNAND ||drv->id == UCLASS_SPI_FLASH || drv->id == UCLASS_MTD) {list_for_each_entry(dev, &uc->dev_head, uclass_node) {if (!strcmp(name, dev->name)) {debug("%s do not bind dev already in list %s\n",__func__, dev->name);/** There is no clearly reason for this* legacy code, but remain it here since* everything seems fine with or without* this. Maybe removed in the future.*/dev->node = node;return 0;}}}/* Use other nodes from kernel dtb */struct udevice *n;list_for_each_entry_safe(dev, n, &uc->dev_head, uclass_node) {if (!strcmp(name, dev->name) &&(dev_read_bool(dev, "u-boot,dm-pre-reloc") ||dev_read_bool(dev, "u-boot,dm-spl"))) {/* Always use crypto node from U-Boot dtb */if (drv->id == UCLASS_CRYPTO) {debug("%s do not delete uboot dev: %s\n",__func__, dev->name);return 0;} else {list_del_init(&dev->uclass_node);}}}}
#endifdev = calloc(1, sizeof(struct udevice));  //分配struct udevice空间if (!dev)return -ENOMEM;INIT_LIST_HEAD(&dev->sibling_node);  //初始化列表INIT_LIST_HEAD(&dev->child_head);INIT_LIST_HEAD(&dev->uclass_node);
#ifdef CONFIG_DEVRES     //宏未定义INIT_LIST_HEAD(&dev->devres_head);
#endifdev->platdata = platdata;   //赋值,NULLdev->driver_data = driver_data; //0dev->name = name;  //“root_driver”dev->node = node;   //一个空的nodedev->parent = parent;  //NULL,dev->driver = drv;  //对应root_driver结构体首地址dev->uclass = uc;  //前文中获取,id对应UCLASS_ROOTdev->seq = -1;   //-1==nonedev->req_seq = -1;  //-1==anyif (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS)) {  //查看.config,两个宏都有定义/** Some devices, such as a SPI bus, I2C bus and serial ports* are numbered using aliases.** This is just a 'requested' sequence, and will be* resolved (and ->seq updated) when the device is probed.*/if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {  //没有设置该flagif (uc->uc_drv->name && ofnode_valid(node)) {dev_read_alias_seq(dev, &dev->req_seq);}}}if (drv->platdata_auto_alloc_size) {  //没有设置,root.cbool alloc = !platdata;if (CONFIG_IS_ENABLED(OF_PLATDATA)) {if (of_platdata_size) {dev->flags |= DM_FLAG_OF_PLATDATA;if (of_platdata_size <drv->platdata_auto_alloc_size)alloc = true;}}if (alloc) {dev->flags |= DM_FLAG_ALLOC_PDATA;dev->platdata = calloc(1,drv->platdata_auto_alloc_size);if (!dev->platdata) {ret = -ENOMEM;goto fail_alloc1;}if (CONFIG_IS_ENABLED(OF_PLATDATA) && platdata) {memcpy(dev->platdata, platdata,of_platdata_size);}}}size = uc->uc_drv->per_device_platdata_auto_alloc_size; //没有设置,root.cif (size) {dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA;dev->uclass_platdata = calloc(1, size);if (!dev->uclass_platdata) {ret = -ENOMEM;goto fail_alloc2;}}if (parent) { //parent = NULL,不执行size = parent->driver->per_child_platdata_auto_alloc_size;if (!size) {size = parent->uclass->uc_drv->per_child_platdata_auto_alloc_size;}if (size) {dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA;dev->parent_platdata = calloc(1, size);if (!dev->parent_platdata) {ret = -ENOMEM;goto fail_alloc3;}}}/* put dev into parent's successor list */if (parent)//parent = NULL,不执行list_add_tail(&dev->sibling_node, &parent->child_head);ret = uclass_bind_device(dev);  //插入到链表中if (ret)goto fail_uclass_bind;/* if we fail to bind we remove device from successors and free it */if (drv->bind) {  //没有实现该函数ret = drv->bind(dev);if (ret)goto fail_bind;}if (parent && parent->driver->child_post_bind) { //parent = NULL,不执行 ret = parent->driver->child_post_bind(dev);if (ret)goto fail_child_post_bind;}if (uc->uc_drv->post_bind) {//驱动中没有,不执行ret = uc->uc_drv->post_bind(dev);if (ret)goto fail_uclass_post_bind;}if (parent)//parent = NULL,不执行pr_debug("Bound device %s to %s\n", dev->name, parent->name);if (devp)*devp = dev;   //dev通过参数返回dev->flags |= DM_FLAG_BOUND;return 0;fail_uclass_post_bind:/* There is no child unbind() method, so no clean-up required */
fail_child_post_bind:if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) {if (drv->unbind && drv->unbind(dev)) {dm_warn("unbind() method failed on dev '%s' on error path\n",dev->name);}}fail_bind:if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) {if (uclass_unbind_device(dev)) {dm_warn("Failed to unbind dev '%s' on error path\n",dev->name);}}
fail_uclass_bind:if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) {list_del(&dev->sibling_node);if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {free(dev->parent_platdata);dev->parent_platdata = NULL;}}
fail_alloc3:if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) {free(dev->uclass_platdata);dev->uclass_platdata = NULL;}
fail_alloc2:if (dev->flags & DM_FLAG_ALLOC_PDATA) {free(dev->platdata);dev->platdata = NULL;}
fail_alloc1:devres_release_all(dev);free(dev);return ret;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/423643.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 面试题11-27

11、Mybatis 是如何将 sql 执行结果封装为目标对象并返回的? 都有哪些映射形式&#xff1f; Mybatis 在执行 SQL 查询后&#xff0c;会将结果集封装为目标对象并返回。这主要依赖于 Mybatis 的映射机制&#xff0c;它提供了两种主要的映射形式&#xff1a; 第一种&#xff1…

代码质量护航:结合Checkstyle、SpringBoot与Git的最佳实践

在团队开发中&#xff0c;保持一致的代码风格和高质量的代码至关重要。为了提升团队的整体代码质量&#xff0c;防止低质量代码的提交&#xff0c;使用工具对代码进行自动化检查是非常有效的手段之一。在这篇博客中&#xff0c;我将介绍如何通过结合 Checkstyle、Spring Boot 和…

Zotero使用(一)PDF文件导入不会自动识别

上面两种&#xff0c;一种中文&#xff0c;一种英文&#xff0c;会发现&#xff0c;中文的导入进去之后不会自动识别&#xff0c;部分英文也是。不能自动识别就会缺少导出参考文献的功能&#xff0c;怎么办&#xff1f; 发现之前导入喜欢使用PDF格式 可以结合.ris格式&#xf…

网络安全 day5 --- 反弹SHELL不回显带外正反向连接防火墙出入站文件下载

免责声明 本免责声明适用于作者所有文章内容。使用者需明确&#xff0c;网络安全技术仅供学习和合法研究使用&#xff0c;不得用于任何非法活动&#xff0c;如未经授权的入侵、攻击或数据窃取&#xff0c;所有相关法律责任由使用者自行承担。由于网络安全操作可能带来系统崩溃、…

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统 在产品将要上线之前&#xff0c;需要制作不同类型格式的根文件系统 在产品研发阶段&#xff0c;我们还是需要使用nfs的方式挂载根文件系统 优点&#xff1a;可以直接在上位机中修改文件系统内容&#xff0c;延长EMMC的寿命 【1】重启上位机nfs服…

【计算机网络】HTTPHTTPS

HTTP&HTTPS HTTP协议初识HTTP如何抓包Fiddler的使用抓包查看包的信息 报文格式请求报文响应报文报文对比 URLHTTP方法认识Header初识状态码 HTTPS协议为什么需要 HTTPS加密基础知识HTTPS的工作流程引入对称加密引入非对称加密引入证书HTTPS 的工作流程 浏览器从输入URL到展…

短视频剪辑从简单到复杂,这四款很OK!

作为一个刚刚踏入视频剪辑世界的新手&#xff0c;我最近可是忙得不亦乐乎。我尝试了四款流行的视频剪辑软件&#xff0c;今天&#xff0c;就让我来和大家分享一下我的使用感受&#xff0c;看看哪款软件更适合我们这些初学者。这里先说一句&#xff0c;选择视频剪辑软件就像挑衣…

opencv学习:calcHist 函数绘制图像直方图及代码实现

cv2.calcHist 函数是 OpenCV 库中用于计算图像直方图的函数。直方图是一种统计图像中像素值分布的工具&#xff0c;它可以提供图像的亮度、颜色等信息。这个函数可以用于灰度图像和彩色图像。 函数语法 hist cv2.calcHist(images, channels, mask, histSize, ranges, accumu…

解决 PyCharm 无法启动 Jupyter 服务器的问题:报错分析与解决方案

文章目录 报错背景报错详细信息解决方案pycharm 设置 报错背景 在使用 pycharm 付费版的过程中&#xff0c;发现一直无法启动 jupyter 服务器。 一直也不知道是为什么&#xff0c;直到在终端输入&#xff1a; jupyter notebook发现 jupyter 服务无法启动。 报错详细信息 下…

数据库系列之GaussDB数据库中逻辑对象关系简析

初次接触openGauss或GaussDB数据库的逻辑对象&#xff0c;被其中的表空间、数据库、schema和用户之间的关系&#xff0c;以及授权管理困惑住了&#xff0c;与熟悉的MySQL数据库的逻辑对象又有明显的不同。本文旨在简要梳理下GaussDB数据库逻辑对象之间的关系&#xff0c;以加深…

浅谈EXT2文件系统(1)

简介 EXT2&#xff08;Second Extended Filesystem&#xff09;文件系统是Linux操作系统的早期文件系统之一&#xff0c;它于 1993 年推出&#xff0c;是第一个旨在克服 Ext 文件系统限制的商业文件系统。EXT2 没有日志功能&#xff0c;EXT2 支持的单个文件大小为 2TB&#xf…

如何在Word中插入复选框

如何在Word中插入复选框&#xff1a;详细教程与技巧 在Word中插入复选框是一项非常实用的技巧&#xff0c;尤其是在制作问卷调查、待办事项清单、交互式表单或文档中需要用户进行选择时&#xff0c;复选框不仅能提高文档的功能性&#xff0c;还能显得更加专业。本文将详细讲解…

不小心把回收站清空了怎么恢复?别慌!四招找回

在日常使用电脑的过程中&#xff0c;我们可能会不小心清空回收站&#xff0c;从而丢失一些重要的文件。当遇到这种情况时&#xff0c;很多人可能会感到焦虑和无助。然而&#xff0c;幸运的是&#xff0c;有一些方法可以帮助我们尝试恢复这些被删除的文件。下面&#xff0c;我们…

大数据-133 - ClickHouse 基础概述 全面了解

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

关于【禁止new对象时在for循环内定义申明变量】

文章目录 简介代码分析反编译之后对比性能测试内存与垃圾回收情况JDK和常用框架怎么写总结依赖 简介 不知道是谁最先提出了一个不要将变量定义在循环内。 然后我们在代码扫描中有一项是&#xff1a;【禁止new对象时在for循环内定义申明变量】 我也好奇为什么不能&#xff1f…

如何利用MES系统进行产品质量全流程追溯

利用MES&#xff08;制造执行系统&#xff09;系统进行产品质量全流程追溯&#xff0c;是一个系统化和精细化的过程&#xff0c;主要涉及数据采集、信息整合、过程控制、查询分析以及持续优化等多个环节。以下是如何具体利用MES系统进行产品质量全流程追溯的步骤&#xff1a; 一…

centos(在线、离线)安装iptables

Iptables 是 Linux 操作系统中的一个用户空间工具&#xff0c;用来配置 Linux 内核中的 Netfilter 防火墙模块。它主要负责网络数据包的过滤、网络地址转换 (NAT) 以及配置防火墙规则。centos默认的防火墙管理工具是Firewalld&#xff0c;所以iptables需要下载安装。 目录 一…

嵌入式软件工程师:科技浪潮中的关键角色

嵌入式软件工程师&#xff1a;科技浪潮中的关键角色 一、嵌入式软件工程师的职业魅力 &#xff08;一&#xff09;市场需求旺盛 嵌入式软件工程师在当今科技领域中扮演着至关重要的角色。随着智能化时代的到来&#xff0c;嵌入式系统在各个行业的应用越来越广泛&#xff0c;市…

【贪心算法】贪心算法

贪心算法简介 1.什么是贪心算法2.贪心算法的特点3.学习贪心的方向 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.什么是贪心算法 与其说是…

[linux基础知识]教你使用vim和ctags阅读linux内核源码

1 安装ctags apt install ctags 2 内核源码目录下添加索引 使用下面命令&#xff0c;添加索引成功后&#xff0c;内核目录下会生成tags 索引文件。 ctags -R 3 vim使用索引阅读源码 跳转到函数变量定义与返回 #跳到函数或者变量定义 Ctrl] #返回 Ctrlo 光标移动到需要…