Alternative dso firmware [Application Software Design Entry]

I can confirm that this works in hw2.7, but the uploading of the hex file from git is currently problematic. I deleted the html headers and footers but the file was still secretly a txt file and not a hex.



No matter what I did, win7 would add a secret .txt after the .hex so even though you see APP_G251.hex, it is actually APP_G251.hex.txt. This causes an error when uploading the file. The error will be, “Item not found, the item is no longer in computer” which seems to be caused by the dso203 rejecting the txt file.



My workaround solution to this was to download the whole zipped repository from git hub and then upload the .hex file from the bin directory into the drive named DFU V3_11_C on the DSO203. Note that the hw2.7 drive name has changed but that it doesn’t matter.



Upload was successful and now that I’ve contributed my little bit I’m off to play with my new toy. Thanks all. We’re standing on the shoulders of giants.

If you like to experiment, try latest version. In the user modules there is a file browser that can flash HEX files, FPGA images and ELF files (only experimental) directly without restarting into DFU mode. When flashing any image keep in mind that it must be built for slot 2, 3, or 4. Slot 1 is used by my firmware. I tested it with the tetris, jpa’s logic analyser & pawn, and it seems working pretty well.

Well, I followed the instructions with a Win7 system and 2.70 hardware and it bricked the scope. Every time I try to copy the hex file over it fails (which the github page says I should ignore) and it boots the scope to a black screen. Ideas?



ETA: I should add I am looking for ideas on how to make this work or if anyone had any experience like this. I can reflash the unit I suppose (I hope…) but if there is something I can do short of that, I would be appreciative. One thing that may be of interest is the time it took to copy the file. I have only USB 2.0 on this windows 7 machine. Would a faster copy get the file over there properly?

PS: This is what I did.

A little update. I am back to 1.07. It’s something with the copy of that file that is causing the issue it appears. After one of those copy attempts, there was an RDY file so that may be the source of the “bricking”, however temporary that was. It must have tried to process a partial file. I am going to find a more modern PC (mac and linux user here, yeah, I admit it :? ) and try this again. It will be monday. I wonder if the USB speed is the culprit.

Thank you so much for this app!!! Please keep the updates going. So much easier to use than stock. The spectral tool is incredible!!

Hello,

now that’s me who is looking for help :slight_smile:



I am working on a ELF loader, including relocations = matching the imported functions to real function addresses. But I am stuck on a very stupid problem. For keeping things simple, I have made an ELF file that should be loaded into RAM instead of ROM. I realized I cannot safely load even most simple code. For example I have this program

</s><i> </i>int main() { return 123; } <e>
loaded at 0x20004000, IDA disassembing looks like this:
</s><i> </i>.text:20004000 ; Processor : ARM .text:20004000 ; Target assembler: Generic assembler for ARM .text:20004000 ; Byte sex : Little endian .text:20004000 .text:20004000 ; .text:20004000 .text:20004000 ; Segment type: Pure code .text:20004000 AREA .text, CODE, ALIGN=1 .text:20004000 ; ORG 0x20004000 .text:20004000 CODE16 .text:20004000 MOVS R0, #0x7B .text:20004002 BX LR .text:20004002 ; .text ends .text:20004002 .text:20004002 END <e>
HEX view

20004000: 7B 20 70 47



When I write these four bytes to RAM and jump to 0x20004000, the device freezes



Here is a minimalistic code to reproduce this issue:

[code]
#define TCALL

int TCALL test(void)
{
return 123;
}

void CWndUserManager::ElfExecute( char* strName )
{
typedef int (TCALL *TMain)(void);
ui16 arrCode[] = {0x7B20, 0x7047, 0x7047, 0x7047};

ui16* pEntry = (ui16*)&test;
BIOS::DBG::Print("%08x = %04x %04x %04x %04x\n",
	pEntry, pEntry[0], pEntry[1], pEntry[2], pEntry[3]);
int nRet = ((TMain) pEntry)();
BIOS::DBG::Print("1/2 Return code=%d\n", nRet);

pEntry = arrCode;
BIOS::DBG::Print("%08x = %04x %04x %04x %04x\n",
	pEntry, pEntry[0], pEntry[1], pEntry[2], pEntry[3]);

nRet = ((TMain) pEntry)();
BIOS::DBG::Print("2/2 Return code=%d\n", nRet);

}
[/code]

