diff --git a/tests/example/gpio/Makefile b/tests/example/gpio/Makefile new file mode 100644 index 0000000..607fcd6 --- /dev/null +++ b/tests/example/gpio/Makefile @@ -0,0 +1,25 @@ + +RISCV_ARCH := rv32im +RISCV_ABI := ilp32 + +RISCV_PATH := ../../../tools/gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004-win64/ + +CFLAGS += -march=$(RISCV_ARCH) +CFLAGS += -mabi=$(RISCV_ABI) +CFLAGS += -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles + +RISCV_GCC := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-gcc) +RISCV_AS := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-as) +RISCV_GXX := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-g++) +RISCV_OBJDUMP := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-objdump) +RISCV_GDB := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-gdb) +RISCV_AR := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-ar) +RISCV_OBJCOPY := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-objcopy) +RISCV_READELF := $(abspath $(RISCV_PATH)/bin/riscv-none-embed-readelf) + + +.PHONY: all +all: + $(RISCV_GCC) $(CFLAGS) start.S main.c -Tlink.ld -o gpio + $(RISCV_OBJCOPY) -O binary gpio gpio.bin + $(RISCV_OBJDUMP) --disassemble-all gpio > gpio.dump diff --git a/tests/example/gpio/README.md b/tests/example/gpio/README.md new file mode 100644 index 0000000..6f6e00a --- /dev/null +++ b/tests/example/gpio/README.md @@ -0,0 +1 @@ +通过一个GPIO来控制板上的LED以1Hz频率闪烁。 \ No newline at end of file diff --git a/tests/example/gpio/gpio b/tests/example/gpio/gpio new file mode 100644 index 0000000..e67add9 Binary files /dev/null and b/tests/example/gpio/gpio differ diff --git a/tests/example/gpio/gpio.bin b/tests/example/gpio/gpio.bin new file mode 100644 index 0000000..20a2c53 Binary files /dev/null and b/tests/example/gpio/gpio.bin differ diff --git a/tests/example/gpio/gpio.dump b/tests/example/gpio/gpio.dump new file mode 100644 index 0000000..40632f2 --- /dev/null +++ b/tests/example/gpio/gpio.dump @@ -0,0 +1,167 @@ + +gpio: file format elf32-littleriscv + + +Disassembly of section .init: + +00000000 <_start>: + 0: 0040006f j 4 <_reset_handler> + +00000004 <_reset_handler>: + 4: 10000197 auipc gp,0x10000 + 8: 7fc18193 addi gp,gp,2044 # 10000800 <__global_pointer$> + c: 00018113 mv sp,gp + 10: 00000d13 li s10,0 + 14: 00000d93 li s11,0 + 18: 1d000513 li a0,464 + 1c: 10000597 auipc a1,0x10000 + 20: fe458593 addi a1,a1,-28 # 10000000 <_data> + 24: 10000617 auipc a2,0x10000 + 28: fdc60613 addi a2,a2,-36 # 10000000 <_data> + 2c: 00c5fc63 bgeu a1,a2,44 <_reset_handler+0x40> + 30: 00052283 lw t0,0(a0) + 34: 0055a023 sw t0,0(a1) + 38: 00450513 addi a0,a0,4 + 3c: 00458593 addi a1,a1,4 + 40: fec5e8e3 bltu a1,a2,30 <_reset_handler+0x2c> + 44: 10000517 auipc a0,0x10000 + 48: fbc50513 addi a0,a0,-68 # 10000000 <_data> + 4c: 10000597 auipc a1,0x10000 + 50: fb458593 addi a1,a1,-76 # 10000000 <_data> + 54: 00b57863 bgeu a0,a1,64 <_reset_handler+0x60> + 58: 00052023 sw zero,0(a0) + 5c: 00450513 addi a0,a0,4 + 60: feb56ce3 bltu a0,a1,58 <_reset_handler+0x54> + 64: 134000ef jal ra,198
+ 68: 00100d13 li s10,1 + +0000006c : + 6c: 0000006f j 6c + +Disassembly of section .text: + +00000070 : + 70: fb010113 addi sp,sp,-80 + 74: 04812623 sw s0,76(sp) + 78: 05010413 addi s0,sp,80 + 7c: faa42e23 sw a0,-68(s0) + 80: c0002773 rdcycle a4 + 84: fee42623 sw a4,-20(s0) + 88: fec42703 lw a4,-20(s0) + 8c: fee42023 sw a4,-32(s0) + 90: fe042223 sw zero,-28(s0) + 94: c8002773 rdcycleh a4 + 98: fce42e23 sw a4,-36(s0) + 9c: fdc42703 lw a4,-36(s0) + a0: 00070793 mv a5,a4 + a4: 00000813 li a6,0 + a8: 00079e93 slli t4,a5,0x0 + ac: 00000e13 li t3,0 + b0: fe042683 lw a3,-32(s0) + b4: fe442703 lw a4,-28(s0) + b8: 01c687b3 add a5,a3,t3 + bc: 00078513 mv a0,a5 + c0: 00d53533 sltu a0,a0,a3 + c4: 01d70833 add a6,a4,t4 + c8: 01050733 add a4,a0,a6 + cc: 00070813 mv a6,a4 + d0: fef42023 sw a5,-32(s0) + d4: ff042223 sw a6,-28(s0) + d8: c00027f3 rdcycle a5 + dc: fcf42c23 sw a5,-40(s0) + e0: fd842783 lw a5,-40(s0) + e4: fcf42823 sw a5,-48(s0) + e8: fc042a23 sw zero,-44(s0) + ec: c80027f3 rdcycleh a5 + f0: fcf42623 sw a5,-52(s0) + f4: fcc42783 lw a5,-52(s0) + f8: 00078f13 mv t5,a5 + fc: 00000f93 li t6,0 + 100: 000f1393 slli t2,t5,0x0 + 104: 00000313 li t1,0 + 108: fd042683 lw a3,-48(s0) + 10c: fd442703 lw a4,-44(s0) + 110: 006687b3 add a5,a3,t1 + 114: 00078513 mv a0,a5 + 118: 00d53533 sltu a0,a0,a3 + 11c: 00770833 add a6,a4,t2 + 120: 01050733 add a4,a0,a6 + 124: 00070813 mv a6,a4 + 128: fcf42823 sw a5,-48(s0) + 12c: fd042a23 sw a6,-44(s0) + 130: fbc42703 lw a4,-68(s0) + 134: 0000c7b7 lui a5,0xc + 138: 35078793 addi a5,a5,848 # c350 <__stack_size+0xbf50> + 13c: 02f707b3 mul a5,a4,a5 + 140: 00078593 mv a1,a5 + 144: 00000613 li a2,0 + 148: fe042683 lw a3,-32(s0) + 14c: fe442703 lw a4,-28(s0) + 150: 00d587b3 add a5,a1,a3 + 154: 00078513 mv a0,a5 + 158: 00b53533 sltu a0,a0,a1 + 15c: 00e60833 add a6,a2,a4 + 160: 01050733 add a4,a0,a6 + 164: 00070813 mv a6,a4 + 168: fd442703 lw a4,-44(s0) + 16c: 00080693 mv a3,a6 + 170: f6d764e3 bltu a4,a3,d8 + 174: fd442703 lw a4,-44(s0) + 178: 00080693 mv a3,a6 + 17c: 00d71663 bne a4,a3,188 + 180: fd042703 lw a4,-48(s0) + 184: f4f76ae3 bltu a4,a5,d8 + 188: 00000013 nop + 18c: 04c12403 lw s0,76(sp) + 190: 05010113 addi sp,sp,80 + 194: 00008067 ret + +00000198
: + 198: ff010113 addi sp,sp,-16 + 19c: 00112623 sw ra,12(sp) + 1a0: 00812423 sw s0,8(sp) + 1a4: 01010413 addi s0,sp,16 + 1a8: 400007b7 lui a5,0x40000 + 1ac: 00478793 addi a5,a5,4 # 40000004 <__global_pointer$+0x2ffff804> + 1b0: 0007a703 lw a4,0(a5) + 1b4: 400007b7 lui a5,0x40000 + 1b8: 00478793 addi a5,a5,4 # 40000004 <__global_pointer$+0x2ffff804> + 1bc: 00174713 xori a4,a4,1 + 1c0: 00e7a023 sw a4,0(a5) + 1c4: 1f400513 li a0,500 + 1c8: ea9ff0ef jal ra,70 + 1cc: fddff06f j 1a8 + +Disassembly of section .stack: + +10000400 <_sp-0x400>: + ... + +Disassembly of section .comment: + +00000000 <.comment>: + 0: 3a434347 fmsub.d ft6,ft6,ft4,ft7,rmm + 4: 2820 fld fs0,80(s0) + 6: 20554e47 fmsub.s ft8,fa0,ft5,ft4,rmm + a: 434d li t1,19 + c: 2055 jal b0 + e: 6345 lui t1,0x11 + 10: 696c flw fa1,84(a0) + 12: 7370 flw fa2,100(a4) + 14: 2065 jal bc + 16: 4952 lw s2,20(sp) + 18: 562d4353 0x562d4353 + 1c: 4520 lw s0,72(a0) + 1e: 626d lui tp,0x1b + 20: 6465 lui s0,0x19 + 22: 6564 flw fs1,76(a0) + 24: 2064 fld fs1,192(s0) + 26: 2c434347 0x2c434347 + 2a: 3620 fld fs0,104(a2) + 2c: 2d34 fld fa3,88(a0) + 2e: 6962 flw fs2,24(sp) + 30: 2974 fld fa3,208(a0) + 32: 3820 fld fs0,112(s0) + 34: 322e fld ft4,232(sp) + 36: 302e fld ft0,232(sp) + ... diff --git a/tests/example/gpio/link.ld b/tests/example/gpio/link.ld new file mode 100644 index 0000000..22f9450 --- /dev/null +++ b/tests/example/gpio/link.ld @@ -0,0 +1,147 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + + +MEMORY +{ + flash (wxa!ri) : ORIGIN = 0x00000000, LENGTH = 4K + ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 2K +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .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 = . ); + } >ram AT>ram + +} diff --git a/tests/example/gpio/main.c b/tests/example/gpio/main.c new file mode 100644 index 0000000..9c706d9 --- /dev/null +++ b/tests/example/gpio/main.c @@ -0,0 +1,43 @@ +#include + + +// GPIO regs +#define GPIO_BASE (0x40000000) +#define GPIO_DATA (GPIO_BASE + (0x04)) + + +#define GPIO_REG(addr) (*((volatile uint32_t *)addr)) + + +#define MS(ms) (ms * 50000) + + +#define read_csr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + + + +static void delay_ms(uint32_t ms) +{ + uint64_t tmp; + uint64_t cycle; + + tmp = read_csr(cycle); + tmp += (uint64_t)(read_csr(cycleh)) << 32; + + do { + cycle = read_csr(cycle); + cycle += (uint64_t)(read_csr(cycleh)) << 32; + } while (cycle < tmp + MS(ms)); +} + + + +int main() +{ + while (1) { + GPIO_REG(GPIO_DATA) ^= 0x1; + delay_ms(500); + } +} diff --git a/tests/example/gpio/start.S b/tests/example/gpio/start.S new file mode 100644 index 0000000..87074dd --- /dev/null +++ b/tests/example/gpio/start.S @@ -0,0 +1,46 @@ + .section .init; + .globl _start; + .type _start,@function + + +_start: + j _reset_handler + +_reset_handler: +.option push +.option norelax + la gp, __global_pointer$ +.option pop + la sp, _sp + li x26, 0x00 + li x27, 0x00 + + /* 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: + + call main + + li x26, 0x01 + +loop: + j loop