赞
踩
目录
NANO 9K低成本体验FPGA开发,还是挺香的,官方例子有加载PICORV32软核的例子,可以建立简单的ISP编程环境,通过串口就可以加载程序,很方便。
Tang Nano 9K picoRV 简单示例 - Sipeed Wiki
运行效果
可以通过命令行进行点灯喝运行benchmark等操作。
相当于例子包括了:
等基本操作。
如果要基于RISCV软核,进一步熟悉工作机制和编程环境,需要参考例子建立交叉编译环境。
step by step.......,以下基于虚拟机运行ubuntu18.04环境,少一点干扰。
为帮助理解, 可以看看高云的官方文档对于picorv32内核架构的介绍:
在虚拟机环境下,解压toolchain到目标目录即可。编译器路径可以在makefile文件里进行指定。
当然,虚拟机依赖环境至少需要安装make工具,gcc也一起
sudo apt-get install make gcc
下载地址:
riscv32交叉编译器,ubuntu18.04亲测可用资源-CSDN文库
参考文章:
从零开始:一步步教你如何写Makefile_makefile菜鸟教程-CSDN博客
makefile组成三要素:目标,依赖, 命令
picotiny工作示例里有两层makefile, 先看主目录下的:
- PYTHON_NAME ?= python
- RISCV_NAME ?= riscv-none-embed
- RISCV_PATH ?= /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004
- MAKE ?= make
-
- FW_FILE = fw/fw-flash/build/fw-flash.v
-
- PROG_FILE ?= $(FW_FILE)
- COMx ?= COM14
-
- export PYTHON_NAME
- export RISCV_NAME
- export RISCV_PATH
-
-
- .PHONY: all brom flash clean program
-
- all: brom flash
-
- $(FW_FILE): flash
-
- brom:
- $(MAKE) -C fw/fw-brom
-
- flash:
- $(MAKE) -C fw/fw-flash
-
- clean:
- $(MAKE) -C fw/fw-brom clean
- $(MAKE) -C fw/fw-flash clean
-
- program: $(PROG_FILE)
- $(PYTHON_NAME) sw/pico-programmer.py $(PROG_FILE) $(COMx)
第一部分:指定环境变量
第二部分:指定分支
第三部分:分支命令编写
这个根目录下的makefile主要功能:一是执行不同的子目录下 ,二是program命令分支。
真正编译项目代码的makefile是在子目录下。
再来看子目录下的makefile
- PROJ_NAME=blink-flash
- DEBUG=no
- BENCH=no
- MULDIV=no
- COMPRESSED=no
-
- SRCS = $(wildcard *.c) \
- $(wildcard *.S)
-
- LDSCRIPT = ./linker_flash.ld
-
- RISCV_NAME ?= riscv-none-embed
- RISCV_PATH ?= /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004
-
- MABI=ilp32
- MARCH := rv32i
- ifeq ($(MULDIV),yes)
- MARCH := $(MARCH)m
- endif
- ifeq ($(COMPRESSED),yes)
- MARCH := $(MARCH)ac
- endif
-
- CFLAGS += -march=$(MARCH) -mabi=$(MABI) -ffunction-sections -fdata-sections
- LDFLAGS += -march=$(MARCH) -mabi=$(MABI) -Wl,--gc-sections
-
- ifeq ($(DEBUG),yes)
- CFLAGS += -g3 -O0
- endif
-
- ifeq ($(DEBUG),no)
- CFLAGS += -g -O3
- endif
-
- ifeq ($(BENCH),yes)
- CFLAGS += -fno-inline
- endif
-
- RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/$(MARCH)/$(MABI)/
-
- RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
- RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
- RISCV_CC = $(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
-
- CFLAGS += -MD -fstrict-volatile-bitfields
- LDFLAGS += -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
-
- OBJDIR = build
- OBJS := $(SRCS)
- OBJS := $(OBJS:.c=.o)
- OBJS := $(OBJS:.cpp=.o)
- OBJS := $(OBJS:.S=.o)
- OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
-
- SUBOBJ := $(addprefix $(OBJDIR)/,$(SUBDIRS))
- SUBOBJ := $(addsuffix /*.o,$(SUBOBJ))
-
- export RISCV_CC CFLAGS LDFLAGS OBJDIR
-
- all: $(SUBDIRS) $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
-
- $(SUBDIRS): ECHO
- make -C $@
-
- ECHO:
- @echo $(SUBDIRS)
-
- $(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
- $(RISCV_CC) $(CFLAGS) -o $@ $^ $(SUBOBJ) $(LDFLAGS) $(LIBS)
-
- %.hex: %.elf
- $(RISCV_OBJCOPY) -O ihex $^ $@
-
- %.bin: %.elf
- $(RISCV_OBJCOPY) -O binary $^ $@
-
- %.v: %.elf
- $(RISCV_OBJCOPY) -O verilog $^ $@
-
- %.asm: %.elf
- $(RISCV_OBJDUMP) -S -d $^ > $@
-
- $(OBJDIR)/%.o: %.c
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
-
- $(OBJDIR)/%.o: %.cpp
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
-
- $(OBJDIR)/%.o: %.S
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
-
- $(OBJDIR):
- mkdir -p $@
-
- clean:
- rm -f $(OBJDIR)/$(PROJ_NAME).elf
- rm -f $(OBJDIR)/$(PROJ_NAME).hex
- rm -f $(OBJDIR)/$(PROJ_NAME).map
- rm -f $(OBJDIR)/$(PROJ_NAME).v
- rm -f $(OBJDIR)/$(PROJ_NAME).asm
- find $(OBJDIR) -type f -name '*.d' -print0 | xargs -0 -r rm
- find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
-
- .SECONDARY: $(OBJS)
-
-
-
主要完成的工作: 指定了环境变量,编译输出目标文件,编译后的处理(文件转换等) 。
编写完示例代码后,可以在子目录下运行make命令,执行响应的makefile即可完成目标代码编译。
烧录的riscv软核支持ISP(串口在线烧录)功能。 所以make program xxx命令调用的python脚本主要是握手协议和烧录固件的传输。
简单理解: 软核的ISP功能完成了flash固件的调用启动和程序引导运行工作。
小知识: 理解ISP
ISP的全称是:In System Programming,即在系统编程,该操作是通过MCU厂商出厂BootLoader来实现,通过ISP可以对主flash区域进行擦除、编程操作,还可以修改芯片的选项字节等。
ISP的实现逻辑是出厂“芯片”(我们这里是软核)自带了BootLoader程序,即出厂引导程序,通过BootLoader可以将程序从串口(上位机)下载到Flash中,实际的时序是通过RST来区分正常启动还是烧录状态,然后上位机的烧录脚本来控制串口时序, 用户程序实际上是通过串口最终下载到了FLASH中,然后程序从flash启动。
blink主要是调用GPIO寄存器写入功能
- #include <stdint.h>
- #include <stdbool.h>
-
- // a pointer to this is a null pointer, but the compiler does not
- // know that because "sram" is a linker symbol from sections.lds.
- extern uint32_t sram;
-
- typedef struct {
- volatile uint32_t OUT;
- volatile uint32_t IN;
- volatile uint32_t OE;
- } PICOGPIO;
-
- // 寄存器地址
- #define GPIO0 ((PICOGPIO*)0x82000000)
-
-
- #define FLASHIO_ENTRY_ADDR ((void *)0x80000054)
-
-
- volatile int i;
- // --------------------------------------------------------
-
-
- void main()
- {
- GPIO0->OE = 0x3F;
- GPIO0->OUT = 0x3F;
-
-
- while (1)
- {
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x01;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x02;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x04;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x08;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x10;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x20;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x00;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F;
- for ( i = 0 ; i < 10000; i++);
-
- }
-
- }
-
- void irqCallback() {
-
- }
makefile,其实之修改了PROJ_NAME
- PROJ_NAME=blink-demo
- DEBUG=no
- BENCH=no
- MULDIV=no
- COMPRESSED=no
-
- SRCS = $(wildcard *.c) \
- $(wildcard *.S)
-
- LDSCRIPT = ./linker_flash.ld
-
- RISCV_NAME ?= riscv-none-embed
- RISCV_PATH ?= /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004
-
- MABI=ilp32
- MARCH := rv32i
- ifeq ($(MULDIV),yes)
- MARCH := $(MARCH)m
- endif
- ifeq ($(COMPRESSED),yes)
- MARCH := $(MARCH)ac
- endif
-
- CFLAGS += -march=$(MARCH) -mabi=$(MABI) -ffunction-sections -fdata-sections
- LDFLAGS += -march=$(MARCH) -mabi=$(MABI) -Wl,--gc-sections
-
- ifeq ($(DEBUG),yes)
- CFLAGS += -g3 -O0
- endif
-
- ifeq ($(DEBUG),no)
- CFLAGS += -g -O3
- endif
-
- ifeq ($(BENCH),yes)
- CFLAGS += -fno-inline
- endif
-
- RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/$(MARCH)/$(MABI)/
-
- RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
- RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
- RISCV_CC = $(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
-
- CFLAGS += -MD -fstrict-volatile-bitfields
- LDFLAGS += -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
-
- OBJDIR = build
- OBJS := $(SRCS)
- OBJS := $(OBJS:.c=.o)
- OBJS := $(OBJS:.cpp=.o)
- OBJS := $(OBJS:.S=.o)
- OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
-
- SUBOBJ := $(addprefix $(OBJDIR)/,$(SUBDIRS))
- SUBOBJ := $(addsuffix /*.o,$(SUBOBJ))
-
- export RISCV_CC CFLAGS LDFLAGS OBJDIR
-
- all: $(SUBDIRS) $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
-
- $(SUBDIRS): ECHO
- make -C $@
-
- ECHO:
- @echo $(SUBDIRS)
-
- $(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
- $(RISCV_CC) $(CFLAGS) -o $@ $^ $(SUBOBJ) $(LDFLAGS) $(LIBS)
-
- %.hex: %.elf
- $(RISCV_OBJCOPY) -O ihex $^ $@
-
- %.bin: %.elf
- $(RISCV_OBJCOPY) -O binary $^ $@
-
- %.v: %.elf
- $(RISCV_OBJCOPY) -O verilog $^ $@
-
- %.asm: %.elf
- $(RISCV_OBJDUMP) -S -d $^ > $@
-
- $(OBJDIR)/%.o: %.c
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
-
- $(OBJDIR)/%.o: %.cpp
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
-
- $(OBJDIR)/%.o: %.S
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
-
- $(OBJDIR):
- mkdir -p $@
-
- clean:
- rm -f $(OBJDIR)/$(PROJ_NAME).elf
- rm -f $(OBJDIR)/$(PROJ_NAME).hex
- rm -f $(OBJDIR)/$(PROJ_NAME).map
- rm -f $(OBJDIR)/$(PROJ_NAME).v
- rm -f $(OBJDIR)/$(PROJ_NAME).asm
- find $(OBJDIR) -type f -name '*.d' -print0 | xargs -0 -r rm
- find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
-
- .SECONDARY: $(OBJS)
-
-
-
项目目录下编译:
- /blink-demo$ make
- mkdir -p build/
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-gcc -c -march=rv32i -mabi=ilp32 -ffunction-sections -fdata-sections -g -O3 -MD -fstrict-volatile-bitfields -o build/main.o main.c
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -ffunction-sections -fdata-sections -g -O3 -MD -fstrict-volatile-bitfields -o build/blink-demo.elf build/main.o build/crt_flash.o -march=rv32i -mabi=ilp32 -Wl,--gc-sections -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,./linker_flash.ld,-Map,build/blink-demo.map,--print-memory-usage
- Memory region Used Size Region Size %age Used
- FLASH: 728 B 8 MB 0.01%
- RAM: 1040 B 8 KB 12.70%
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-objcopy -O ihex build/blink-demo.elf build/blink-demo.hex
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-objdump -S -d build/blink-demo.elf > build/blink-demo.asm
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-objcopy -O verilog build/blink-demo.elf build/blink-demo.v
生成的.v文件即用于执行的文件。
执行根目录下的make program来烧录
烧录成功:
- ...../picotiny$ make programBlink
- python sw/pico-programmer.py fw/blink-demo/build/blink-demo.v /dev/ttyUSB1
- Read program with 736 bytes
- - Waiting for reset -
- ...
- Total sectors 1
- Total pages 3
- Flashing 1 / 1
-
- Flashing completed
main.c:
-
-
- #include <stdint.h>
- #include <stdbool.h>
-
- // a pointer to this is a null pointer, but the compiler does not
- // know that because "sram" is a linker symbol from sections.lds.
- extern uint32_t sram;
-
- typedef struct {
- volatile uint32_t DATA;
- volatile uint32_t CLKDIV;
- } PICOUART;
-
- typedef struct {
- volatile uint32_t OUT;
- volatile uint32_t IN;
- volatile uint32_t OE;
- } PICOGPIO;
-
- typedef struct {
- union {
- volatile uint32_t REG;
- volatile uint16_t IOW;
- struct {
- volatile uint8_t IO;
- volatile uint8_t OE;
- volatile uint8_t CFG;
- volatile uint8_t EN;
- };
- };
- } PICOQSPI;
-
- #define QSPI0 ((PICOQSPI*)0x81000000)
- #define GPIO0 ((PICOGPIO*)0x82000000)
- #define UART0 ((PICOUART*)0x83000000)
-
- #define FLASHIO_ENTRY_ADDR ((void *)0x80000054)
-
- void (*spi_flashio)(uint8_t *pdata, int length, int wren) = FLASHIO_ENTRY_ADDR;
-
- int putchar(int c)
- {
- if (c == '\n')
- UART0->DATA = '\r';
- UART0->DATA = c;
-
- return c;
- }
-
- void print(const char *p)
- {
- while (*p)
- putchar(*(p++));
- }
-
- void print_hex(uint32_t v, int digits)
- {
- for (int i = 7; i >= 0; i--) {
- char c = "0123456789abcdef"[(v >> (4*i)) & 15];
- if (c == '0' && i >= digits) continue;
- putchar(c);
- digits = i;
- }
- }
-
- void print_dec(uint32_t v)
- {
- if (v >= 100) {
- print(">=100");
- return;
- }
-
- if (v >= 90) { putchar('9'); v -= 90; }
- else if (v >= 80) { putchar('8'); v -= 80; }
- else if (v >= 70) { putchar('7'); v -= 70; }
- else if (v >= 60) { putchar('6'); v -= 60; }
- else if (v >= 50) { putchar('5'); v -= 50; }
- else if (v >= 40) { putchar('4'); v -= 40; }
- else if (v >= 30) { putchar('3'); v -= 30; }
- else if (v >= 20) { putchar('2'); v -= 20; }
- else if (v >= 10) { putchar('1'); v -= 10; }
-
- if (v >= 9) { putchar('9'); v -= 9; }
- else if (v >= 8) { putchar('8'); v -= 8; }
- else if (v >= 7) { putchar('7'); v -= 7; }
- else if (v >= 6) { putchar('6'); v -= 6; }
- else if (v >= 5) { putchar('5'); v -= 5; }
- else if (v >= 4) { putchar('4'); v -= 4; }
- else if (v >= 3) { putchar('3'); v -= 3; }
- else if (v >= 2) { putchar('2'); v -= 2; }
- else if (v >= 1) { putchar('1'); v -= 1; }
- else putchar('0');
- }
-
- char getchar_prompt(char *prompt)
- {
- int32_t c = -1;
-
- uint32_t cycles_begin, cycles_now, cycles;
- __asm__ volatile ("rdcycle %0" : "=r"(cycles_begin));
-
- if (prompt)
- print(prompt);
-
- // if (prompt)
- // GPIO0->OUT = ~0;
- // reg_leds = ~0;
-
- while (c == -1) {
- __asm__ volatile ("rdcycle %0" : "=r"(cycles_now));
- cycles = cycles_now - cycles_begin;
- if (cycles > 12000000) {
- if (prompt)
- print(prompt);
- cycles_begin = cycles_now;
- // if (prompt)
- // GPIO0->OUT = ~GPIO0->OUT;
- // reg_leds = ~reg_leds;
- }
- c = UART0->DATA;
- }
- // if (prompt)
- // GPIO0->OUT = 0;
- // reg_leds = 0;
- return c;
- }
-
- char getchar()
- {
- return getchar_prompt(0);
- }
-
- #define QSPI_REG_CRM 0x00100000
- #define QSPI_REG_DSPI 0x00400000
-
- void cmd_set_crm(int on)
- {
- if (on) {
- QSPI0->REG |= QSPI_REG_CRM;
- } else {
- QSPI0->REG &= ~QSPI_REG_CRM;
- }
- }
-
- int cmd_get_crm() {
- return QSPI0->REG & QSPI_REG_CRM;
- }
-
- volatile int i;
- // --------------------------------------------------------
-
- #define CLK_FREQ 25175000
- #define UART_BAUD 115200
-
- void main()
- {
- UART0->CLKDIV = CLK_FREQ / UART_BAUD - 2;
-
- GPIO0->OE = 0x3F;
- GPIO0->OUT = 0x3F;
-
- cmd_set_crm(1);
-
-
- print("\n");
- print(" ____ _ ____ ____\n");
- print(" | _ \\(_) ___ ___/ ___| ___ / ___|\n");
- print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
- print(" | __/| | (_| (_) |__) | (_) | |___\n");
- print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
- print("\n");
- print(" On Lichee Tang Nano-9K\n");
- print("\n");
-
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x01;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x02;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x04;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x08;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x10;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F ^ 0x20;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x00;
- for ( i = 0 ; i < 10000; i++);
- GPIO0->OUT = 0x3F;
- for ( i = 0 ; i < 10000; i++);
-
- while (1)
- {
- print("\n");
- print("Select an action:\n");
- print("\n");
- print(" [1] Toggle led 1\n");
- print(" [2] Toggle led 2\n");
- print(" [3] Toggle led 3\n");
- print(" [4] Toggle led 4\n");
- print(" [5] Toggle led 5\n");
- print(" [6] Toggle led 6\n");
-
-
- for (int rep = 10; rep > 0; rep--)
- {
- print("\n");
- print("IO State: ");
- print_hex(GPIO0->IN, 8);
- print("\n");
-
- print("\n");
-
- print("Command> ");
- char cmd = getchar();
- if (cmd > 32 && cmd < 127)
- putchar(cmd);
- print("\n");
-
- switch (cmd)
- {
-
-
- case '1':
- GPIO0->OUT ^= 0x00000001;
- break;
-
- case '2':
- GPIO0->OUT ^= 0x00000002;
- break;
-
- case '3':
- GPIO0->OUT ^= 0x00000004;
- break;
-
- case '4':
- GPIO0->OUT ^= 0x00000008;
- break;
-
- case '5':
- GPIO0->OUT ^= 0x00000010;
- break;
-
- case '6':
- GPIO0->OUT ^= 0x00000020;
- break;
-
- default:
- continue;
- }
- }
- }
- }
-
- void irqCallback() {
-
- }
makefile:
- PROJ_NAME=uart-demo
- DEBUG=no
- BENCH=no
- MULDIV=no
- COMPRESSED=no
-
- SRCS = $(wildcard *.c) \
- $(wildcard *.S)
-
- LDSCRIPT = ./linker_flash.ld
-
- RISCV_NAME ?= riscv-none-embed
- RISCV_PATH ?= /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004
-
- MABI=ilp32
- MARCH := rv32i
- ifeq ($(MULDIV),yes)
- MARCH := $(MARCH)m
- endif
- ifeq ($(COMPRESSED),yes)
- MARCH := $(MARCH)ac
- endif
-
- CFLAGS += -march=$(MARCH) -mabi=$(MABI) -ffunction-sections -fdata-sections
- LDFLAGS += -march=$(MARCH) -mabi=$(MABI) -Wl,--gc-sections
-
- ifeq ($(DEBUG),yes)
- CFLAGS += -g3 -O0
- endif
-
- ifeq ($(DEBUG),no)
- CFLAGS += -g -O3
- endif
-
- ifeq ($(BENCH),yes)
- CFLAGS += -fno-inline
- endif
-
- RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/$(MARCH)/$(MABI)/
-
- RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
- RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
- RISCV_CC = $(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
-
- CFLAGS += -MD -fstrict-volatile-bitfields
- LDFLAGS += -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
-
- OBJDIR = build
- OBJS := $(SRCS)
- OBJS := $(OBJS:.c=.o)
- OBJS := $(OBJS:.cpp=.o)
- OBJS := $(OBJS:.S=.o)
- OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
-
- SUBOBJ := $(addprefix $(OBJDIR)/,$(SUBDIRS))
- SUBOBJ := $(addsuffix /*.o,$(SUBOBJ))
-
- export RISCV_CC CFLAGS LDFLAGS OBJDIR
-
- all: $(SUBDIRS) $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
-
- $(SUBDIRS): ECHO
- make -C $@
-
- ECHO:
- @echo $(SUBDIRS)
-
- $(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
- $(RISCV_CC) $(CFLAGS) -o $@ $^ $(SUBOBJ) $(LDFLAGS) $(LIBS)
-
- %.hex: %.elf
- $(RISCV_OBJCOPY) -O ihex $^ $@
-
- %.bin: %.elf
- $(RISCV_OBJCOPY) -O binary $^ $@
-
- %.v: %.elf
- $(RISCV_OBJCOPY) -O verilog $^ $@
-
- %.asm: %.elf
- $(RISCV_OBJDUMP) -S -d $^ > $@
-
- $(OBJDIR)/%.o: %.c
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
-
- $(OBJDIR)/%.o: %.cpp
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
-
- $(OBJDIR)/%.o: %.S
- mkdir -p $(dir $@)
- $(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
-
- $(OBJDIR):
- mkdir -p $@
-
- clean:
- rm -f $(OBJDIR)/$(PROJ_NAME).elf
- rm -f $(OBJDIR)/$(PROJ_NAME).hex
- rm -f $(OBJDIR)/$(PROJ_NAME).map
- rm -f $(OBJDIR)/$(PROJ_NAME).v
- rm -f $(OBJDIR)/$(PROJ_NAME).asm
- find $(OBJDIR) -type f -name '*.d' -print0 | xargs -0 -r rm
- find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
-
- .SECONDARY: $(OBJS)
-
-
-
项目子目录下编译结果,生成目标文件:
- /uart-demo$ make
- mkdir -p build/
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-gcc -c -march=rv32i -mabi=ilp32 -ffunction-sections -fdata-sections -g -O3 -MD -fstrict-volatile-bitfields -o build/main.o main.c
- mkdir -p build/
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-gcc -c -march=rv32i -mabi=ilp32 -ffunction-sections -fdata-sections -g -O3 -MD -fstrict-volatile-bitfields -o build/crt_flash.o crt_flash.S -D__ASSEMBLY__=1
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -ffunction-sections -fdata-sections -g -O3 -MD -fstrict-volatile-bitfields -o build/uart-demo.elf build/main.o build/crt_flash.o -march=rv32i -mabi=ilp32 -Wl,--gc-sections -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,./linker_flash.ld,-Map,build/uart-demo.map,--print-memory-usage
- Memory region Used Size Region Size %age Used
- FLASH: 3152 B 8 MB 0.04%
- RAM: 1040 B 8 KB 12.70%
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-objcopy -O ihex build/uart-demo.elf build/uart-demo.hex
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-objdump -S -d build/uart-demo.elf > build/uart-demo.asm
- /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004/bin/riscv-none-embed-objcopy -O verilog build/uart-demo.elf build/uart-demo.v
根目录下烧录运行:
makefile增加选项programUart:
-
- PYTHON_NAME ?= python
- RISCV_NAME ?= riscv-none-embed
- RISCV_PATH ?= /home/hy/riscv/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.2-20190521-0004
- MAKE ?= make
-
- FW_FILE_BLINK = fw/blink-demo/build/blink-demo.v
- FW_FILE_UART = fw/uart-demo/build/uart-demo.v
-
-
- PROG_FILE_BLINK ?= $(FW_FILE_BLINK)
- PROG_FILE_UART ?= $(FW_FILE_UART)
-
- COMx ?= /dev/ttyUSB1
-
- export PYTHON_NAME
- export RISCV_NAME
- export RISCV_PATH
-
-
- .PHONY: all brom flash clean program
-
- all: brom flash
-
- $(FW_FILE): flash
-
- brom:
- $(MAKE) -C fw/fw-brom
-
- flash:
- $(MAKE) -C fw/blink-demo
-
- clean:
- $(MAKE) -C fw/fw-brom clean
- $(MAKE) -C fw/fw-flash clean
-
-
- program: $(PROG_FILE)
- $(PYTHON_NAME) sw/pico-programmer.py $(PROG_FILE) $(COMx)
-
- programBlink: $(PROG_FILE_BLINK)
- $(PYTHON_NAME) sw/pico-programmer.py $(PROG_FILE_BLINK) $(COMx)
-
- programUart: $(PROG_FILE_UART)
- $(PYTHON_NAME) sw/pico-programmer.py $(PROG_FILE_UART) $(COMx)
运行烧录:
- /picotiny$ make programUart
- python sw/pico-programmer.py fw/uart-demo/build/uart-demo.v /dev/ttyUSB1
- Read program with 3152 bytes
- - Waiting for reset -
- ..
- Total sectors 1
- Total pages 13
- Flashing 1 / 1
-
- Flashing completed
调用cutecom运行页面:
输入框输入1-6可以控制对应的LED亮灭。
1)延申理解,通过官方开发包,编写更易于移植和开发的库
2)理解配合软核的SDK架构(理解指令集) 和HAL库的基本逻辑。 理解SDK应该按什么逻辑来规划
3)移植FREERTOS, 理解操作系统移植的基本逻辑
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。