This code dumps the code of the test() function:

08064875 = 7020 7047 7047 7047

and then it calls the function:

1/2 Return code=123



And then it dumps the synthesized function:

2000fee0 = 7b20 7047 7047 7047

and freezes…



The strange thing is, that the memory at function “test()” is 7020, 7047 instead of 7b20, 7047

When I try to copy the function test() into 32 bytes long buffer, and then call this buffer, the device freezes anyway.



I tried even flashing these four bytes into ROM, but no success. Loading the code into RAM has been done already by this guy (<LINK_TEXT text=“https://github.com/neilstockbridge/dsoq … ART-loader”>https://github.com/neilstockbridge/dsoquad-demo/tree/master/USART-loader</LINK_TEXT>).

Maybe the CPU does not know whether the code is thumb or not and interprets the instructions incorrectly.


Maybe you should post such questions in a separate thread to get better coverage…


The CPU uses the LSB of the target address to know if it should switch to ARM or Thumb. 08064875 (odd address) is Thumb and will work. 2000fee0 (even address) is ARM and will cause a hard fault on Cortex.



You have to tell the compiler that pEntry() is a pointer to a (thumb) function. Not sure what your TMain type is.


If you are calling the buffer at an even address, it will freeze. But why it shows “70” instead of “7B” I am not sure. There might be some alignment issues here. Compiled code will be aligned on a 32-bit word boundary, with the address table entry of address+1. When you look up a 16-bit word at this (mis-aligned) address, it might not be so obvious what you see. My guess is that the “70” is from the following BX LR “47 70” opcode.



I find it confusing to dump the code in 16-bit chunks, and would prefer byte or 32-bit word dumps, knowing that the 4 bytes will be “backwards” due to LSB architecture. Try changing your debug dump prints to bytes instead.


Yes, tell the compiler and it will tweak the address LSB correctly.



EDIT: For these kinds of issues, stepping through the code with qemu is priceless:

http://www.seeedstudio.com/wiki/DSO_Nano/Qemu_gdb



EDIT2: I saw your TMain typedef now. The problem is that typecasting pEntry does not change the LSB. Try patching it manually with | 1.

Oh my god!! Thank you very much Tormod, this explains many things that were unclear for me.

Now I am facing another problem, I am trying to match imported ELF functions with real addresses. This document shows how does this resolving works (The Procedure Linkage Table paragraph) there is a picture showing the code flow when an imported function is called.



<LINK_TEXT text=“http://eli.thegreenplace.net/2011/11/03 … libraries/”>http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/</LINK_TEXT>







The import process is called “lazy binding” and works like this: the function call “func@plc” refers to a function stub in PLT section. When this function is called for the first time, the GOT[n] is uninitialized and points to next instruction in PLT section, this calls resolver that will update the GOT[n] address to real function address. Next time when the cpu will jump to address specified at GOT[n], it will jump to the real function instead of resolver routine.



For me it seems, that the resolver just updates the entry in GOT table, so during loading of the ELF image, I walk through all the imported entries and write a real function address to GOT table for each function:



<LINK_TEXT text=“https://github.com/gabonator/DS203/blob … te.cpp#L82”>https://github.com/gabonator/DS203/blob/master/Source/User/Execute.cpp#L82</LINK_TEXT>



when I load the ELF file it shows this:

Relocation 20000e84 <- 0804c277 ‘GetKeys’

Relocation 20000e88 <- 0804d683 ‘Print’

Relocation 20000e8c <- 0804d6c7 ‘Printf’



this means, that the GOT entry at address 2000e81 will be rewritten by the address 0804c277 pointing to real ‘GetKeys’ function, and so on… But for some reason the device freezes after calling of any imported function… :frowning:



Here is the assembly listing:

http://pub.valky.eu/elf_reloc1.html



could anyone explain to me this two lines of code (it is the actual PLT stub for GetKeys function)?

</s><i> </i>.plt:20000DC0 GetKeys .plt:20000DC0 ADRL R12, 0x20000DC8 .plt:20000DC8 LDR PC, [R12,#(GetKeys_ptr - 0x20000DC8)]! ; __imp_GetKeys .plt:20000DC8 ; End of function GetKeys <e>

and here is a readelf report of that file:

http://pub.valky.eu/elf_reloc1.txt

Little update - I borrowed the hardfault reporting functions from JPA

https://svn.kapsi.fi/jpa/dsoquad/pawn/debug.c



and it shows following:

SP: 2000fc68

PC: 20000b42

LR: 08005b9b



R0: 00000014, R1: 000000a0, R2:00000000, R3: 0000ffff, R4: 20000c9c…



When I look at the disassembly at PC, it is this:
</s><i> </i>.text:20000B12 BL MyPrint .text:20000B16 MOVS R3, #0x42 .text:20000B18 STRB.W R3, [SP,#0x15] .text:20000B1C LDR R3, =0x20000E74 .text:20000B1E ADD.W R0, SP, #0x17 .text:20000B22 LDR R1, [R3] .text:20000B24 BL convhex .text:20000B28 MOVS R1, #0x14 .text:20000B2A ADD.W R2, SP, R1 .text:20000B2E MOVS R0, #0xA .text:20000B30 BL MyPrint .text:20000B34 LDR R3, =0x20000CD1 .text:20000B36 MOVS R1, #0xA0 .text:20000B38 STR R3, [SP] .text:20000B3A MOVS R2, #0 .text:20000B3C MOVW R3, #0xFFFF .text:20000B40 MOVS R0, #0x14 .text:20000B42 BLX dword_20000DCC <--- here it crashes .text:20000B46 LDR R3, =0x20000CE6 .text:20000B48 MOVS R1, #0xDC .text:20000B4A STR R3, [SP] <e>

matching code in GCC produced assembly:
</s><i> </i> ldr r1, [r3, #0] bl convhex movs r1, #20 add r2, sp, r1 movs r0, #10 bl MyPrint ldr r3, .L22+12 movs r1, #160 str r3, [sp, #0] movs r2, #0 movw r3, #65535 movs r0, #20 bl Print <---- here ldr r3, .L22+16 movs r1, #220 str r3, [sp, #0] <e>

and source code:
[code]
char test[20] = “ha-…-”;
convhex(test+3, (ui32)&Print);
MyPrint(10, 50, test);

test[1] = 'B';
ui32 dwPrintAddr = *((ui32*)0x20000e74);
convhex(test+3, dwPrintAddr);
MyPrint(10, 20, test);

Print(20, 160, 0x0000, 0xffff, __DATE__ " " __TIME__);

[/code]

and the code at address 20000DCC (at .plt), that was failed to call
</s><i> </i>.plt:20000DCC .plt:20000DCC ; =============== S U B R O U T I N E ======================================= .plt:20000DCC .plt:20000DCC ; Attributes: thunk .plt:20000DCC .plt:20000DCC Print .plt:20000DCC ADRL R12, 0x20000DD4 .plt:20000DD4 LDR PC, [R12,#(Print_ptr - 0x20000DD4)]! ; __imp_Print .plt:20000DD4 ; End of function Print <e>

At first I thought I have loaded the image incorrectly and the bytes at 20000DCC are corrupted, but the JPA’s hardfault handler dumps a memory image (starting at 20000000) and everything seems ok (IDA at background showing ELF file, FAR manager viewing the memory dump in front):

The instruction "blx " is not valid in Thumb mode (i.e. Cortex-M3). Instead only "blx " is allowed.



I bet you are missing -mcpu=cortex-m3 -mthumb in some linker or compiler command line.

this is my build script… the problem will be somewhere else, but thanks for a try
[code]
set CFLAGS=-Wall -Werror -Os -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD -std=c99 -Wno-psabi
set LDFLAGS=-nostartfiles -mcpu=cortex-m3 -mthumb -march=armv7 -mfix-cortex-m3-ldrd -msoft-float

rem Build library
!CC! !CFLAGS! -c -Wall -Werror -fpic …/library.c
!CC! !LDFLAGS! -shared -o libbios.so library.o

rem Build example
!CC! !CFLAGS! -S …/main.c
!CC! !CFLAGS! -c …/main.c
!CC! -T …/APP2main.lds !LDFLAGS! -Wl,-dynamic-linker,gloader.1 -Wl,-emain main.o -o !TFILE!_!APP!.elf -lbios -L.
[/code]

When searing this problem over internet “cortex m3 blx gcc”, I found many forums regarding this problem and the cause for issuing “BLX address” was mixing thumb/non thumb libraries. But in my build script I am calling gcc with the same -m settings, so I really don’t know what is the cause of this problem…



library.c (it contains only empty functions for each export)
[code]
#include “library.h”

#undef IMPORT
#define IMPORT(local, remote, ret, args) ret local args

IMPORT(PutPixel, BIOS::LCD::PutPixel, void, (int a, int b, ui16 c)) {}
IMPORT(Print, BIOS::LCD::Print, int, (int a, int b, ui16 c, ui16 d, const char* e)) {return 0;}
IMPORT(GetKeys, BIOS::key::GetKeys, ui16, ()) {return 0;}
IMPORT(Printf, BIOS::LCD::Printf, int, (int x, int y, unsigned short clrf, unsigned short clrb, const char * format, …) ){return 0;}
[/code]

library.h
[code]
typedef unsigned char u8;
typedef unsigned int ui32;
typedef unsigned int u32;
typedef unsigned short ui16;
typedef unsigned short uc16;
typedef unsigned short u16;

#undef IMPORT
#define IMPORT(local, remote, ret, args) extern ret local args;

IMPORT(PutPixel, BIOS::LCD::PutPixel, void, (int, int, ui16));
IMPORT(Print, BIOS::LCD::Print, int, (int, int, ui16, ui16, const char*));
IMPORT(GetKeys, BIOS::KEY::GetKeys, ui16, ());	
IMPORT(Printf, BIOS::LCD::Printf, int, (int x, int y, unsigned short clrf, unsigned short clrb, const char * format, ...) );

[/code]

main.c
</s><i> </i>#include "library.h" int main(void) { Print(20, 160, 0x0000, 0xffff, "Hello!!!"); return 1; } <e>

objdump of resulting ELF:

[code]
bin\APP_2.elf: file format elf32-littlearm

Disassembly of section .text:

20005000 :
20005000: b507 push {r0, r1, r2, lr}
20005002: 4b05 ldr r3, [pc, #20] ; (20005018 <main+0x18>)
20005004: 2014 movs r0, #20
20005006: 9300 str r3, [sp, #0]
20005008: 21a0 movs r1, #160 ; 0xa0
2000500a: 2200 movs r2, #0
2000500c: f64f 73ff movw r3, #65535 ; 0xffff
20005010: f000 e85c blx 200050cc <_ebss+0x1c>
20005014: 2001 movs r0, #1
20005016: bd0e pop {r1, r2, r3, pc}
20005018: 2000501c .word 0x2000501c
2000501c: 6c6c6548 .word 0x6c6c6548
20005020: 2121216f .word 0x2121216f

Disassembly of section .plt:

200050b8 <.plt>:
200050b8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
200050bc: e59fe004 ldr lr, [pc, #4] ; 200050c8 <_ebss+0x18>
200050c0: e08fe00e add lr, pc, lr
200050c4: e5bef008 ldr pc, [lr, #8]!
200050c8: 00000064 .word 0x00000064
200050cc: e28fc600 add ip, pc, #0, 12
200050d0: e28cca00 add ip, ip, #0, 20
200050d4: e5bcf064 ldr pc, [ip, #100]! ; 0x64
[/code]

I have found this:

<LINK_TEXT text=“http://infocenter.arm.com/help/topic/co … CAIGH.html”>http://infocenter.arm.com/help/topic/com.arm.doc.dui0493e/BABCAIGH.html</LINK_TEXT>



linker switch “–no_blx_thumb_arm” that prevents using BLX… unfortunately no such switch is supported by toolchain I am using.



But I have found this:
</s><i> </i>C:\Programs\Devel\Gcc\arm-2011.03\arm-none-eabi\bin>ld --help | find "blx" --use-blx Enable use of BLX instructions <e>

Explanation:

The `–use-blx’ switch enables the linker to use ARM/Thumb BLX instructions (available on ARMv5t and above) in various situations. Currently it is used to perform calls via the PLT from Thumb code using BLX rather than using BX and a mode-switching stub before each PLT entry. This should lead to such calls executing slightly faster.



it seems that it is enabled by default and no way to turn it off… I tried setting -march-armv3 but it produced the same assembly :frowning:



Update:

I managed to work around the BLX issue, by enabling long calls “-mlong-calls” it will produce this assembly:
[code]
Disassembly of section .text:

20005000 :
20005000: b513 push {r0, r1, r4, lr}
20005002: 4b05 ldr r3, [pc, #20] ; (20005018 <main+0x18>)
20005004: 2014 movs r0, #20
20005006: 9300 str r3, [sp, #0]
20005008: 21a0 movs r1, #160 ; 0xa0
2000500a: 2200 movs r2, #0
2000500c: f64f 73ff movw r3, #65535 ; 0xffff
20005010: 4c02 ldr r4, [pc, #8] ; (2000501c <main+0x1c>)
20005012: 47a0 blx r4
20005014: 2001 movs r0, #1
20005016: bd1c pop {r2, r3, r4, pc}
20005018: 20005020 .word 0x20005020
2000501c: 200050e0 .word 0x200050e0
20005020: 6c6c6548 .word 0x6c6c6548
20005024: 2121216f .word 0x2121216f

Disassembly of section .plt:

200050cc <.plt>:
200050cc: e52de004 push {lr} ; (str lr, [sp, #-4]!)
200050d0: e59fe004 ldr lr, [pc, #4] ; 200050dc <_ebss+0x18>
200050d4: e08fe00e add lr, pc, lr
200050d8: e5bef008 ldr pc, [lr, #8]!
200050dc: 00000064 .word 0x00000064
200050e0: e28fc600 add ip, pc, #0, 12 <---- here
200050e4: e28cca00 add ip, ip, #0, 20
200050e8: e5bcf064 ldr pc, [ip, #100]! ; 0x64
[/code]

Now it hangs at 200050e0. Now I am a little bit confused - does the stm32f108 support ARM 32 bit instructions?

May still be soldered to the DSO miniSD card

Owners board version 2.7 can be happy for them developer made connector. power to make it through the diode 3.3V
[attachment=1]CIMG0255.JPG[/attachment]
2.6 The owners will have to solder the 98 pin (PE1) controller.

Will need 93 pin (PB7) software to translate into a high level, thus disabling the built-in flash, signals MOSI, MSCK, MISO take with integrated flash, and 98 pin (PE1) in selecting a low SD card.

Also implement a normal file system on the card FAT32. example



htt ps://mb ed. org/coo kbook/ SD-C ard-File-Sy ste m <–remove spaces from URL



And in the flash controller to leave only the BIOS, the file system, Explorer to select downloads, and will be all happy. 32 Gb enough for all applications



datasheet dso203v2.7[attachment=0]DS203 V2.7.pdf[/attachment]

There is also an additional 2 free pin (PC0, PC1 on the board R33, R34) which can also be used (for example to check a MicroSD slot)


I don’t understand why you are using the -march=armv7 option. It should be enough to specify -mcpu=cortex-m3 which already defines the architecture. Also. the architecture for the cortex-m3 used in STM32F103 is armv7-m and not armv7. Possibly your conflicting architecture specification fools the toolchain into allowing ARM instructions.


You can see all instructions in the .plt section are 4 bytes wide, a typical sign of ARM instructions and not Thumb. This is the root of your problem: The toolchain has compiled and labelled this code as ARM code and therefore also calls into it with pair addresses (like 0x200050cc, or 0x200050e0 in your other post).

I tried armv7-m but there is no change in PLT… the problem of generating thumb PLT entries by gcc was already discussed 10 years ago:



<LINK_TEXT text=“http://www.sourceware.org/ml/binutils/2 … 00439.html”>http://www.sourceware.org/ml/binutils/2002-07/msg00439.html</LINK_TEXT>



but they did not implement the patch it into bintools, I tried patching it manually, but the current source of elf32-arm.c was heavily changed during that long period, and I am not in a mood to dig into this huge 14000 lines long messy code. Anyway there is already support for custom PLT behavior (for vxworks), and there is some suspicious code with thumb instructions, but I don’t know how to force the gcc to use it (tried armv7-m & fPIC/fpic):



bintools-2.20.1/bfd/elm32-arm.c
</s><i> </i>/* Thumb -> Thumb long branch stub, PIC. Used on M-profile architectures. */ static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] = { THUMB16_INSN(0xb401), /* push {r0} */ THUMB16_INSN(0x4802), /* ldr r0, [pc, #8] */ THUMB16_INSN(0x46fc), /* mov ip, pc */ THUMB16_INSN(0x4484), /* add ip, r0 */ THUMB16_INSN(0xbc01), /* pop {r0} */ THUMB16_INSN(0x4760), /* bx ip */ DATA_WORD(0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */ }; <e>

I followed this tutorial for building arm toolchain on windows pc with msys and mingw:

<LINK_TEXT text=“http://www.microbuilder.eu/Tutorials/So … chain.aspx”>http://www.microbuilder.eu/Tutorials/SoftwareDevelopment/BuildingGCCToolchain.aspx</LINK_TEXT>



here is the function that chooses the right plt stub type:

http://pastebin.com/Ly3BtJwj

the condition for using the previous entry is following: thub_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24) && st_type == STT_ARM_TFUNC



thumb_only is set for ‘M’ type of architectures (armv7-m), so I probably need to set the relocation type in my “library” to R_ARM_THM_CALL instead of R_ARM_JUMP_SLOT… but how to achieve this?

Hi, I received my DSO QUAD , make a update with the correct code.



All is the scope is fine, except the function generator…



When I tell to generate Square Wave, the frequency is correct.

When I change to Triangle, or Sawtooth, ou Sin HQ, the real frequency generated is 4 times greater than the specified.

And When I specified Sin LQ, the real frequency generated is 16 times greater !

I used my desk digital scope to the measures.



My original HW was 2.72, I put first all the files from comunity APP, that works ok, then I use the Gabonator’s code.

My last try today was reflashing the FPGA code, but the result is the same.



And one curiosity, after the Gabonator code, my HW info shows 2.60, and when I go to the ABOUT Menu, in the Device, this is the result :



Hardware Version : 2.60

System version : 1.50 SmTech 1.6

FPGA version : 0.00 :o :o :o <- what the hell !!!

DFU version : 3.10

Display Driver : ILI9327

Serial Number : 7d24a570



What I can do to fix the Function Generator ?



Thanks.

I would like to use the RS232 ability of the Gabonator alternative firmware (which is truly excellent, although development seems to have ceased some while back :frowning: ). I have searched and searched but not been able to find out how the RS323 signal is actually input into the DS203.



On the page https://github.com/gabonator/DS203, the very first screenshot seems to indicate that the RS232 signal is extracted from the input on channel A and a second signal from channel B. The threshold taken as the ‘zero’ marker “1” and “2” respectively.



This is exactly what I want to do… look at the analog waveform on the oscilloscope, and simultaneously decode it and display the string on the screen!



Other pages allude to cutting open the DS203 and connecting to the ‘genuine’ UART (TX & RX pins on CN7) to achieve RS232 comms.



Anyone done something like what I want to do?

If the input is indeed from one of the analog channels, how do I get to it, and is there an ‘invert’ for signals that appear on the ‘inside’ (logic side) of a level converter (eg:MAX232)?

Is there any information out there on the ‘UART’ function that Gabonator has put in his firmware?



Cheers,

Owen.

Hi, I just got my new latest DS203. It is with HW v2.81. But I bricked it while updating the firmware.



Does anyone dumped the DFU v3.04c? So that I can flush my DSO.

Hi



I really like the UI of this firmware but I have the latest 2.81 hardware and it doesn’t work :frowning:

It shows “FPGA configuration err!” and I believe it’s because the memory layout needs to be changed.



Would it be possible for the firmware to be adjusted for newest hardware ?



Thanks :slight_smile: