lv12 uboot移植深化 9

u-boot-2013.01移植

【实验目的】

了解u-boot 的代码结构及移植的基本方法

【实验环境】

  1. ubuntu 14.04发行版
  2. FS4412实验平台
  3. 交叉编译工具arm-none-linux-gnueabi-

注意事项

      实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行

【实验步骤】

1 建立自己的平台

1.1 下载uboot源码

uboot官网下载uboot源码(这里我们选择u-boot-2013.01.tar.bz2

ftp://ftp.denx.de/pub/u-boot/

1.2解压uboot源码

拷贝uboot源码包到ubuntu的家目录下,解压并进入其顶层目录

$ tar xvf u-boot-2013.01.tar.bz2
$ cd u-boot-2013.01/

1.3 指定交叉编译工具信息 

uboot源码并不知道我们使用的处理器架构及交叉编译工具是什么,这里我们需要自己 在Makefile中指定

$ vi Makefile

feq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif

修改为如下内容(注意后边不要有多余的空格),然后保存退出

ifeq (arm,arm)
CROSS_COMPILE ?= arm-none-linux-gnueabi-
endif

1.4 添加Board信息 

因为uboot源码并不支持我们的开发板,这里我们需要从源码支持的开发板中找一个硬 件与我们最类似的,在其基础上进行修改,这里我们参考的是samsung公司的origen

$ cp -rf board/samsung/origen/ board/samsung/fs4412$ mv board/samsung/fs4412/origen.c board/samsung/fs4412/fs4412.c

因为修改了文件名,所以对应的Makefile也要修改

$ vi board/samsung/fs4412/Makefile

ifndef CONFIG_SPL_BUILDCOBJS += origen.oendif

修改为如下内容,然后保存退出

ifndef CONFIG_SPL_BUILDCOBJS += fs4412.oendif

拷贝origen相关的头文件并将其重命名

$ cp include/configs/origen.h include/configs/fs4412.h

修改文件中的信息

$ vi include/configs/fs4412.h

#define CONFIG_SYS_PROMPT "ORIGEN #"

修改为如下内容

#define CONFIG_SYS_PROMPT "fs4412 #"

再将

#define CONFIG_IDENT_STRING " for ORIGEN"

修改为如下内容,然后保存退出。这块影响的是启动打印信息

#define CONFIG_IDENT_STRING "for fs4412"

打开uboot源码顶层目录下的boards.cfg文件

$ vi boards.cfg

origen arm armv7 origen samsung exynos

后添加如下内容(FS4412的相关信息),然后保存退出。

fs4412 arm armv7 fs4412 samsung exynos

至此我们在uboot源码中给我们的板子添加了“档案”,源码就支持我们的开发板了

1.5 编译uboot

在uboot源码顶层目录下执行如下命令,指定当前使用的Board信息

$ make fs4412_config

编译uboot

$ make

编译完成后会在源码顶层目录下生成u-boot.bin文件,但该文件还不能在我们的开发板 上运行,因为以上操作我们只是把origen相关的文件的名字改成了fs4412,使uboot能 识别fs4412开发板,但文件中的代码还是origen的,和我们的开发板不匹配,所以我 们还需要进一步进行修改和配置

2 添加三星加密引导方式

考虑芯片启动的安全性,Exynos4412需要三星提供的初始引导加密后我们的u-boot才 能被引导运行,所以我们需要在uboot源码中添加三星提供的加密处理代码。(uboot是开源的,所以很多厂家为了安全性采用了加密引导)

2.1 添加三星加密引导方式

将资料中“移植相关文件”下的sdfuse_q和CodeSign4SecureBoot目录拷贝到uboot源 码的顶层目录下(这之后不要执行make clean或make distclean,这会将加密文件清除

因为添加的加密文件也要编译,所以对应的Makefile也要修改

$ vi Makefile 

$(obj)u-boot.bin: $(obj)u-boot$(OBJCOPY)${OBJCFLAGS} -O binary $< $@$(BOARD_SIZE_CHECK)

后添加如下内容(添加的内容需要tab键缩进,否则编译报错),然后保存退出

@#./mkuboot
@split -b 14336 u-boot.bin bl2
@+make -C sdfuse_q/
@#cp u-boot.bin u-boot-4212.bin
@#cp u-boot.bin u-boot-4412.bin
@#./sdfuse_q/add_sign
@./sdfuse_q/chksum
@./sdfuse_q/add_padding
@rm bl2a*
@echo

2.2 添加调试代码(点灯法)

很多时候我们不确定uboot是否已经在板子上运行,所以我们在uboot源码中添加一段 代码使板子上的LED点亮,这样如果看到LED亮的话就表示uboot已经在运行了

打开uboot启动后的第一段代码

$ vi arch/arm/cpu/armv7/start.S

在第134行后添加如下代码(即点亮LED2),然后保存退出

ldr r0, =0x11000c40
ldr r1, [r0]
bic r1, r1, #0xf0000000
orr r1, r1, #0x10000000
str r1, [r0]
ldr r0, =0x11000c44
mov r1, #0xff
str r1, [r0]

​​​​​​2.3 添加编译脚本

使用make命令编译时只链接uboot源码中的相关代码,而我们添加的初始引导加密 代码不会被连接到u-boot.bin中,所以这里我们自己编写编译脚本build.sh,这个脚本 中除了对uboot源码进行配置和编译外还将初始引导加密代码链接到了u-boot.bin上, 最终生成一个完成的uboot镜像u-boot-fs4412.bin

将资料中“移植相关文件下的build.sh拷贝到uboot源码的顶层目录

给编译脚本添加可执行权限

$ chmod 777 build.sh

build.sh中内容主要是实现make fs4412_config 和make -j 多核数

 把三星的引导文件合并为了u-boot-fs4412.bin(不需要过多了解)

2.4 编译uboot

通过脚本编译uboot源码

$ ./build.sh

编译完成后在源码的顶层目录下会生成“u-boot-fs4412.bin”

2.5 测试uboot

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动, 然后上电查看现象,若LED2点亮则说明我自己移植的u-boot已经能够被加载运行

3 实现串口输出

虽然uboot已经能在开发板上加载运行,但是此时的uboot还不能在终端上打印信息, 原因在于uboot源码中对UART的配置与我们实际的硬件不匹配

3.1 修改UART源码

$ vi board/samsung/fs4412/lowlevel_init.S

lowlevel_init:

后添加如下内容(初始化临时栈)

dr sp,=0x02060000

beq wakeup_reset

后添加如下内容(关闭看门狗)

#if 1ldr r0, =0x1002330cldr r1, [r0]orr r1, r1, #0x300str r1, [r0]ldr r0, =0x11000c08ldr r1, =0x0str r1, [r0]/* Clear  MASK_WDT_RESET_REQUEST  */ldr r0, =0x1002040cldr r1, =0x00str r1, [r0]#endif

uart_asm_init:/* setup UART0-UART3 GPIOs (part1) */mov r0, r7ldr r1, =EXYNOS4_GPIO_A0_CON_VALstr r1, [r0, #EXYNOS4_GPIO_A0_CON_OFFSET]ldr r1, =EXYNOS4_GPIO_A1_CON_VALstr r1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET]

后添加如下内容(UART初始化)

ldr r0, =0x10030000ldr r1, =0x666666ldr r2, =CLK_SRC_PERIL0_OFFSETstr r1, [r0, r2]ldr r1, =0x777777ldr r2, =CLK_DIV_PERIL0_OFFSETstr r1, [r0, r2]

注释掉

bl uart_asm_init

后的一条语句,然后保存退出

#if 0bl tzpc_init#endif

3.2 编译uboot

通过脚本编译uboot源码

$ ./build.sh

3.3 测试uboot

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动, 然后上电查看现象,若终端有打印信息则说明UART移植成功

网卡移植

虽然可以通过终端输入命令,但此时的uboot还不能使用ping、tftp等命令,原因在于 命令都是操作网络的,而uboot源码中网卡的相关配置与我们当前的板子不匹配,所以 我们还要对网卡进行移植

4.1 修改网络初始化代码

$ vi board/samsung/fs4412/fs4412.c

struct exynos4_gpio_part2 *gpio2;

后添加如下内容

#ifdef  CONFIG_DRIVER_DM9000#define EXYNOS4412_SROMC_BASE 0X12570000#define DM9000_Tacs     (0x1)#define DM9000_Tcos     (0x1)#define DM9000_Tacc     (0x5)#define DM9000_Tcoh     (0x1)#define DM9000_Tah      (0xC)#define DM9000_Tacp     (0x9)   #define DM9000_PMC      (0x1)  struct exynos_sromc {unsigned int bw;unsigned int bc[6];};void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf){unsigned int tmp;struct exynos_sromc *srom = (struct exynos_sromc *)(EXYNOS4412_SROMC_BASE);/* Configure SMC_BW register to handle proper SROMC bank */tmp = srom->bw;tmp &= ~(0xF << (srom_bank * 4));tmp |= srom_bw_conf;srom->bw = tmp;/* Configure SMC_BC register */srom->bc[srom_bank] = srom_bc_conf;}static void dm9000aep_pre_init(void){unsigned int tmp;unsigned char smc_bank_num = 1;unsigned int     smc_bw_conf=0;unsigned int     smc_bc_conf=0;/* gpio configuration */writel(0x00220020, 0x11000000 + 0x120);writel(0x00002222, 0x11000000 + 0x140);/* 16 Bit bus width */writel(0x22222222, 0x11000000 + 0x180);writel(0x0000FFFF, 0x11000000 + 0x188);writel(0x22222222, 0x11000000 + 0x1C0);writel(0x0000FFFF, 0x11000000 + 0x1C8);writel(0x22222222, 0x11000000 + 0x1E0);writel(0x0000FFFF, 0x11000000 + 0x1E8);              smc_bw_conf &= ~(0xf<<4);smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4);smc_bc_conf = ((DM9000_Tacs << 28)| (DM9000_Tcos << 24)| (DM9000_Tacc << 16)| (DM9000_Tcoh << 12)| (DM9000_Tah  << 8)| (DM9000_Tacp << 4)| (DM9000_PMC));exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf);}#endif

gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);

后添加如下内容

#ifdef CONFIG_DRIVER_DM9000dm9000aep_pre_init();#endif

在文件末尾添加如下内容,然后保存退出

#ifdef CONFIG_CMD_NETint board_eth_init(bd_t *bis)                                                  {      int rc = 0;#ifdef CONFIG_DRIVER_DM9000rc = dm9000_initialize(bis);                                            #endif                                                                         return rc;                                                              }  #endif

​​​​​​​4.2 修改网络配置代码

$ vi include/configs/fs4412.h

#undef CONFIG_CMD_PING

修改为

#define CONFIG_CMD_PING

再将

#undef CONFIG_CMD_NET

修改为

#define CONFIG_CMD_NET

在文件末尾

#endif /* __CONFIG_H */

前添加如下内容,然后保存退出

#ifdef  CONFIG_CMD_NET#define CONFIG_NET_MULTI#define CONFIG_DRIVER_DM9000 1#define CONFIG_DM9000_BASE 0x05000000#define DM9000_IO CONFIG_DM9000_BASE#define DM9000_DATA (CONFIG_DM9000_BASE + 4)#define CONFIG_DM9000_USE_16BIT#define CONFIG_DM9000_NO_SROM 1#define CONFIG_ETHADDR 11:22:33:44:55:66#define CONFIG_IPADDR 192.168.9.200#define CONFIG_SERVERIP 192.168.9.120#define CONFIG_GATEWAYIP 192.168.9.1#define CONFIG_NETMASK 255.255.255.0#endif

​​​​​​​4.3 编译uboot

通过脚本编译uboot源码

$ ./build.sh

​​​​​​​4.4 测试uboot

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动, 然后上电查看现象;设置好相关的环境变量,使用网线连接开发板与开发主机,使用 ping命令连接ubuntu,若显示“host xxx.xxx.xxx.xxx is alive”则表示网卡移植成功

​​​​​​​5 EMMC移植

因为uboot源码中对EMMC的配置与我们的板子不匹配,这里还需要对EMMC相关的 代码进行修改和配置

5.1 修改EMMC初始化代码

将资料中“移植相关文件下的movi.c拷贝到uboot源码arch/arm/cpu/armv7/exynos/ 目录

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi arch/arm/cpu/armv7/exynos/Makefile

COBJS += clock.o power.o soc.o system.o pinmux.o

修改为如下内容,然后保存退出

COBJS += clock.o power.o soc.o system.o pinmux.o movi.o

修改板级文件

$ vi board/samsung/fs4412/fs4412.c

#include <asm/arch/mmc.h>

后添加如下内容

#include <asm/arch/clk.h>#include "origen_setup.h"

#ifdef CONFIG_GENERIC_MMC

后添加如下内容

u32 sclk_mmc4;  /*clock source for emmc controller*/#define __REGMY(x) (*((volatile u32 *)(x)))#define CLK_SRC_FSYS  __REGMY(EXYNOS4_CLOCK_BASE + CLK_SRC_FSYS_OFFSET)#define CLK_DIV_FSYS3 __REGMY(EXYNOS4_CLOCK_BASE + CLK_DIV_FSYS3_OFFSET)int emmc_init(){u32 tmp;u32 clock;u32 i;/* setup_hsmmc_clock *//* MMC4 clock src = SCLKMPLL */tmp = CLK_SRC_FSYS & ~(0x000f0000);CLK_SRC_FSYS = tmp | 0x00060000;/* MMC4 clock div */tmp = CLK_DIV_FSYS3 & ~(0x0000ff0f);clock = get_pll_clk(MPLL)/1000000;for(i=0 ; i<=0xf; i++)  {sclk_mmc4=(clock/(i+1));if(sclk_mmc4 <= 160) //200{CLK_DIV_FSYS3 = tmp | (i<<0);break;}}emmcdbg("[mjdbg] sclk_mmc4:%d MHZ; mmc_ratio: %d\n",sclk_mmc4,i);sclk_mmc4 *= 1000000;/** MMC4 EMMC GPIO CONFIG** GPK0[0] SD_4_CLK* GPK0[1] SD_4_CMD* GPK0[2] SD_4_CDn* GPK0[3:6] SD_4_DATA[0:3]*/writel(readl(0x11000048)&~(0xf),0x11000048); //SD_4_CLK/SD_4_CMD pull-down enablewritel(readl(0x11000040)&~(0xff),0x11000040);//cdn set to be outputwritel(readl(0x11000048)&~(3<<4),0x11000048); //cdn pull-down disablewritel(readl(0x11000044)&~(1<<2),0x11000044); //cdn output 0 to shutdown the emmc powerwritel(readl(0x11000040)&~(0xf<<8)|(1<<8),0x11000040);//cdn set to be outputudelay(100*1000);writel(readl(0x11000044)|(1<<2),0x11000044); //cdn output 1writel(0x03333133, 0x11000040);writel(0x00003FF0, 0x11000048);writel(0x00002AAA, 0x1100004C);#ifdef CONFIG_EMMC_8Bitwritel(0x04444000, 0x11000060);writel(0x00003FC0, 0x11000068);writel(0x00002AAA, 0x1100006C);#endif#ifdef USE_MMC4smdk_s5p_mshc_init();#endif}

将board_mmc_init函数中的内容修改为(之前的内容删除即可)如下内容

int board_mmc_init(bd_t *bis){int i, err;#ifdef CONFIG_EMMCerr = emmc_init();#endifreturn err;}

在文件的最末尾添加如下内容,然后保存退出​​​​​​​

#ifdef CONFIG_BOARD_LATE_INIT#include <movi.h>int  chk_bootdev(void)//mj for boot device check{char run_cmd[100];struct mmc *mmc;int boot_dev = 0;int cmp_off = 0x10;ulong  start_blk, blkcnt;mmc = find_mmc_device(0);if (mmc == NULL){printf("There is no eMMC card, Booting device is SD card\n");boot_dev = 1;return boot_dev;}start_blk = (24*1024/MOVI_BLKSIZE);blkcnt = 0x10;sprintf(run_cmd,"emmc open 0");run_command(run_cmd, 0);sprintf(run_cmd,"mmc read 0 %lx %lx %lx",CFG_PHY_KERNEL_BASE,start_blk,blkcnt);run_command(run_cmd, 0);/* switch mmc to normal paritition */sprintf(run_cmd,"emmc close 0");run_command(run_cmd, 0);return 0;}int board_late_init (void){int boot_dev =0 ;char boot_cmd[100];boot_dev = chk_bootdev();if(!boot_dev){printf("\n\nChecking Boot Mode ... EMMC4.41\n");}return 0;}#endif

​​​​​​​5.2 添加EMMC命令

将资料中“移植相关文件下的cmd_movi.c、cmd_mmc.c、cmd_mmc_fdisk.c拷贝到uboot 源码common/目录

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi common/Makefile

COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o

后添加如下内容,然后保存退出

COBJS-$(CONFIG_CMD_MMC) += cmd_mmc_fdisk.oCOBJS-$(CONFIG_CMD_MOVINAND) += cmd_movi.o

将资料中“移植相关文件下的mmc.c、s5p_mshc.c拷贝到uboot源码drivers/mmc/ 目录

将资料中“移植相关文件下的mmc.h、movi.h、s5p_mshc.h拷贝到uboot源码include/ 目录

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi drivers/mmc/Makefile

COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o

后添加如下内容,然后保存退出

COBJS-$(CONFIG_S5P_MSHC) += s5p_mshc.o

5.3 修改EMMC配置代码

 $ vi include/configs/fs4412.h

在文件的末尾

 

#endif /* __CONFIG_H */

前添加如下内容,然后保存退出

#define CONFIG_EVT1     1       /* EVT1 */#ifdef CONFIG_EVT1#define CONFIG_EMMC44_CH4 //eMMC44_CH4 (OMPIN[5:1] = 4)#ifdef CONFIG_SDMMC_CH2#define CONFIG_S3C_HSMMC#undef DEBUG_S3C_HSMMC#define USE_MMC2  #endif#ifdef CONFIG_EMMC44_CH4#define CONFIG_S5P_MSHC#define CONFIG_EMMC             1#define USE_MMC4  /* #define CONFIG_EMMC_8Bit */#define CONFIG_EMMC_EMERGENCY/*#define emmcdbg(fmt,args...) printf(fmt ,##args) */#define emmcdbg(fmt,args...)#endif#endif /*end CONFIG_EVT1*/#define CONFIG_CMD_MOVINAND#define CONFIG_CLK_1000_400_200#define CFG_PHY_UBOOT_BASE      CONFIG_SYS_SDRAM_BASE + 0x3e00000#define CFG_PHY_KERNEL_BASE     CONFIG_SYS_SDRAM_BASE + 0x8000#define BOOT_MMCSD      0x3#define BOOT_EMMC43     0x6#define BOOT_EMMC441    0x7#define CONFIG_BOARD_LATE_INIT

​​​​​​​5.4 编译uboot

通过脚本编译uboot源码

$ ./build.sh

​​​​​​​5.5 测试uboot

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动, 然后上电查看现象;若显示EMMC的相关信息则表示EMMC移植成功

6 电源管理移植

因为uboot源码中对电源管理芯片的配置与我们的板子不匹配,后续有可能会导致内核 启动卡死,这里还需要对电源管理芯片相关的代码进行修改和配置

6.1 修改电源管理相关代码

将资料中“移植相关文件下的pmic_s5m8767.c拷贝到uboot源码drivers/power/pmic/ 目录下​​​​​​​

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi drivers/power/pmic/Makefile

COBJS-$(CONFIG_POWER_MAX77686) += pmic_max77686.o

后添加如下内容,然后保存退出

COBJS-$(CONFIG_POWER_S5M8767) += pmic_s5m8767.o

将添加的函数在头文件中声明

$ vi include/power/pmic.h

int pmic_set_output(struct pmic *p, u32 reg, int ldo, int on);

后添加如下内容,然后保存退出

void pmic_s5m8767_init(void);

修改配置文件

$ vi include/configs/fs4412.h

在文件末尾

#endif /* __CONFIG_H */

前添加如下内容,然后保存退出

#define CONFIG_POWER_S5M8767

修改板级文件

$ vi board/samsung/fs4412/fs4412.c

在board_init函数中

#ifdef CONFIG_DRIVER_DM9000dm9000aep_pre_init();#endif

后添加如下内容,然后保存退出

#ifdef CONFIG_POWER_S5M8767pmic_s5m8767_init();#endif

注释原有的代码

$ vi drivers/power/Makefile

COBJS-$(CONFIG_POWER) += power_core.o

修改为(即注释掉)

#COBJS-$(CONFIG_POWER) += power_core.o

修改架构文件

$ vi arch/arm/cpu/armv7/s5p-common/cpu_info.c

#include <asm/arch/clk.h>

后添加如下内容,然后保存退出

#include <power/pmic.h>

​​​​​​​6.2 编译uboot

通过脚本编译uboot源码

$ ./build.sh

6.3 测试uboot

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动,然后上电查看现象

至此,uboot移植完成

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

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

相关文章

flutter 代码混淆

Flutter 应用混淆&#xff1a; Flutter 应用的混淆非常简单&#xff0c;只需要在构建 release 版应用时结合使用 --obfuscate 和 --split-debug-info 这两个参数即可。 –obfuscate --split-debug-info 用来指定输出调试文件的位置&#xff0c;该命令会生成一个符号映射表。目前…

【TB作品】基于单片机的机械通风控制系统,实时温度和二氧化碳浓度

硬件&#xff1a; &#xff08;1&#xff09;51系列单片机&#xff0c;拟采用STC89C52RC&#xff1b; &#xff08;2&#xff09;DS18B20温度传感器&#xff1b; &#xff08;3&#xff09;二氧化碳浓度传感器&#xff1a;https://item.taobao.com/item.htm?spma21n57.1.0.0.1…

紫光展锐CEO任奇伟博士:展锐5G芯筑基当下,迈向未来

12月5日&#xff0c;紫光集团执行副总裁、紫光展锐CEO任奇伟博士受邀出席2023世界5G大会5G产业强基发展论坛&#xff0c;发表了题为《展锐5G芯&#xff1a;筑基当下&#xff0c;迈向未来》的演讲。 ​ 世界5G大会由国务院批准&#xff0c;国家发展改革委、科技部、工信部与地方…

小程序使用Nodejs作为服务端,Nodejs与与MYSQL数据库相连

小程序使用Nodejs作为服务端,Nodejs与MYSQL数据库相连 一、搭建环境二、配置Nodejs三、与小程序交互四、跨域处理/报错处理五、nodejs连接mysql数据库六、微信小程序连接nodejs报错七、小程序成功与服务端相连,且能操作数据库一、搭建环境 新建空文件夹:Win + R进入cmd命令界…

再不跳槽,就晚了

从时间节点上来看&#xff0c;3月、4月是每年跳槽的黄金季&#xff01; 以 BAT 为代表的互联网大厂&#xff0c;无论是薪资待遇、还是平台和福利&#xff0c;都一直是求职者眼中的香饽饽&#xff0c;“大厂经历” 在国内就业环境中无异于一块金子招牌。 现在年底了&#xff0…

【推荐系统】推荐算法数学基础

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍推荐系统涉及的数学知识、推荐系统涉及的概率统计知识。 后续会继续分享其他重要知识点总结&#xff0c;如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下吧】 上一篇文章&#xff1a;《【推…

R语言|分面中嵌入趋势线

简介 关于分面的推文&#xff0c;小编根据实际科研需求&#xff0c;已经分享了很多技巧。例如&#xff1a; 分面中添加不同表格 分面中添加不同的直线 基于分面的面积图绘制 分面中的细节调整汇总 基于分面的折线图绘制 最近科研中又遇到了与分面相关的需求&#xff1a;…

CF1898C Colorful Grid(构造)

题目链接 题目大意 n 行 m 列 的一个矩阵&#xff0c;每行有m - 1条边&#xff0c;每列有 n - 1 条边。 问一共走 k 条边&#xff0c;能不能从 &#xff08;1&#xff0c; 1&#xff09;&#xff0c;走到&#xff08;n&#xff0c; m&#xff09;&#xff0c;要求该路径上&am…

【一文带你掌握Java中方法定义、调用和重载的技巧】

方法的定义和调用 方法的定义 方法&#xff08;method&#xff09;是一段用于实现特定功能的代码块&#xff0c;类似于其他编程语言中的函数&#xff08;function&#xff09;。方法被用来定义类或类的实例的行为特征和功能实现。方法是类和对象行为特征的抽象表示。方法与面向…

十八)Stable Diffusion使用教程:艺术二维码案例

今天说说怎么样使用SD生成艺术二维码。 我们直接上图。 方式有三种,分别如下: 1)方式一:直接 contronet 的tile模型进行控制 使用QRBTF Classic生成你的二维码。 首先输入网址,选择喜欢的二维码样式(推荐第一种就行): 然后选择相应参数,这里推荐最大的容错率,定…

JieLink+智能终端操作平台存在弱口令漏洞

产品简介 捷顺JeLink智能终端操作平台(JSOTC2016 fJeLink)是捷顺历经多年行业经验积累&#xff0c;集智能硬件技术视频分析技术、互联网技术等多种技术融合&#xff0c;基于B/S架构&#xff0c;实现核心业务处理模型(用户中心、投权中心财务中心中心值班室、 运维中心车行客户…

《地理信息系统原理》笔记/期末复习资料(11. GIS的输出与地图可视化)

目录 11. GIS的输出与地图可视化 11.1. GIS的输出 11.1.1. 输出方式 11.1.2. GIS的图形输出设备 11.2. 地图符号 11.2.1. 地图符号的实质 11.2.2. 地图符号的分类 11.2.3. 地图符号的设计要求 11.3. 专题信息表达 11.3.1. 专题地图的基本概念 11.3.2. 专题地图的表示…

boost graph之基础

结构 属性相关 #mermaid-svg-LUDFVluXTOlnqK0d {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-LUDFVluXTOlnqK0d .error-icon{fill:#552222;}#mermaid-svg-LUDFVluXTOlnqK0d .error-text{fill:#552222;stroke:#5522…

微软自带浏览器Edge,无法关闭“保存历史记录网站的屏幕截图”解决方案

微软自带浏览器Edge&#xff0c;无法关闭“保存历史记录网站的屏幕截图”解决方案 吐槽1&#xff1a;Windows自带的Chrome内核版本的浏览器Microsofg Edge刚发布时可谓一股清流&#xff0c;启动速度快&#xff0c;占用内存较小&#xff0c;相信很多人也开始抛弃正代Chrome&…

【Spring】08 BeanNameAware 接口

文章目录 1. 简介2. 作用3. 使用3.1 创建并实现接口3.2 配置 Bean 信息3.3 创建启动类3.4 启动 4. 应用场景总结 Spring 框架为开发者提供了丰富的扩展点&#xff0c;其中之一就是 Bean 生命周期中的回调接口。本文将聚焦于其中的一个接口 BeanNameAware&#xff0c;介绍它的作…

Hudi 在 vivo 湖仓一体的落地实践

作者&#xff1a;vivo 互联网大数据团队 - Xu Yu 在增效降本的大背景下&#xff0c;vivo大数据基础团队引入Hudi组件为公司业务部门湖仓加速的场景进行赋能。主要应用在流批同源、实时链路优化及宽表拼接等业务场景。 一、Hudi 基础能力及相关概念介绍 1.1 流批同源能力 与H…

go学习redis的学习与使用

文章目录 一、redis的学习与使用1.Redis的基本介绍2.Redis的安装下载安装包即可3.Redis的基本使用1&#xff09;Redis的启动&#xff1a;2&#xff09;Redis的操作的三种方式3&#xff09;说明&#xff1a;Redis安装好后&#xff0c;默认有16个数据库&#xff0c;初始默认使用0…

java导出word使用模版与自定义联合出击解决复杂表格!

1. 看一下需要导出什么样子的表格 如图所示&#xff0c;这里的所有数据行都是动态的&#xff0c;需要根据查询出来的数据循环展示。 如果只是这样的话&#xff0c;使用freemarker应该都可以搞定&#xff0c;但是他一列中内容相同的单元格&#xff0c;需要合并。 这对于表格样式…

conda命令克隆(复制)环境

前情介绍 最近有个需求是&#xff1a;根据已有的环境生成一个新的环境&#xff0c;也就是所需的新环境有大多数包和已有的环境都是相同的&#xff0c;需要改的只是部分&#xff0c;所以呢&#xff0c;克隆一个就再适合不过了&#xff01; 所需命令 conda create -n B --clone…