Bootloader 2 images, shared section of code

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Bootloader 2 images, shared section of code

1,668 次查看
francois_boucha
Contributor III

Hi there,

 

To save some FLASH space we are looking for a way to have both images that could share a common section of code.  As an example, we would like having the libraries located at only one place in the FLASH.  Both images would then refer to that section for code.  The goal is not to duplicate too much of the same code in the 2 images.

 

Other part of the program could be shared as well, like the tcp/ip stack we're using (lwIP, etc.

 

Our platform is the mcf52259, no OS.  CW 7.1.1

 

Any hints?

 

FB

标签 (1)
0 项奖励
回复
3 回复数

937 次查看
mjbcswitzerland
Specialist V

Hi FB

 

The uTasker project supports the following:

- a boot project containing all library resources (OS, TCP/IP stack and other things that can be shared)

- multiple application images sharing the library routines (via a dynamic jump table)

- application firmware updates controlled by the boot project

- ability to update also the boot project (eg. when new library calls are added) using a 2k (4k for Kirin3 since it has a larger FLASH granularity) boot loader

 

As mentioned above, this is based on a jump table. The boot project enters its function calls in a table in RAM which can then be used as trampoline calls by any application rather than them needing to known where the code is and associated linker complications.

 

The actual use is very simple since the trampoline operation is invisible to the programmer as it is controlled by a header file used exclusively by the application projects which causes all relevant routines to be re-defined to their trampoline variation, causing the jump to take place via an intermediate address in SRAM.

 

The configuration itself is however a bit tricky since the applications needs to by able to interact with the boot program at startup enought to be able to configured the trampoline reources (based on a few FLASH locations which are fixed accordingly in the general project).

 

The uTasker scheduler also controls the operation, allowing an application project to also be dynamically constructed from various tasks; some taken from the boot program and some taken from certain application configurations. In your case, without an OS, your scheduler may need some additional capabilities depending on the actual goal.

 

Unfortunately it is not possible to give a short guide as how to actually program this (there are various possible detailed solutions) since it can get quite involved but you may get some ideas from the general description above.

 

Regards

 

Mark

 

 

www.uTasker.com
- OS, TCP/IP stack, USB, device drivers and simulator for M521X, M521XX, M5221X, M5222X, M5223X, M5225X. One package does them all - "Embedding it better..."

 

0 项奖励
回复

937 次查看
bkatt
Contributor IV

I'm curious as to what sort of C declaration you use to get the compiler to call a function through an indirect or "trampoline" address?

 

Also, there are a large number of unused vectors at the end of the vector table. Does it seem reasonable to re-use that space for the indirect function calls? 

 

0 项奖励
回复

937 次查看
mjbcswitzerland
Specialist V

Hi

 

Here's the basic 'trick' used.

 

1) Assume a common function (will be used by the boot program and applications). For example
extern void uEnable_Interrupt(void); Both boot program and applications use the same code:

    uEnable_Interrupt();       // enable interrupts


2) The applications (not the boot program) use a header which diverts this through a call from a location in SRAM. It does this as follows:
#define uEnable_Interrupt      _uEnable_Interrupt

 

extern void (*uEnable_Interrupt)(void)                                               JUMP_ENTRY_TERMINATOR;

 

There is an entry in the header file for all shared functions available.

 

This means that the application code doesn't actually call the routine uEnable_Interrupt() but _uEnable_Interrupt(), where this is a variable in SRAM, resulting in effectively the same thing (a call to the location in FLASH but via a pointer to it in SRAM).

 

There is a further trick allowing the single header to be used since somewhere the variable has to be actually created.

 

This is 

#ifdef _JUMP_LIST_OWNER
    #define JUMP_ENTRY_TERMINATOR  = 0
#else
    #define JUMP_ENTRY_TERMINATOR
#endif

 

Only one file in the project has the local define  _JUMP_LIST_OWNER before its header include and so the variable (initialised to 0) is created only in this one single file and all others see it as a globally defined variable which they can use to call shared routines with.

 

3) The only thing missing is for the variable to be initialised with the location of the real routines in the boot program. This has to be coordinated by (for example) the application being able to find a list of them (eg. at a defined location in FLASH) and copying them to its own list in SRAM.

 

Of course these variables could be (somehow) positioned to use spare vector locations if RAM is very tight. In the example they are  simple variables (which could be forced to be at any location). But the same is true for any system variable I suppose...

 

Regards

 

Mark

 

 

 

0 项奖励
回复