56. Uboot移植实验
一、NXP官方Uboot编译与测试
1、将NXP提供的uboot拷贝到ubuntu中。
一个开发板也好运行uboot,DDR或者叫DRAM,串口,SD、EMMC、NAND。板子能工作。
测似结果:
1、uboot能正常启动
2、LCD驱动要根据所使用的屏幕修改。
3、NET初始化失败。
SD卡Formatter V4.0 格式化后,环境变量会被格式化掉。再烧录,

U-Boot 2016.03 (Feb 03 2025 - 19:31:00 +0800)CPU: Freescale i.MX6ULL rev1.1 69 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 32C
Reset cause: WDOG
Board: MX6ULL 14x14 EVK
I2C: ready
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
MMC: FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environmentDisplay: TFT43AB (480x272)
Video: 480x272x24
In: serial
Out: serial
Err: serial
switch to partitions #0, OK
mmc0 is current device
Net: Board Net Initialization Failed
No ethernet found.
Normal Boot
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
switch to partitions #0, OK
mmc0 is current device
** No partition table - mmc 0 **
** No partition table - mmc 0 **
Booting from net ...
No ethernet found.
No ethernet found.
Bad Linux ARM zImage magic!
=>
环境变量没清是这样

二、移植NXP官方uboot到ALPHA开发板
2.1 添加板子默认配置文件
借鉴NXP官方6ULL EVK开发板,默认配置文件也用他的,
/uboot_m/configs
cp mx6ull_14x14_evk_emmc_defconfig mx6ull_14x14_my_emmc_defconfig
新建my.sh
#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_my_emmc_defconfig
make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
修改mx6ull_14x14_my_emmc_defconfig
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_my_emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6ULL_MY_EMMC=y
CONFIG_CMD_GPIO=y
修改Kconfig

if TARGET_MX6ULL_MY_EMMC
config SYS_BOARD
default “mx6ull_my_emmc”
config SYS_VENDOR
default “freescale”
config SYS_CONFIG_NAME
default “mx6ull_my_emmc”
endif
修改MAINTAINERS

MX6ULLEVK BOARD
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ull_my_emmc/
F: include/configs/mx6ull_my_emmc.h
F: configs/mx6ull_my_emmc_defconfig
2.2添加板子对应的头文件
不同的板子,有一些需要配置的信息,一般是在一个头文件里面配置,每个板子有一个。对于NXP官方的6ULL EVK板子,这个头文件就是
/uboot_m/include/configscp mx6ullevk.h mx6ull_my_emmc.h

2.3 添加板子对应的板级文件夹
每个板子都有特有的文件,也叫做板级文件。这里我们将6ULL EVK的板级文件直接拷贝过来。
/uboot_m/board/freescale
cp mx6ullevk/ mx6ull_my_emmc -r

重命名
/uboot_m/board/freescale/mx6ull_my_emmc
mv mx6ullevk.c mx6ull_my_emmc.c

修改Makefile

修改

#ifdef CONFIG_USE_PLUGIN
/*PLUGIN plugin-binary-file IRAM_FREE_START_ADDR*/
PLUGIN board/freescale/mx6ull_my_emmc/plugin.bin 0x00907000
#else
2.4 修改uboot的配置界面

config TARGET_MX6ULL_9X9_EVKbool "Support mx6ull_9x9_evk"select MX6ULLselect DMselect DM_THERMALconfig TARGET_MX6ULL_MY_EMMCbool "Support mx6ull_my_emmc"select MX6ULLselect DMselect DM_THERMALsource "board/freescale/mx6dqscm/Kconfig"
source "board/freescale/mx6sxscm/Kconfig"
source "board/freescale/mx6ull_my_emmc/Kconfig"
endif
2.5 使用新添加的板子配置并编译Uboot
编译
./my.sh

mx6ull_my_emm.c编译成.o,mx6ullevk里没有编译

