Alternative dso firmware [Application Software Design Entry]

As a quick fix, you could divide the program into two .HEX files.



Basically to do that:


  1. Cut the file in half at any line which begins with :02000004 (set address). Cut & paste this line and the rest of the file to a new file.
  2. At the end of the first file, add the line :00000001FF (end of file)

Hi gabonator,



would your firmware run on the hardware version HW2.7 as well or just on HW2.6?



Kind regards,



Axel

Dear Gabonator,



My DFU V3_10_D : Is fully empty even looking at hiden files.



I’ve cut the file before each start adress beginning with :02000004 . adding end mark :00000001FF (end of file) at the end of each file.



I’ve got the RDY file back each time I published the HEX into the HDD of the DSO Quad.



Strangelly, at reboot, I always have my past application at Slot 1, as if your muliple HEX files were not writen.



Any idea?

Do you reboot in transfer mode the DSO between two files written to the DSO? Or do you add them one after one without rebooting?



Thx for help,

Sincerely,

Hervé

galmiche, try downloading older revision of the HEX file. In the github, go to Bin folder and click on history button, there you can select any older revision and browse its repository. For example, select “browse code” for Jan 27, 2013 and then download HEX file from this version. The older revision, the smaller hex :slight_smile:

Hi, I’d really like to try the app but each time I flash it the DSO comes back with .err file. I attempted older hex files that were slightly smaller (433k or so) with the same results. I have no issues loading the latest community edition though. Am I missing something? :?

I reinstalled the latest community edition files as well as FPGA firmware and now I was able to install gabonator’s app.



I’ve got to say I most definately looked like this :smiley: after I run through the GUI. It is very well though out and very responsive. Even the candy look is there! :mrgreen:



That is some pretty high quality work.

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)