参考友晶科技的https://github.com/johnnyfan1979/public_doc/blob/main/documentation/DE25_Nano/DE25%20Nano%20Build%20Linux%20image%20from%20scratch.md 教程制作image之后,想在uboot阶段运行uboot应用程序,需要先编译uboot应用程序。

 

首先在 u-boot-fpga/examples/standalone 路径下的makefile我添加了一行:

企业微信截图_17821203703550

 设置编译链环境变量:

Screenshot from 2026-06-22 21-49-38

 

在u-boot-fpga路径下 执行make examples 没有看到.bin文件产生:

Screenshot from 2026-06-22 05-39-42

 

原来是要使能u-boot api 和 example,在uboot源码路径下执行:

 

make menuconfig

 

然后选择General Setup:

Screenshot from 2026-06-22 21-32-23

 

选择Enable U-Boot API,键入Y选择该项:

Screenshot from 2026-06-22 21-43-20

 

选择API出现如下界面, 选择Compile API examples, 键入Y,出现(0x0C100000)Address in memory to link standalone applications to:

 

Screenshot from 2026-06-22 21-45-05

 将程序运行地址改为0x04100000(针对DE25-Nano开发板):

Screenshot from 2026-06-22 21-44-21

 然后保存设置:

Screenshot from 2026-06-22 21-45-39

 再执行 make examples:

Screenshot from 2026-06-22 22-16-20

 

 

备注:如若执行make menuconfig遇到提示:

Unable to find the ncurses package. 

Install ncurses(ncurses-devel or libncurses-dev

depending on your distribution).
make[1]:*** [scripts/kconfig/Makefile:227: scripts/kconfig/.mconf-cfg] Error 1
make: *** 「Makefile:586:menuconfiglError 2

Screenshot from 2026-06-22 21-35-28

 

 请执行如下命令:

 

sudo apt update

sudo apt install libscurses-dev

 

 

 

 

uboot_blink_app.c源码如下:

#include <exports.h>



/* Macro for reading from memory */
#define readl(addr)    *((volatile unsigned int *)(addr))

/* Macro for writing to memory */
#define writel(value,addr)    *((volatile unsigned int *)(addr)) = (value)

/* Agilex 5 Lightweight HPS-to-FPGA桥和HPS-to-FPGA桥的基地址 */
#define LW_H2F_BASE             0x20000000
#define H2F_BASE                0x40000000

/* FPGA 外设偏移地址 (Platform Designer中的地址) */
#define SYSTEM_ID_PIO_OFFSET     0x00010000      /* 请根据您的GHRD填写 */
#define LED_PIO_OFFSET           0x00010080
#define BUTTON_PIO_OFFSET        0x00010060
#define SWITCH_PIO_OFFSET        0x00010070
#define OCRAM_64K_OFFSET         0x00000000

/* FPGA 外设偏移地址 (Platform Designer中的地址) */
#define SYSTEM_ID_BASE            (LW_H2F_BASE + SYSTEM_ID_PIO_OFFSET)
#define LED_PIO_BASE            (LW_H2F_BASE + LED_PIO_OFFSET)
#define BUTTON_PIO_BASE            (LW_H2F_BASE + BUTTON_PIO_OFFSET)
#define SWITCH_PIO_BASE            (LW_H2F_BASE + SWITCH_PIO_OFFSET)
#define OCRAM_64K_BASE            (H2F_BASE + OCRAM_64K_OFFSET)


#define OCRAM_64K_SIZE_VALUE 65536
#define LED_PIO_DATA_WIDTH 7

#define LED_DELAY_US 250000

void demo_sysid(void);
void demo_ocram(void);
void demo_leds(void);
void demo_switches(void);
void demo_buttons(void);

int blink_app(int argc, char * const argv[]) {

    int i;

    /* Start application */
    app_startup(argv);

    /* Display welcome message */
    printf("\n");
    printf("Blink application started.\n");
    printf("\n");

    /* Display command line parameters */
    printf("Number of command line parameters: %d\n", argc);
    for(i=0; i<argc; i++)
        printf("Command line parameter %d = %s\n", (i + 1), argv[i]);

    printf("\n");

    /* Display U-Booot ABI version */
    printf("U-Boot ABI version %d\n", (int)get_version());
    printf("\n");

    /* Exercise FPGA IP */
    demo_sysid();
    demo_ocram();
    demo_leds();
    demo_switches();
    demo_buttons();

    /* Goodbye message */
    printf("Blink Application completed.\n");
    printf("\n");

    return(0);
}

void demo_sysid(void) {

    /* Display SysID parameters */
    printf("SysID.id = 0x%08x\n", (int)readl(SYSTEM_ID_BASE));
    printf("SysID.timestamp = 0x%08x\n", (int)readl(SYSTEM_ID_BASE + 0x4));
    printf("\n");
}

void demo_ocram(void) {

    unsigned int * ptr = (unsigned int *)OCRAM_64K_BASE;
    unsigned int i;

    printf("Writing pattern into FPGA OCRAM.\n");
    for(i = 0; i< OCRAM_64K_SIZE_VALUE / sizeof(unsigned int); i++)
        ptr[i] = i;

    printf("Checking pattern from FPGA OCRAM: ");
    for(i = 0; i< OCRAM_64K_SIZE_VALUE / sizeof(unsigned int); i++) {
        if(ptr[i] != i) {
            printf("FAILED.\n");
            return;
        }
    }

    printf("passed.\n");
    printf("\n");
}

void demo_leds(void) {

    unsigned int led = 0;

    /* Blink the LEDs until any key is pressed */
    printf("Blinking LEDs\n");
    printf("Press any key to stop LED lightshow\n");
    while(!tstc()) {

        /* Turn on LED */
        writel(1L << led, LED_PIO_BASE);

        /* Delay */
        udelay(LED_DELAY_US);

        /* Advance to next LED */
        led = (led + 1) % LED_PIO_DATA_WIDTH;
    }

    /* Discard the key that was pressed */
    (void) getc();
    printf("\n");
}

void demo_switches(void) {

    unsigned int switches, prev_switches;

    /* Display state of switches */
    printf("Displaying the state of switches\n");
    printf("Slide switch SW0, Sw1, SW2 or SW3 to observe updates\n");
    printf("Press any key to stop displaying the switches\n");
    prev_switches = ~readl(SWITCH_PIO_BASE);

    while(!tstc()) {
        switches = readl(SWITCH_PIO_BASE);
        if(switches != prev_switches) {
            printf("Switch value: 0x%01x\n", (int)switches);
            prev_switches = switches;
        }
    }

    /* Discard the key that was pressed */
    (void) getc();
    printf("\n");
}

void demo_buttons(void) {

    unsigned int buttons, prev_buttons;

    /* Display state of buttons */
    printf("Displaying the state of buttons\n");
    printf("Press push button KEY1 to observe updates\n");
    printf("Press any key to stop displaying the buttons\n");
    prev_buttons = ~readl(BUTTON_PIO_BASE);

    while(!tstc()) {
        buttons = readl(BUTTON_PIO_BASE);
        if(buttons != prev_buttons) {
            printf("Button value: 0x%01x\n", (int)buttons);
            prev_buttons = buttons;
        }
    }

    /* Discard the key that was pressed */
    (void) getc();
    printf("\n");
}