tools: add flash_loader
Signed-off-by: liangkangnan <liangkangnan@163.com>pull/4/head
parent
27dc2ed0c1
commit
cfc170f896
|
@ -0,0 +1,9 @@
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.bin
|
||||||
|
*.dump
|
||||||
|
*.mem
|
||||||
|
flash_loader
|
||||||
|
tinyriscv.inc
|
|
@ -0,0 +1,58 @@
|
||||||
|
TARGET := flash_loader
|
||||||
|
|
||||||
|
BSP_DIR := ../../sdk/bsp
|
||||||
|
|
||||||
|
RISCV_TOOLS_PATH := /opt/riscv32/bin
|
||||||
|
RISCV_TOOLS_PREFIX := riscv32-unknown-elf-
|
||||||
|
|
||||||
|
RISCV_GCC := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)gcc)
|
||||||
|
RISCV_AS := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)as)
|
||||||
|
RISCV_GXX := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)g++)
|
||||||
|
RISCV_OBJDUMP := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)objdump)
|
||||||
|
RISCV_GDB := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)gdb)
|
||||||
|
RISCV_AR := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)ar)
|
||||||
|
RISCV_OBJCOPY := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)objcopy)
|
||||||
|
RISCV_READELF := $(abspath $(RISCV_TOOLS_PATH)/$(RISCV_TOOLS_PREFIX)readelf)
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
ASM_SRCS += start.S
|
||||||
|
|
||||||
|
C_SRCS += main.c
|
||||||
|
C_SRCS += $(BSP_DIR)/lib/flash_ctrl.c
|
||||||
|
|
||||||
|
LINKER_SCRIPT := link.ld
|
||||||
|
|
||||||
|
INCLUDES += -I$(BSP_DIR)/include
|
||||||
|
|
||||||
|
LDFLAGS += -Os -T $(LINKER_SCRIPT) -nostartfiles -Wl,--gc-sections -Wl,--check-sections
|
||||||
|
|
||||||
|
ASM_OBJS := $(ASM_SRCS:.S=.o)
|
||||||
|
C_OBJS := $(C_SRCS:.c=.o)
|
||||||
|
|
||||||
|
LINK_OBJS += $(ASM_OBJS) $(C_OBJS)
|
||||||
|
LINK_DEPS += $(LINKER_SCRIPT)
|
||||||
|
|
||||||
|
CLEAN_OBJS += $(TARGET) $(LINK_OBJS) $(TARGET).dump $(TARGET).bin $(TARGET).hex $(TARGET).mem tinyriscv.inc
|
||||||
|
|
||||||
|
CFLAGS += -march=rv32im
|
||||||
|
CFLAGS += -mabi=ilp32
|
||||||
|
CFLAGS += -mcmodel=medlow -ffunction-sections -fdata-sections -fno-builtin-printf -fno-builtin-malloc
|
||||||
|
|
||||||
|
$(TARGET): $(LINK_OBJS) $(LINK_DEPS) Makefile
|
||||||
|
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) $(LINK_OBJS) -o $@ $(LDFLAGS)
|
||||||
|
$(RISCV_OBJCOPY) -O binary $@ $@.bin
|
||||||
|
$(RISCV_OBJDUMP) --disassemble-all $@ > $@.dump
|
||||||
|
./bin2char.sh < flash_loader.bin > tinyriscv.inc
|
||||||
|
|
||||||
|
$(ASM_OBJS): %.o: %.S
|
||||||
|
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||||
|
|
||||||
|
$(C_OBJS): %.o: %.c
|
||||||
|
$(RISCV_GCC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f $(CLEAN_OBJS)
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ $# != 0 ] && {
|
||||||
|
echo "Usage: $0"
|
||||||
|
echo
|
||||||
|
echo "Read binary data from standard input and write it as a comma separated"
|
||||||
|
echo "list of hexadecimal byte values to standard ouput. The output is usable"
|
||||||
|
echo "as a C array initializer. It is terminated with a comma so it can be"
|
||||||
|
echo "continued e.g. for zero termination."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "/* Autogenerated with $0 */"
|
||||||
|
od -v -A n -t x1 | sed 's/ *\(..\) */0x\1,/g'
|
|
@ -0,0 +1,148 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
flash (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||||
|
ram (wxa!ri) : ORIGIN = 0x20001000, LENGTH = 1K
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 256;
|
||||||
|
|
||||||
|
.init :
|
||||||
|
{
|
||||||
|
KEEP (*(SORT_NONE(.init)))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text.unlikely .text.unlikely.*)
|
||||||
|
*(.text.startup .text.startup.*)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
PROVIDE (__etext = .);
|
||||||
|
PROVIDE (_etext = .);
|
||||||
|
PROVIDE (etext = .);
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
/* gcc uses crtbegin.o to find the start of
|
||||||
|
the constructors, so we make sure it is
|
||||||
|
first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not
|
||||||
|
actually link against crtbegin.o; the
|
||||||
|
linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it
|
||||||
|
doesn't matter which directory crtbegin.o
|
||||||
|
is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*crtbegin?.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from
|
||||||
|
the crtend.o file until after the sorted ctors.
|
||||||
|
The .ctor section from the crtend file contains the
|
||||||
|
end of ctors marker and it must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.lalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data_lma = . );
|
||||||
|
} >flash AT>flash
|
||||||
|
|
||||||
|
.dalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _data = . );
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.rdata)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||||
|
*(.sdata .sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.srodata.cst16)
|
||||||
|
*(.srodata.cst8)
|
||||||
|
*(.srodata.cst4)
|
||||||
|
*(.srodata.cst2)
|
||||||
|
*(.srodata .srodata.*)
|
||||||
|
} >ram AT>flash
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE( _edata = . );
|
||||||
|
PROVIDE( edata = . );
|
||||||
|
|
||||||
|
PROVIDE( _fbss = . );
|
||||||
|
PROVIDE( __bss_start = . );
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.sbss*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >ram AT>ram
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
PROVIDE( _end = . );
|
||||||
|
PROVIDE( end = . );
|
||||||
|
|
||||||
|
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
|
||||||
|
{
|
||||||
|
PROVIDE( _heap_end = . );
|
||||||
|
. = __stack_size;
|
||||||
|
PROVIDE( _sp = . );
|
||||||
|
__freertos_irq_stack_top = .;
|
||||||
|
} >ram AT>ram
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "flash_ctrl.h"
|
||||||
|
|
||||||
|
|
||||||
|
// 烧写数据地址:4K + 1K + 256
|
||||||
|
#define DATA_ADDR (0x20001500)
|
||||||
|
|
||||||
|
// 烧写数据长度
|
||||||
|
#define DATA_LEN (0x20001400)
|
||||||
|
|
||||||
|
// 烧写(擦除)地址
|
||||||
|
#define PROGRAM_ADDR (0x20001404)
|
||||||
|
|
||||||
|
// 擦除标志
|
||||||
|
// 0: 不擦除,1:擦除
|
||||||
|
#define ERASE_FLAG (0x20001408)
|
||||||
|
|
||||||
|
// 烧写状态标志
|
||||||
|
// bit0为烧写结束标志,0:未烧写完成,1:烧写完成。
|
||||||
|
// bit1为烧写结果标志,0:烧写失败,1:烧写成功
|
||||||
|
#define RESULT_FLAG (0x2000140C)
|
||||||
|
|
||||||
|
#define PAGE_SIZE (256)
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t *data_p;
|
||||||
|
static uint32_t *result_p;
|
||||||
|
static uint32_t len, addr;
|
||||||
|
static uint32_t erase;
|
||||||
|
static uint8_t succ;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
data_p = (uint32_t *)DATA_ADDR;
|
||||||
|
result_p = (uint32_t *)RESULT_FLAG;
|
||||||
|
len = *((uint32_t *)DATA_LEN);
|
||||||
|
addr = *((uint32_t *)PROGRAM_ADDR);
|
||||||
|
erase = *((uint32_t *)ERASE_FLAG);
|
||||||
|
|
||||||
|
*result_p = 0;
|
||||||
|
|
||||||
|
flash_ctrl_init();
|
||||||
|
|
||||||
|
// 擦除操作
|
||||||
|
if (erase) {
|
||||||
|
// 擦除子扇区
|
||||||
|
succ = flash_ctrl_sector_erase(addr);
|
||||||
|
// 编程操作
|
||||||
|
} else {
|
||||||
|
// 编程
|
||||||
|
succ = flash_ctrl_page_program(addr, data_p, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_ctrl_deinit();
|
||||||
|
|
||||||
|
if (succ)
|
||||||
|
*result_p = 0x3;
|
||||||
|
else
|
||||||
|
*result_p = 0x1;
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
.section .init;
|
||||||
|
.globl _start;
|
||||||
|
.type _start,@function
|
||||||
|
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.option push
|
||||||
|
.option norelax
|
||||||
|
la gp, __global_pointer$
|
||||||
|
.option pop
|
||||||
|
la sp, _sp
|
||||||
|
|
||||||
|
/* Load data section */
|
||||||
|
la a0, _data_lma
|
||||||
|
la a1, _data
|
||||||
|
la a2, _edata
|
||||||
|
bgeu a1, a2, 2f
|
||||||
|
1:
|
||||||
|
lw t0, (a0)
|
||||||
|
sw t0, (a1)
|
||||||
|
addi a0, a0, 4
|
||||||
|
addi a1, a1, 4
|
||||||
|
bltu a1, a2, 1b
|
||||||
|
2:
|
||||||
|
|
||||||
|
/* Clear bss section */
|
||||||
|
la a0, __bss_start
|
||||||
|
la a1, _end
|
||||||
|
bgeu a0, a1, 2f
|
||||||
|
1:
|
||||||
|
sw zero, (a0)
|
||||||
|
addi a0, a0, 4
|
||||||
|
bltu a0, a1, 1b
|
||||||
|
2:
|
||||||
|
|
||||||
|
li a0, 0
|
||||||
|
li a1, 0
|
||||||
|
call main
|
||||||
|
|
||||||
|
loop:
|
||||||
|
j loop
|
Loading…
Reference in New Issue