查看.h文件有没有被引用
~/uboot_m/uboot_m$ grep -nR "mx6ull_my_emmc.h"
disk/.part.o.cmd:152: include/configs/mx6ull_my_emmc.h \
disk/.part_dos.o.cmd:134: include/configs/mx6ull_my_emmc.h \
drivers/block/.disk-uclass.o.cmd:133: include/configs/mx6ull_my_emmc.h \
drivers/gpio/.mxc_gpio.o.cmd:142: include/configs/mx6ull_my_emmc.h \
drivers/spi/.spi.o.cmd:134: include/configs/mx6ull_my_emmc.h \
drivers/spi/.fsl_qspi.o.cmd:139: include/configs/mx6ull_my_emmc.h \
至此,说明我们在uboot里成功添加了我们的板子。下载测试下。
2.6 LCD驱动修改
般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的, xxx 为板子名称,比如 mx6ull_alientek_emmc.h 和 mx6ull_alientek_emmc.c 这两个文件。
一般修改 LCD 驱动重点注意以下几点:
①、 LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②、 LCD 背光引脚 GPIO 的配置。
③、 LCD 配置参数是否正确。
正点原子的 I.MX6U-ALPHA 开发板 LCD 原理图和 NXP 官方 I.MX6ULL 开发板一致,也就是 LCD 的 IO 和背光 IO 都一样的,所以 IO 部分就不用修改了。需要修改的之后 LCD 参数,打开文件 mx6ull_alientek_emmc.c,找到如下所示内容:
1、确定LCD IO初始化正确,mx6ull_alientek_emmc.c中的lcd_pads。
#ifdef CONFIG_VIDEO_MXS
static iomux_v3_cfg_t const lcd_pads[] = {MX6_PAD_LCD_CLK__LCDIF_CLK | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_ENABLE__LCDIF_ENABLE | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_HSYNC__LCDIF_HSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_VSYNC__LCDIF_VSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA00__LCDIF_DATA00 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA01__LCDIF_DATA01 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA02__LCDIF_DATA02 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA03__LCDIF_DATA03 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA04__LCDIF_DATA04 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA05__LCDIF_DATA05 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA06__LCDIF_DATA06 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA07__LCDIF_DATA07 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA08__LCDIF_DATA08 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA09__LCDIF_DATA09 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA10__LCDIF_DATA10 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA11__LCDIF_DATA11 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA12__LCDIF_DATA12 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA13__LCDIF_DATA13 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA14__LCDIF_DATA14 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA15__LCDIF_DATA15 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA16__LCDIF_DATA16 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA17__LCDIF_DATA17 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA18__LCDIF_DATA18 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA19__LCDIF_DATA19 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA20__LCDIF_DATA20 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA21__LCDIF_DATA21 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA22__LCDIF_DATA22 | MUX_PAD_CTRL(LCD_PAD_CTRL),MX6_PAD_LCD_DATA23__LCDIF_DATA23 | MUX_PAD_CTRL(LCD_PAD_CTRL),/* LCD_RST */MX6_PAD_SNVS_TAMPER9__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),/* Use GPIO for Brightness adjustment, duty cycle = period. */MX6_PAD_GPIO1_IO08__GPIO1_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
改为
/* LCD_RST */
// MX6_PAD_SNVS_TAMPER9__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
2、LCD参数,mx6ull_alientek_emmc.c中的displays。fb_videomode表示RGB LCD参数。
struct display_info_t const displays[] = {{.bus = MX6UL_LCDIF1_BASE_ADDR,.addr = 0,.pixfmt = 24,.detect = NULL,.enable = do_enable_parallel_lcd,.mode = {.name = "TFT43AB",.xres = 480,.yres = 272,.pixclock = 108695,.left_margin = 8,.right_margin = 4,.upper_margin = 2,.lower_margin = 4,.hsync_len = 41,.vsync_len = 10,.sync = 0,.vmode = FB_VMODE_NONINTERLACED
} } };
size_t display_count = ARRAY_SIZE(displays);
MX6ULL_LCDIF1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x48000)AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000)ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR
AIPS2_ARB_BASE_ADDR 0x02100000MX6ULL_LCDIF1_BASE_ADDR = 0x02100000 + 0x80000 + 0x48000 = 0x21c8000

void do_enable_parallel_lcd(struct display_info_t const *dev)
{enable_lcdif_clock(dev->bus);imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));/* Reset the LCD */gpio_direction_output(IMX_GPIO_NR(5, 9) , 0);udelay(500);gpio_direction_output(IMX_GPIO_NR(5, 9) , 1);/* Set Brightness to high */gpio_direction_output(IMX_GPIO_NR(1, 8) , 1);
}
改为
/* Reset the LCD */// gpio_direction_output(IMX_GPIO_NR(5, 9) , 0);// udelay(500);// gpio_direction_output(IMX_GPIO_NR(5, 9) , 1);
修改参数

