Closed universal-git closed 2 months ago
Would it be possible to set up a godbolt link that demonstrates the issue?
This seems fine, for example:
Tried here, https://godbolt.org/z/oTTo1GPnG , this looks alright. But, let me share my local one:
whereas, if buff is set to b"Github", output is: 1Github 2Github 3Github 4Github 5Github etc..
Also sharing the output objdump of both the builds. Git__together.txt Github.txt In this asm, but each string length generates different result.
key to look into the asm objdumps: each block before "fence" writes a byte to uart: 200278: 13 05 00 00 li a0, 0 20027c: 83 25 4b 11 lw a1, 276(s6) 200280: 93 f5 05 06 andi a1, a1, 96 200284: e3 8c 05 fe beqz a1, 0x20027c <_main+0x1ac> 200288: b3 85 ad 00 add a1, s11, a0 20028c: 83 c5 05 00 lbu a1, 0(a1) 200290: 23 20 bb 10 sw a1, 256(s6) 200294: 0f 00 f0 0f fence
In the long string case, you can notice that it is not writing all the bytes.
I've done the above with target=riscv32i-unknown-none-elf, +m using "rustc 1.77.2 (25ef9e3d8 2024-04-09)" opt-level=3
Tried with nightly but no different results. -end-
Can you post the source code that reproduces this issue? I feel it's unlikely to be the target, as I think that target gets used by a lot of Espressif chips.
Sure, here pls:
https://github.com/universal-git/riscv_write/tree/main
I tried studying the asm dump further, it loops and tries to load the string data from memory, probably the fetch address fails. study notes:
2002b0: 93 fa 0a 06 andi s5, s5, 0x60 2002b4: e3 9c ea fe bne s5, a4, 0x2002ac <_main+0x294> 2002b8: b3 0a 44 01 add s5, s0, s4 2002bc: 83 ca 0a 00 lbu s5, 0x0(s5) 2002c0: 23 a0 55 11 sw s5, 0x100(a1) 2002c4: 0f 00 f0 0f fence 2002c8: 13 0a 1a 00 addi s4, s4, 0x1 2002cc: 83 aa 45 11 lw s5, 0x114(a1) 2002d0: 13 fb 0a 02 andi s6, s5, 0x20 2002d4: e3 0c 0b fe beqz s6, 0x2002cc <_main+0x2b4> 2002d8: 93 fa fa 0f andi s5, s5, 0xff 2002dc: e3 1a 9a fc bne s4, s1, 0x2002b0 <_main+0x298>
Attaching a copy of the asm obj-dump. reproduceable.txt
Meanwhile, trying possibilities on the linker. -end-
The short strings write because their bytes are written directly from registers, not fetched from data stack. The problem is clearly accessing the data stack. Possible reasons:
It looks to me that you don't copy data from flash to RAM at startup. Is there a reason to not use the riscv-rt
crate? It would handle this for you and fix your linker script too (which I'm surprised works given you don't declare the flash memory region, so maybe it's a different problem).
In another version, I do copy flash to RAM at startup. Tried riscv_rt initially, it didnot work for the board. Moreover, I was into building it from scratch, so made it myself. The program works because it is loaded in UART test mode. After much trials and tests, I realised that the problem is due to SPI flash, which does not load onto RAM with the usual method. Closing this thread as it is not related to the target.
Target: riscv32i-unknown-none-elf, target-feature=+m, no_std Raw strings in the rust code would compile for all lengths but they show garbage values at runtime. Cases:
Strings with small length e.g. len<16 would compile and run fine for below case: let buff = b" Github brings\r\n"; ...,but for the below code, it takes garbage: let buff = b" Github brings us all together\r\n";
push_str: here, the len constraint reduces even more. e.g. num_str.push_str(" Git\r\n"); would compile and run, but, num_str.push_str(" Github.com\r\n"); ...would not.
Is there any known solution?