cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4xx IAP - passing arguments

kubakotlorz
Associate II
Posted on July 12, 2013 at 00:17

Hi,

I'd like to have algorithm executing application (from 0x8004000) operating on data buffered in my modified IAP firmware (2 x (uint16_t [128]) located after IAP code, before 0x8004000).

But after compiling my IAP I don't know where they are located exactly. I can get those addresses via pointer but how to pass them (and int size of them) to my application?

Sounds weird but I'd like to have SOMETHING LIKE main(int *buf1, int *buf2, int size) in my application.

I could make it a function like myFunction(int *buf1, int *buf2, int size)  for 0x8004000 code but I woudn't know how to compile it (as a library?)

I'm using Keil.
9 REPLIES 9
Posted on July 12, 2013 at 02:24

Calling function within a secondary code image has some issues, these revolve mainly around the initialization of statics.

Now if you look at you startup_stm32fxxx.s file, you can certainly pass parameters to the Reset_Handler, four parameters would be held in R0..R3, you challenge however would be to pass those along, but you could create variables in the secondary code that the compiler/linker would know about. With Keil it first calls SystemInit(), which you could have parameters passed too, and then __main. This isn't your main() function, but rather code to clear/copy initialized variables, and later calls main(). You'd need to watch SystemInit() because it's operating before the C runtime is properly started. If your IAP code set the processor clocks and pll as you want, you wouldn't even need to call SystemInit() again.

You could also park a structure in high RAM, say 0x2001FF00, which both your primary and secondary code can agree upon.

Also don't forget the Backup SRAM as a place to pass command line or parameters.

When you build the secondary image, you can control the IROM and IRAM spaces, both the placement and size, and can customize the startup.s.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
kubakotlorz
Associate II
Posted on July 12, 2013 at 08:29

Wow, the first approach really discouraged me. Then you showed me that I considered ROM space for those buffers not correctly!

Sure, those two buffers should be parked in RAM during execution. There must be easy access for both two apps (IAP and DSP algorithm) and saving some fixed space for them (like last 0xFF bytes - 2x128 elements) could work for me. I understand that placing them on the end of RAM would help me avoid overriding local program data but is it another reason?

So I agree on fixed size and fixed start addresses (0x2001 FF00, 0x2001 FF80) for those buffers and I need no passing any arguments right now. Could you help me how declare and use (if it needs other approach) those buffers in both applications in C?

kubakotlorz
Associate II
Posted on July 14, 2013 at 18:29

Could you show me (in C) how can I access from those two applications to specific SRAM area like 0x2001FF00 - 0x2001FFFF? I want place my buffesr there. Can I just use pointers to begin of that memory? How do I prevent compiler to use this space for local  variables so other data won't override those buffers?

Posted on July 14, 2013 at 19:37

You'd want to shrink the IRAM memory allocation in the target dialog, or scatter file, so that it DOES NOT include the space you want to carve out for the parameters. This doesn't stop the memory from being useable indirectly, but does stop the linker from placing data there, and cause it to warn if the RAM requirements exceed the available space.

typedef struct _PARAMETERS {

  unsigned short params[128]; // Space of 256 bytes

} PARAMETERS;

PARAMETERS * Parameters = (PARAMETERS *)0x2001FF00; // Common Address between apps

int main()

{

  int i;

  for(i=0; i<10; i++)

    printf(''%d\n'',Parameters->params[i]);

}

I'd put it at the end because it's significantly less likely to be damaged inadvertently, by things like the debugger's flashing algorithm code/applet, or the user application where someone forgot to shrink the IRAM.

Sorry, pulled the template from some other example
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
kubakotlorz
Associate II
Posted on July 14, 2013 at 20:27

Why it's casted on''(FLASH_DATA *)''? This type isn't defined in my project. How to fix that? Should I include something?

kubakotlorz
Associate II
Posted on July 14, 2013 at 21:05

Thank you now it's compiling.

I found another solution on ARM pages (just one line):

uint32_t Parameters[128] __attribute__((at(0x2001FF00)));

What do you think about that?

Posted on July 14, 2013 at 22:51

That works for one compiler.

A structure allows you to pass some more complex collections of settings and variables, it really depends on what you want to pass back and forward, and how many memory locations you want to keep track of. It permits a pretty clean abstraction.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 14, 2013 at 23:18

0690X00000604ncQAA.png
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
kubakotlorz
Associate II
Posted on July 15, 2013 at 08:31

Now it's clear to me, thank you.

Could you help me consider splitting my functionality into those two apps? I would like my first/boot application to configure all the peripherials (like gpios, i2c, i2s, dma) and my second application just do the calculations.

Problem I noticed is executing DMA interrupts (defined in first app) what don't let me come back to DSP routines defined in second app. (commenting DMA interrupts enabling line really do the trick).

I think I should divide IRAM space into two different spaces what I did like you showed in previous image (ex. 0x 1 8000 for 1st and 0x 0 8000 for 2nd minus shared buffer space so 0x 0 7F00) so both stacks won't interfere. But it didn't help.

Is that the right way to do that? Or should I move all my DMA interrupts and DMA/I2S/SPI peripherials to second app so all the interrupts will be handled here and program will never come back to first app after launching?