quick boot to other module

It seems that many users install gabonators fw into APP1 slot and jpa’s logic analyser and pawn into slots APP3&4. It would be a nice if it was possible to swap between these applications without needing to switch the device off/on.

I suggest following: Every DSO application should have some header for identifying whether something is installed in certain application slot. For example, we could place something like “DSO_APP: Gabonators alternative UI;Alter UI;Gabriel Valky 2013” right after the isr_vectors section. I put there three labes separated by semicolon. First part is full application name, second is short variant less than 10 characters long (for menus where there is only small space for displaying app name) and third is information about author.

The isr_vectors is always the same size and the application which want to swap between app slots could easily scan the memory for installed application (by checking if the ‘DSO_APP’ string is present at specific memory location) and then display their names.

And my question is - how to set the program counter to execute code of other slot, while resetting the stack to provide maximum possible RAM for the application being executed?

changes in code:

__attribute__ ((section(".identify")))
__attribute__((__used__))
const static char strIdentification[] = "DSO_APP: Gabonators alternative UI;Alter UI;Gabriel Valky 2013";

changes in linker script:

    .rom : {
	    . = ALIGN(4);
      _vectors = .;
      *(.isr_vectors)      /* Vector table */
      *(.identify)
............
............
............
    } >ROM

How do you suggest that the switching would be done? I’m running out of buttons as it is.

This is how the BIOS does it:
github.com/neilstockbridge/dsoq … ain.c#L109

in my app there is application selection screen:

By selecting “Frequency response” I would like to locate which slot contains this application and then execute it. In your PAWN app I saw nice screen with icons for each pawn program. You could scan the memory to find out whether there are any other applications and if any, create an icon for each of them.

by this simple code I was able to find the indentification in ROM:

void* BIOS::SYS::IdentifyApplication( int nCode )
{
	u32 dwGotoAddr = 0;

	switch ( nCode )
	{
		case BIOS::SYS::EApp1: dwGotoAddr = APP1_BASE; break;
		case BIOS::SYS::EApp2: dwGotoAddr = APP2_BASE; break;
		case BIOS::SYS::EApp3: dwGotoAddr = APP3_BASE; break;
		case BIOS::SYS::EApp4: dwGotoAddr = APP4_BASE; break;
		case BIOS::SYS::ESys: dwGotoAddr = SYS_BASE; break;
		case BIOS::SYS::EDfu: dwGotoAddr = DFU_BASE; break;
	}
	ui32* pData = (ui32*)dwGotoAddr;
	for (int i=0; i<200; i++, pData++)
	{
		if ( *pData == ToDword('D', 'S', 'O', '_') )
			return pData;
	}
	return NULL;
}

Here is the result:

My idea is to see from the disassembled binaries if the APPs reset the stack pointer on start. If they do, a simple jump could be fine (provided every APP rewrites the interrupt vector table accordingly on start too). If they don’t, I think it’ll be necessary to replicate the stack state left from the bootloader…

Remember to also reset all the peripherals (there are reset bits for them).

I much prefer just restarting, it’s less hassle. Better spend the time on more useful features, but that’s just my opinion. I can add the metadata to my applications if wanted, but I won’t spend time creating any menu for switching applications.

jpa, please let me know when your builds with metadata will be available.

in the original DFU, the program flow is controlled with function __set_MSP, I dont have such function in my stm32 library, but I have found something very similar __MSR_MSP. But after calling __MSR_MSP(0x0800C000+4); to reset to the first app, the device freezes. It seems that it will be more complicated, but it would be a nice feature demonstrating the synergy of various applications.

If anyone more experienced will be reading this post, please let us know how to safely restart the device into desired application.

__MRS_MSP:

  MRS r0, MSP
  BX r14
/**
 * @brief  Set the Main Stack Pointer
 *
 * @param  topOfMainStack  Main Stack Pointer
 *
 * Assign the value mainStackPointer to the MSP 
 * (main stack pointer) Cortex processor register
 */
__ASM void __set_MSP(uint32_t mainStackPointer)
{
  msr msp, r0
  bx lr
}