12 .left_margin = 88, //HBPD
13 .right_margin = 40 //HFPD
14 .upper_margin = 32, //VBPD
15 .lower_margin = 13, //VFBD
16 .hsync_len = 48, //HSPW
17 .vsync_len = 3, //VSPW
结构体 fb_videomode 里面的成员变量为 LCD 的参数,这些成员变量函数如下: name: LCD 名字,要和环境变量中的 panel 相等。
xres、 yres: LCD X 轴和 Y 轴像素数量。pixclock:像素时钟,每个像素时钟周期的长度,单位为皮秒。left_margin: HBP,水平同步后肩。right_margin: HFP,水平同步前肩。upper_margin: VBP,垂直同步后肩。lower_margin: VFP,垂直同步前肩。hsync_len: HSPW,行同步脉宽。vsync_len: VSPW,垂直同步脉宽。
vmode: 大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描。
可以看出,这些参数和我们第二十四章讲解 RGB LCD 的时候参数基本一样,唯一不同的像素时钟 pixclock 的含义不同,以正点原子的 7 寸 1024*600 分辨率的屏幕(ATK7016)为例,屏幕要求的像素时钟为 51.2MHz,因此:
pixclock=(1/51200000)*10^12=19531
struct display_info_t const displays[] = {{.bus = MX6UL_LCDIF1_BASE_ADDR,.addr = 0,.pixfmt = 24,.detect = NULL,.enable = do_enable_parallel_lcd,.mode = {.name = "TFT4384",.xres = 800,.yres = 480,.pixclock = 19531,.left_margin = 88,.right_margin = 40,.upper_margin = 32,.lower_margin = 13,.hsync_len = 48,.vsync_len = 3,.sync = 0,.vmode = FB_VMODE_NONINTERLACED
} } };
Panel环境变量表示LCD ID。
打开 mx6ull_my_emmc.h,找到所有如下语句:
panel=TFT43AB将其改为: panel=TFT4384
SD全部格式化