That code sets the stack pointer, and setting the stack pointer to a location in flash probably makes the CPU “throw” an exception (fault interrupt) and go to a particular point of the code like the hard fault handler (see github.com/Seeed-Studio/DSOQuad … nterrupt.c - it’s an endless loop). The only way to know where the CPU has gone to is the JTAG.

I’d try a blind jump to the branch, but it takes an offset and you don’t know where exactly that code will be. Can you place a function in a fixed position in flash with GCC?

Or program start on a software interrupt vector and generating a software interrupt.

– IMPORTANT EDIT –
Looks like there’s an absolute jump instruction in ARM :smiley: just try this:

mov r0, PUTJUMPADDRESSHERE bx r0

I have a couple of other ideas I’d like to discuss. If you wish, you can send me a gtalk address in a PM.

Application signature

I once brought up this topic for the Nano in viewtopic.php?f=22&t=3605 (there is not much activity there though). I suggest for your app signature/header that you use for instance:

  1. A magic marker which is more unique than “DSO_APP”, like some half-random four byte combination.
  2. The version of this header format (so that it can be changed later and the application switcher code can parse different formats.)
  3. The address of the next free page after this application. At some point you might want to break free from this “slot” restriction and pack applications more tightly. Then the scanning can be more efficient and avoid false positives if it can jump ahead to next possible location.
  4. Zero-terminated string for application name. Come up with a reasonable limit (16?) for how many characters must be displayed in a application switcher, with longer titles shown at best effort (imagine horizontally scrolling text etc).

Instead of (4) you could have:
4. Pointer to short name string
5. Pointer to full name string

[To save space, (2) could be the fourth byte in (1), or in (3) since the page start will always have LSB zero. (1) and (3) should be word-aligned to optimize the scan, I believe. But it is most important to fix where (2) should be and make it independent from the rest (like 3) which you might want to change one day, rather than optimizing 3 bytes.]

Executing a new application

For executing the new application, doing it fresh from a software-triggered reset is the way to go. Then you will have no hassle with peripheral states etc. Put a magic marker and the start address in a fixed position in RAM before the reset and check for this in the early bootloader code. I implemented this in my extended bootloader: gitorious.org/dsonano/dso-bootl … r.c#line42

To demonstrate this I also made a very simple application switcher that scans through the flash: gitorious.org/dsonano/dso-bootl … .c#line107

App selection app

The application switcher can be a free-standing application like any other. So a lazy application writer just has to include the signature header and a menu entry which sets the magic and resets the unit into the application switcher. For this you will have to agree on what address should be set with the magic - a fixed address where the application switcher should always reside, or more indirectly, a flag that tells the bootloader to start whatever is the default application switcher.

Or you make it so the bootloader always runs the application switcher, which in turn should allow the user to define the default “real” application. With the current bootloader that would mean putting the app switcher in “slot 1”, but you certainly don’t want to waste a whole slot on it, so you should make a hook for it in the bootloader.

Tormod

Finally a soft reboot is working! Now it is possible to run applications in slots 2,3,4 directly from main menu, unfortunatelly there is no way how to go back to my fw… Big thanks goes to JackTheVendicator for these three lines of code:

        u32 *vector_table = (u32 *) 0x08024000;
        __MSR_MSP(vector_table[0]);
        ((void (*)(void)) vector_table[1])();

Regarding the application signature, here is a excerpt from email I was sending to Jack:

As I said in the email, that code is not mine, it’s tormod’s :slight_smile:
Anyway, I’m still considering if it’s a good idea to add some code to reset peripherals before jumping to another APP.

Did you read my comments above on executing the new application? (I have now added section headers to that post - I realize people don’t read through such a long post :stuck_out_tongue: )

Sorry guys :slight_smile:

Yes Tormod, I was. Buit I decided to work on other stuff and then suddenly Jack sent me few emails with the exact code :slight_smile: I was very curious and gave it a try and it worked, so I was very happy and wanted to share this success :slight_smile:
As next step I would like to make a PAWN application that does the same (resets to APP1), but unfortunatelly JPA does not have API functions for this purpose…

I have an idea… Instead of having 4 application slots and using DFU for loading them into flash, I was thinking about applications that would be stored on the EEPROM (2MB disk). All these application would be ELF files compiled to occupy ROM area corresponding to slots 2…4 (large projects cannot fit into single slot) with entry point on slot2.
The main application would have something like file manager, where you can list all applications and execute any of them. File manager would act as a DFU and after selecting some application, it would read the ELF file and burn it into flash. The documentation of STM32 processor says, the flash should survive more than 10000 overwrites. Before burning the image it can check whether the image is not already there to prevent useless overwrites. 2MB is not a lot of space, but I think the internal storage could handle about 20 applications including some user data. To save space I decided to use binary ELF file instead of HEX. For example - my firmware hex file is 471000 bytes long, stripped ELF takes 277000 bytes, more stripped ELF takes 167817 bytes, but keep in mind that this firmware is quite complex. Normal application will be about 30kB.

Other benefits: we can support also HEX files, so any applications that were already made for DSO could be loaded without any problem (except the images compiled to occupy first slot), burning new images without restarting the DSO - you just copy new file on disk and DSO would ask the user whether he wants to execute it. The user do not need to know that there is any DFU utility

Prerequisites: findfirst/findnext listing functions - JPA already ported some more reliable FAT functions, so directory listing functionality should be already there, DFU source code - I am looking for the DFU code to see how does the HEX file is being burnt onto flash… Can anybody help?

Why not just .bin? It’s much easier to parse than .elf (actually no need to parse at all, just write it to some hardcoded address).

It is.

Another way to do this all would be to reserve some area in the extra flash for “loadable applications”. That way it wouldn’t conflict with any old apps, and also if you run out of write cycles it doesn’t matter that much because it’s only the extra flash anyway.

I like this idea much more than the basic “switch quickly between apps”, which is a bit useless IMO. I think alterbios could be a good place for code like this. I’m already planning to add FPGA loading functions to alterbios, so this would be similar:

bool load_app(const char *filename, void *address);
void start_app(void *address);

(But I’m not planning to spend much time on DSO Quad in the near future, so this is just random babble.)

Bin has not any information where to load it, it is just an image of whole ROM. Second problem is that it contains large segments filled with zeros, without compression they are unreasonably big and you can’t identify unused parts which do not require to flash.

ELF format defines which part of elf file should be loaded into ROM/RAM at specific address. Actually it is very simple to parse it, it has its own header defining how many program headers and section headers continue after the main header. Program header defines the memory address where a block of data should be loaded with offset and size of the data block inside the elf file. Section header is something we do not care about, I made a utility that removes all the section headers and all unreferenced data from ELF file to make is small as possible. By this stripping approach I was able to reduce the size from 379kb (277kB after gcc-strip that removes all debug informations) to 167kB (in the stripped file there were still large zeroed parts and some compiler extra informations + section names).

Here is a read-elf report:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x804c000
  Start of program headers:          52 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x5000002, has entry point, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         3
  Size of section headers:           40 (bytes)
  Number of section headers:         0
  Section header string table index: 11 <corrupt: out of range>

There are no sections in this file.

There are no sections in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000094 0x0800c000 0x0800c000 0x00171 0x00171 R   0x8000
  LOAD           0x000205 0x0804c000 0x0804c000 0x28ae8 0x28ae8 RWE 0x8000
  LOAD           0x028ced 0x20003000 0x08074ae8 0x0029c 0x083e8 RW  0x8000

There is no dynamic section in this file.

There are no relocations in this file.

No version information found in this file.

I understand you, that was pretty nasty from seeedstudio to close the competition in this way. Actually I don’t fully understand whether the competition is over or the remaining prices are waiting for assignment…

From what I saw on the blog, there was only the gold prize that was announced; the others are for a ‘next time’. I am surprised that there were no entries from their side to even lay claim to the other prizes. That indirectly means they might want the rights to the gabo IP.

I did not like the way Seeed has handled this contest. Gabonator1, congrats on the win. I enjoy your UI design and I hope you continue to develop it. Hopefully Seeed does not claim it as theirs.

JPA, I enjoy your work a great deal as well. Please don’t stop development because of this. I am still planning write capacitance and inductance meters in pawn.

I have only found the DS201 (dso mini) DFU utility code. It is the last RAR archive on this page (DS0201_OpenSource.rar) code.google.com/p/dsonano/downloads/list, I would like to know the reason why the quad’s DFU utility source code is not published yet.