U-Boot 2016.03 (Feb 04 2025 - 16:19:07 +0800)CPU: Freescale i.MX6ULL rev1.1 69 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 32C
Reset cause: POR
Board: MX6ULL 14x14 EVK
I2C: ready
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environmentDisplay: TFT4384 (800x480)
Video: 800x480x24
In: serial
Out: serial
Err: serial
switch to partitions #0, OK
mmc0 is current device
Net: Board Net Initialization Failed
No ethernet found.
Normal Boot
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
switch to partitions #0, OK
mmc0 is current device
** No partition table - mmc 0 **
** No partition table - mmc 0 **
Booting from net ...
No ethernet found.
No ethernet found.
Bad Linux ARM zImage magic!
环境变量panel=TFT4384,识别出TFT4384,LCD屏显示NXP图标。
如果 EMMC 中的环境变量 panel 不等于 TFT7016,那么 LCD 显示肯定不正常,我们只需要在uboot 中修改 panel 的值为 TFT7016 即可,在 uboot 的命令模式下输入如下命令:
setenv panel TFT4384
saveenv
2.7 网络驱动修改
I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案。大家可能听过 DM9000 这个网络芯片,在一些没有内部 MAC 的 CPU 中,比如三星的 2440, 4412 等,就会采用 DM9000 来实现联网功能。 DM9000 提供了一个类似 SRAM 的访问接口,主控 CPU 通过这个接口即可与DM9000 进行通信, DM9000 就是一个 MAC+PHY 芯片。这个方案就相当于外部 MAC+外部PHY,那么 I.MX6U 这样的内部 MAC+PHY 芯片与 DM9000 方案比有什么优势吗?那优势大了去了!首先就是通信效率和速度,一般 SOC 内部的 MAC 是带有一个专用 DMA 的,专门用于处理网络数据包,采用 SRAM 来读写 DM9000 的速度是压根就没法和内部 MAC+外部 PHY 芯片的速度比。采用外部 DM9000 完全是无奈之举,谁让 2440, 4412 这些芯片内部没有以太网外设呢,现在又想用有线网络,没有办法只能找个 DM9000 的方案。从这里也可以看出,三星的 2440、 4412 这些芯片设计之初就不是给工业产品用的,他们是给消费类电子使用的,比如手机、平板等,手机或平板要上网,可以通过 WIFI 或者 4G,我是没有见过哪个手机或者平板上网是要接根网线的。正点原子的 I.MX6U-ALPHA 开发板也可以通过 WIFI 或者 4G 上网,这个是后话了。
I.MX6UL/ULL 有两个网络接口 ENET1 和 ENET2,正点原子的 I.MX6U-ALPHA 开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片。 NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片, LAN8720A 相比 KSZ8081 具有体积小、外围器件少、价格便宜等优点。直接使用 KSZ8081 固然可以,但是我们在实际的产品中不一定会使用 KSZ8081,有时候为了降低成本会选择其他的 PHY 芯片,这个时候就有个问题:换了PHY 芯片以后网络驱动怎么办?为此,正点原子的 I.MX6U-ALPHA 开发板将 ENET1 和 ENET2的 PHY 换成了 LAN8720A,这样就可以给大家讲解更换 PHY 芯片以后如何调整网络驱动,使网络工作正常。
6ULL网络方案采用内部MAC+外部PHY,6ULL官方开发板使用的PHY芯片就是KSZ8081。正点原子的ALPHA开发板没有使用KSZ8081,我们使用的LAN8720A。因此要修改驱动。
LAN872有一个管理接口,叫做MDIO,两根线,MDIO和MDC,一个MDIO接口可以管理32个PHY芯片。MIDO通过PHY ADDR来确定访问那个PHY芯片。ALPHA开发板ENET1的PHY ADDR是0x0,ENET2的PHY ADDR是0X1.
每个LAN8720都有一个复位引脚,ENET1是SNVS_TAMPER7,ENET2是SNVS_TAMPER8。
LAN8720驱动,因为所有的PHY,其前16个寄存器一模一样,因此uboot里面已经写好了通用PHY驱动,所以理论上不需要修改。
驱动修改
1、修改PHY ADDR
/uboot_m/uboot_m/include/configs/mx6ull_my_emmc.h
#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV 1#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x2
#define CONFIG_FEC_XCV_TYPE RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"#define CONFIG_PHYLIB
#define CONFIG_PHY_MICREL
#endif
改为
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x0#define CONFIG_PHY_SMSC
2、删除原有的74LV595相关代码。
// #define IOX_SDI IMX_GPIO_NR(5, 10)
// #define IOX_STCP IMX_GPIO_NR(5, 7)
// #define IOX_SHCP IMX_GPIO_NR(5, 11)
// #define IOX_OE IMX_GPIO_NR(5, 8)// static iomux_v3_cfg_t const iox_pads[] = {
// /* IOX_SDI */
// MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
// /* IOX_SHCP */
// MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
// /* IOX_STCP */
// MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
// /* IOX_nOE */
// MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
// };//static void iox74lv_init(void)
//{
//
//}//void iox74lv_set(int index)
//{
//
//}
3、添加ALPHA开发板的网络复位IO
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
修改
static iomux_v3_cfg_t const fec1_pads[] = {MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
};static iomux_v3_cfg_t const fec2_pads[] = {MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
为
static iomux_v3_cfg_t const fec1_pads[] = {MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
};static iomux_v3_cfg_t const fec2_pads[] = {MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
修改
static void setup_iomux_fec(int fec_id)
{if (fec_id == 0)imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));elseimx_iomux_v3_setup_multiple_pads(fec2_pads,ARRAY_SIZE(fec2_pads));
}
为
static void setup_iomux_fec(int fec_id)
{if (fec_id == 0){imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));gpio_direction_output(ENET1_RESET, 1);gpio_set_value(ENET1_RESET, 0);mdelay(20);gpio_set_value(ENET1_RESET, 1);}else{imx_iomux_v3_setup_multiple_pads(fec2_pads,ARRAY_SIZE(fec2_pads));gpio_direction_output(ENET2_RESET, 1);gpio_set_value(ENET2_RESET, 0);mdelay(20);gpio_set_value(ENET2_RESET, 1);}
}
修改 drivers/net/phy/phy.c 文件中的函数 genphy_update_link
修改
/*** genphy_update_link - update link status in @phydev* @phydev: target phy_device struct** Description: Update the value in phydev->link to reflect the* current link value. In order to do this, we need to read* the status register twice, keeping the second value.*/
int genphy_update_link(struct phy_device *phydev)
{unsigned int mii_reg;/** Wait if the link is up, and autonegotiation is in progress* (ie - we're capable and it's not done)*/mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);/** If we already saw the link up, and it hasn't gone down, then* we don't need to wait for autoneg again*/if (phydev->link && mii_reg & BMSR_LSTATUS)return 0;if ((phydev->autoneg == AUTONEG_ENABLE) &&!(mii_reg & BMSR_ANEGCOMPLETE)) {int i = 0;printf("%s Waiting for PHY auto negotiation to complete",phydev->dev->name);while (!(mii_reg & BMSR_ANEGCOMPLETE)) {/** Timeout reached ?*/if (i > PHY_ANEG_TIMEOUT) {printf(" TIMEOUT !\n");phydev->link = 0;return 0;}if (ctrlc()) {puts("user interrupt!\n");phydev->link = 0;return -EINTR;}if ((i++ % 500) == 0)printf(".");udelay(1000); /* 1 ms */mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);}printf(" done\n");phydev->link = 1;} else {/* Read the link a second time to clear the latched state */mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);if (mii_reg & BMSR_LSTATUS)phydev->link = 1;elsephydev->link = 0;}return 0;
}
为
int genphy_update_link(struct phy_device *phydev)
{unsigned int mii_reg;#ifdef CONFIG_PHY_SMSCstatic int lan8720_flag = 0;int bmcr_reg = 0;if (lan8720_flag == 0) {bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {udelay(100);}phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);lan8720_flag = 1;}#endif
成功了
U-Boot 2016.03 (Feb 04 2025 - 18:54:14 +0800)CPU: Freescale i.MX6ULL rev1.1 69 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 38C
Reset cause: POR
Board: MX6ULL 14x14 EVK
I2C: ready
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT4384 (800x480)
Video: 800x480x24
In: serial
Out: serial
Err: serial
switch to partitions #0, OK
mmc0 is current device
Net: FEC1
Normal Boot
Hit any key to stop autoboot: 0

改到ETH0
#define CONFIG_FEC_ENET_DEV 0

2.8 其他需要修改的地方
在 uboot 启动信息中会有“Board: MX6ULL 14x14 EVK”这一句,也就是说板子名字为“ MX6ULL 14x14 EVK”,要将其改为我们所使用的板子名字,比如“ MX6ULL ALIENTEK EMMC”或者“MX6ULL ALIENTEK NAND”。打开文件 mx6ull_alientek_emmc.c,找到函数checkboard,将其改为如下所示内容:
int checkboard(void)
{if (is_mx6ull_9x9_evk())puts("Board: MX6ULL 9x9 EVK\n");elseputs("Board: MX6ULL 14x14 EVK\n");return 0;
}
改为
int checkboard(void)
{if (is_mx6ull_9x9_evk())puts("Board: MX6ULL 9x9 EVK\n");elseputs("Board: MX6ULL MY EMMC\n");return 0;
}

打印环境变量
U-Boot 2016.03 (Feb 04 2025 - 19:07:16 +0800)CPU: Freescale i.MX6ULL rev1.1 69 MHz (running at 396 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 43C
Reset cause: POR
Board: MX6ULL MY EMMC
I2C: ready
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Display: TFT4384 (800x480)
Video: 800x480x24
In: serial
Out: serial
Err: serial
switch to partitions #0, OK
mmc0 is current device
Net: FEC1
Normal Boot
Hit any key to stop autoboot: 0
=> print
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootargs=console=ttymxc0,115200 root=/dev/nfs ip=dhcp nfsroot=:,v3,tcp
bootcmd=run findfdt;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if
run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot
; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
ethact=FEC1
ethaddr=00:04:9f:04:d2:35
ethprime=FEC
fdt_addr=0x83000000
fdt_file=imx6ull-14x14-evk.dtb
fdt_high=0xffffffff
findfdt=if test $fdt_file = undefined; then if test $board_name = EVK && test $b
oard_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_nam
e = EVK && test $board_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb;
fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb touse; fi; fi;
gatewayip=192.168.32.1
get_cmd=dhcp
image=zImage
initrd_addr=0x83800000
initrd_high=0xffffffff
ip_dyn=yes
ipaddr=192.168.32.50
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_ma
ss_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_st
orage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass
_storage.iSerialNumber="" clk_ignore_unused
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || tes
t ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr};
else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT;
fi; fi; else bootz; fi;
mmcdev=0
mmcpart=1
mmcroot=/dev/mmcblk0p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfs
root=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then se
tenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${
boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_
file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; the
n bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
netmask=255.255.255.0
panel=TFT4384
script=boot.scr
serverip=192.168.32.100Environment size: 2657/8188 bytes
=>
在启动 Linux 内核之前我们先来学习两个重要的环境变量 bootcmd 和 bootargs。
三、bootcmd和bootargs环境变量
3.1 bootcmd环境变量
宏CONFIG_BOOTCOMMAND也可以设置bootcmd的值。
"run findfdt;" \"mmc dev ${mmcdev};" \"mmc dev ${mmcdev}; if mmc rescan; then " \"if run loadbootscript; then " \"run bootscript; " \"else " \"if run loadimage; then " \"run mmcboot; " \"else run netboot; " \"fi; " \"fi; " \"else run netboot; fi"Findfdt 设置fdt_file环境变量,也就是dtb文件名字。
mmc dev 1 //切换到emmc
fatload mmc 1:1 80800000 zImage
fatload mmc 1:1 83000000 imx6ull-14x14-evk.dtb
booz 80800000 - 83000000
"loadbootscript=" \"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
展开以后:fatload mmc 1:1 80800000 boot.scrloadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \展开:fatload mmc 1:1 80800000 zImage"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \展开
fatload mmc 1:1 83000000 imx6ull-14x14-evk.dtbbootz ${loadaddr} - ${fdt_addr};
booz 80800000 - 83000000
3.2 bootargs环境变量
宏CONFIG_BOOTARGS也可以设置bootargs的值
mmcargs=setenv bootargs console=${console},${baudrate} " \CONFIG_BOOTARGS_CMA_SIZE \"root=${mmcroot}\0" \
展开以后就是:
bootargs console= ttymxc0,115200 root=/dev/mmcblk1p2
Bootargs是会传递给Linux内核,设置了一些东西
Bootargs环境变量也叫做命令行参数。
四、uboot启动Linux测试
4.1 从EMMC启动
1、首先查看EMMC里面是否有系统,linux镜像zImage和.dtb文件。先将当前设备切换到EMMC:
mmc dev 1 //切换到EMMC
mmcinfo //查看信息
fatls mmc 1:1 //查看EMMC分区1里面的文件
fatload mmc 1:1 80800000 zImage //将zimage下载到DDR的0x80800000处
fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb //将dtb读取到0X83000000
bootz 80800000 – 83000000 //启动内核
如果内核启动成功,说明uboot支持emmc启动,验证成功。
4.2 从网络启动
\8、系统镜像\1、出厂系统镜像\2、kernel镜像\linux-imx-4.1.15-2.1.0-gb78e551-v1.4

imx6ull-14x14-emmc-4.3-800x480-c.dtb、zImage复制到tftp服务器
先启动下tftp服务器
sudo service tftpd-hpa restart
tftp 80800000 zImage //从tftp服务器下载zimage
tftp 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb //从tftp服务器下载.dtb
bootz 80800000 - 83000000//启动系统
五、uboot DDR初始化
1、裸 机
imxdownload软件下载,会在bin文件头部添加IVT DCD数据,
2、uboot
uboot编译生成u-boot.imx。u-boot.imx已经包含了IVT DCD数据。
u-boot.imx的头部信息是怎么添加的?
u-boot.imx的DCD中的DDR初始化代码该怎么修改。
uboot编译会输出
./tools/mkimage -n board/freescale/mx6ull_alientek_emmc/imximage.cfg.cfgtmp -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx
可以看出uboot使用/tools/mkimage工具,向u-boot.bin添加board/freescale/mx6ull_alientek_emmc/imximage.cfg.cfgtmp文件信息,从而得到u-boot.imx。
默认只有imximage.cfg文件,imximage.cfg里面保存的就是DCD数据。DDR初始化也此文件里面。
我们要修改DDR初始化代码,就需要修改imximage.cfg文件。此文件默认拷贝的NXP给IMX6ULL EVK开发板写的,默认是给512MB DDR3L写的。
相关文章:
56. Uboot移植实验
一、NXP官方Uboot编译与测试 1、将NXP提供的uboot拷贝到ubuntu中。 一个开发板也好运行uboot,DDR或者叫DRAM,串口,SD、EMMC、NAND。板子能工作。 测似结果: 1、uboot能正常启动 2、LCD驱动要根据所使用的屏幕修改。 3、NET初始…...
AI大模型:本地部署deepseek
一、安装lmstudio 1、下载网站: LM Studio - Discover, download, and run local LLMs 2、直接安装即可,记住安装的路径 二、下载deepseek模型 2.1、下载的流程 1、下载网站 https://huggingface.co/models 2、在搜索框输入:deepseek …...
(算法竞赛)图论+DFS深搜——图的dfs遍历1
题目描述 给定一个无向图,包含 n 个顶点(编号为 1 到 n)和 e 条边。要求从顶点 1 开始进行深度优先搜索(DFS),并按照访问顺序输出遍历结果。注意:当存在多个邻接点时,优先访问编号较…...
RK3588平台开发系列讲解(DMA篇)DMA engine使用
文章目录 一、DMA 使用步骤二、DMA接口2.1、DMA 通道管理相关接口2.2、DMA 描述符相关接口2.3、DMA 启动与控制接口2.4、DMA 状态检查接口2.5、 DMA 缓存管理接口2.6、DMA 中断与同步机制沉淀、分享、成长,让自己和他人都能有所收获!😄 Linux 内核的 DMA 引擎提供了一组完整…...
报名 | IEEE ICME 2025 音频编码器能力挑战赛正式开启
音频编码器是多模态大模型的重要组件,优秀的音频编码器在构建多模态系统中至关重要。在此背景下,小米集团、萨里大学、海天瑞声共同主办了 IEEE International Conference on Multimedia & Expo (ICME) 2025 Audio Encoder Capability Challenge。 …...
fputs的概念和使用案例
fputs 是 C 语言中用于向文件写入字符串的标准库函数。它与 puts 类似,但不会自动添加换行符,且支持向任意文件流(如磁盘文件、标准输出等)写入数据。 概念解析 函数原型:int fputs(const char *str, FILE *stream); …...
ASP.NET Core标识框架Identity
目录 Authentication与Authorization 标识框架(Identity) Identity框架的使用 初始化 自定义属性 案例一:添加用户、角色 案例二:检查登录用户信息 案例三:实现密码的重置 步骤 Authentication与Authorizatio…...
PFAS(全氟烷基和多氟烷基物质)测试流程详细介绍
PFAS(全氟烷基和多氟烷基物质)测试详细介绍 什么是PFAS? PFAS是(Per-and polyfluoroalkyl substances)的简称,中文名:全氟烷基和多氟烷基物质,是一系列合成有机氟化物的总称,是指至少含有一个…...
宝塔面板端口转发其它端口至MySQL的3306
最近需要把服务器的MySQL服务开放给外网,但又希望公开给所有人。也不想用默认的3306端口。同时也不想改变MySQL的默认端口。 这时候最好的办法就是用一个不常用的端口来转发至3306上去。例如使用49306至3306,外网通过49306来访问,内网依然使用…...
inquirer介绍及配合lerna在Vue中使用示例
目录 安装基本用法使用多个提示框动态选择(动态选项)表单式输入配合lerna在Vue中使用示例 Inquirer 是一个用于创建交互式命令行工具的 Node.js 库,常用于收集用户输入。它提供了多种类型的提示框,可以用于创建交互式应用程序&…...
AI商业化:如何包装技术并找到客户需求?
AI商业化:如何包装技术并找到客户需求? 适用人群:对人工智能技术有一定沉淀,正在探索技术变现和商业模式创新的创业者、技术团队以及企业管理者。同时也适合对 AI 产品包装、市场调研与用户调研感兴趣的从业人员。 一、引言 在过去几年里,从 GPT、Transformer 到 DeepSee…...
基于MODIS/Landsat/Sentinel/国产卫星遥感数据与DSSAT作物模型同化的作物产量估算
基于过程的作物生长模拟模型DSSAT是现代农业系统研究的有力工具,可以定量描述作物生长发育和产量形成过程及其与气候因子、土壤环境、品种类型和技术措施之间的关系,为不同条件下作物生长发育及产量预测、栽培管理、环境评价以及未来气候变化评估等提供了…...
OpenAI 宣布免费开放 ChatGPT 搜索,无需注册
在科技飞速发展的今天,人工智能领域的每一次突破都犹如一颗重磅炸弹,震撼着整个世界。北京时间 2025 年 2 月 6 日凌晨,OpenAI 宣布向所有用户开放 ChatGPT 搜索功能,且无需注册,这一消息瞬间引发了全球范围内的广泛关…...
如何打开vscode系统用户全局配置的settings.json
📌 settings.json 的作用 settings.json 是 Visual Studio Code(VS Code) 的用户配置文件,它存储了 编辑器的个性化设置,包括界面布局、代码格式化、扩展插件、快捷键等,是用户全局配置(影响所有…...
DeepSeek-V3本地Docker容器化部署
1. 安装Docker 确保已安装Docker Desktop for Mac: 下载并安装 Docker Desktop。 安装完成后,启动Docker Desktop。 验证安装: docker --version docker-compose --version 2. 克隆DeepSeek-V3仓库 git clone https://github.com/deeps…...
【Leetcode 每日一题】47. 全排列 II
问题背景 给定一个可包含重复数字的序列 n u m s nums nums,按任意顺序 返回所有不重复的全排列。 数据约束 1 ≤ n u m s . l e n g t h ≤ 8 1 \le nums.length \le 8 1≤nums.length≤8 − 10 ≤ n u m s [ i ] ≤ 10 -10 \le nums[i] \le 10 −10≤nums[i]≤…...
【Uniapp-Vue3】从uniCloud中获取数据
需要先获取数据库对象: let db uniCloud.database(); 获取数据库中数据的方法: db.collection("数据表名称").get(); 所以就可以得到下面的这个模板: let 函数名 async () > { let res await db.collection("数据表名称…...
【重生之学习C语言----杨辉三角篇】
目录 编辑 --------------------------------------begin---------------------------------------- 一、什么是杨辉三角? 二、问题分析 三、算法设计 使用二维数组存储杨辉三角: 递推关系: 格式化输出: 四、代码实现 完…...
天童教育:帮助孩子建立稳定的自信心
不少家长发现,自己家孩子不知道从什么时候开始,不再自信了。有些孩子在面对挑战时总是畏缩不前,不敢尝试新事物;在众人面前发言时,声音微弱,眼神闪躲。昆明天童教育认为,这些表现往往是孩子自信…...
LabVIEW自定义测量参数怎么设置?
以下通过一个温度采集案例,说明在 LabVIEW 中设置自定义测量参数的具体方法: 案例背景 假设使用 NI USB-6009 数据采集卡 和 热电偶传感器 监测温度,需自定义以下参数: 采样率:1 kHz 输入量程:0~10 V&a…...
Vim的基础命令
移动光标 H(左) J(上) K(下) L(右) $ 表示移动到光标所在行的行尾, ^ 表示移动到光标所在行的行首的第一个非空白字符。 0 表示移动到光标所在行的行首。 W 光标向前跳转一个单词 w光标向前跳转一个单词 B光标向后跳转一个单词 b光标向后跳转一个单词 G 移动光标到…...
SpringCloud详细讲解
学习目标 微服务框架SpringCloud的核心组件分布式与集群Spring Cloud 优缺点 微服务框架 微服务框架是将某个应用程序开发划分为多个小型服务独立进行业务开发的一种架构模式。以下是对微服务框架的详细介绍: 一、定义与特点 定义:微服务框架围绕业务…...
使用 OpenGL ES 在 iOS 上渲染一个四边形:从基础到实现
使用 OpenGL ES 在 iOS 上渲染一个四边形:从基础到实现 在 iOS 开发中,OpenGL ES 是一个强大的工具,用于实现高性能的 2D 和 3D 图形渲染。本文将详细分析一段完整的代码,展示如何使用 OpenGL ES 在 iOS 上渲染一个简单的四边形。…...
98.2 AI量化开发:基于DeepSeek打造个人专属金融消息面-AI量化分析师(理论+全套Python代码)
目录 0. 承前1. 金融工程结构图2. Why is DeepSeek3. 项目实现代码3.1 导入python库3.2 参数设置3.3 获取数据3.4 数据处理3.5 AI人设提示词3.6 Messages构建3.7 AI Agent3.8 response格式处理3.9 汇总函数3.10 运行案例 4. 总结4.1 系统优点4.2 系统缺点4.3 可提升方向 0. 承前…...
复制粘贴小工具——Ditto
在日常工作中,复制粘贴是常见的操作,但Windows系统自带的剪贴板功能较为有限,只能保存最近一次的复制记录,这对于需要频繁复制粘贴的用户来说不太方便。今天,我们介绍一款开源、免费且功能强大的剪贴板增强工具——Dit…...
中国人名汉语拼音字母拼写规则
中国人名汉语拼音字母拼写规则 1. Lv and Lyu2. 中国人名汉语拼音字母拼写规则References 1. Lv and Lyu LongBench: A Bilingual, Multitask Benchmark for Long Context Understanding https://arxiv.org/abs/2308.14508 2. 中国人名汉语拼音字母拼写规则 http://www.moe.g…...
MAC OS安装Homebrew
文章目录 1.下载Homebrew2.完成安装3.验证安装4.更新 Homebrew作为一个包管理器,提供了一种简便的方式来安装、更新和卸载各种命令行工具和应用程序。相比于手动下载和编译源代码,或者从不同的网站下载安装包,使用Homebrew可以显著减少这些操…...
计算机组成原理——存储系统(四)
当晨曦的第一缕光线划破夜空,那是宇宙给奋斗者的信号——光明属于那些在黑暗中依旧寻找希望的人。在这条通往梦想的道路上,每一步都充满挑战,但正是这些挑战定义了你的坚韧与不屈。不要满足于现状,因为你的潜力远超想象࿱…...
飞算JavaAI:开辟 AI + 行业趋势的编程新范式
在当今数字化浪潮汹涌澎湃的时代,科技的快速发展正以前所未有的速度重塑着各个行业的面貌。人工智能(AI)作为其中最具变革性的力量之一,已经深入渗透到众多领域,从金融、医疗到制造业、教育等,无一不在经历…...
Axure PR 9 动效 设计交互
大家好,我是大明同学。 这期内容,我们来用Axure制作一组动效。 动效 创建动效元件 1.打开一个新的 RP 文件并在画布上打开 Page 1。 2.选中画布,将画布填充颜色设置为蓝色(#0052D9)。 3.在元件库中拖出一个圆形元件,选中矩形元件&…...
