Is it safe to use the util functions in bootloader section?

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello hArVaRd* freaks,

about static inline function, there are several threads, e.g. topic 67893.

But one question is open for me:
Can I get sure, that a function, which is declared in an header file as "static __inline__" really goes into the section, from where it called (specially into the bootloader section)?
OK, if it is really inlined, then there is no doubt about it, that it is in the correct section: it "inherits" the section from where it is called.

But I read, that "__inline__" is only a proposal to the compiler. It is free to do it another way, if it is not forced with the attribute "always_inline".
What if the compiler decides to put the inline-proposed function as a separate function block? Then the attribute for the section is missing...
I wonder, why there are different declarations:
.../util/delay.h:

static inline void _delay_ms(double __ms) __attribute__((always_inline));

No problem for me, because always inlined.

.../util/crc16.h

static __inline__ uint16_t
_crc_xmodem_update(uint16_t __crc, uint8_t __data)

This function was correctly inlined though the always_inline attribute is not used.

But is this critical, if the compiler one day changes it behavior, about what code to inline and what to call. Then the correct section, where to place the code is missing...

Or am I wrong and the compiler takes automatically care, that it goes to the correct section, also if it is not inlined, because it is "static"?

I noticed in the past that it is really important that the functions called from a bootloader reside also in the same section...

So, should I better copy and paste the utility functions into my C file with the correct section (and the copyright information of the header file)?

skotti

*) my idea, where the name AVR results of

In the beginning was the Word, and the Word was with God, and the Word was God.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you worried about this? Let the compiler worry about where to put the code.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
*) my idea, where the name AVR results of

A great idea in fact!

As for the question, certainly for the current build you can simply look at the generated asm to ensure that the code has been inlined into the .bootloader function but as for a guarantee that it will always compile that way I'm not so sure.

However is this just some SPM support code for an application or is it truly a bootloader you are engineering? If the latter then you don't need to coerce code into named sections but you simply move the base of the entire .text

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Koshchi:
I am worried about this, if during flash-update this function resides not in the bootloader, the flash-update will (probably) fail.
@clawson:
The project is a combination of an application and a bootloader. The bootloader will seldomly change (but now is improved), but the application has already changed some times...
So normally the (old) bootloader will flash a new code in the application section.

skotti

In the beginning was the Word, and the Word was with God, and the Word was God.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The project is a combination of an application and a bootloader
This may need more explaining. If you take the 'normal' route, you simply have 2 applications, 1 a bootloader and 1 an application. When creating the bootloader, you do as Cliff said and just move the .text section up to the address of the bootloader start. All functions will stay inside the bootloader section (because .text stays inside of it), and you don't even have to create a section for your bootloader code. Easy. Simple. Even I can do it.

Now if you really have a 'combination' with both sections in the same 'project', then there will be no guarantee the functions will be in the bootloader section unless the function is specified to be in that section (if for some reason its not inlined like it should, or you pull some function from a library, etc.). Not easy. You have to keep an eye on it.

I'm not sure there is ever a good case for a 'combined project', as the bootloader usually has to be able to function without any app loaded anyway (it really is a separate application). And if you want, the app code can still use functions that are located inside the bootloader.

But maybe you have a good reason, or I'm misunderstanding what you're after.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am one of the heretics that compiles the boot with the app*, but I actually agree with Curt and Cliff that compiling the boot separate from the app is a Good Idea (tm).

I use the CRC16 routines in my boot and can confirm that the routines are inlined, as they are supposed to be, but again I agree with Curt that you are betting that the compiler will never change its mind about that. A bad bet, usually. Okay, maybe this won't change, but you need to keep an eye on it.

Instead, doesn't it make more sense to compile the boot separately, confirm that it works as you expect, then set the compiled version aside so it isn't mucked with when you change compilers? After all, the compiled binary doesn't need to change. Fer cryin' out loud, you could check the .hex file into your source control system so it's never lost!

I agree with Cliff, don't depend on the compiler to get it right. Inspect the resulting code, be sure that it's right, then set it aside.

Stu

* I keep thinking about separating the boot and app compile, but dang it, it works as it is. It just hasn't risen to the level of pain that I'm willing to change what works. This is a case of me being obstinate in face of overwhelming evidence that what I'm doing is stupid. And yes, given what I wrote above, what I'm doing is stupid. :oops:

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm assuming the app uses bootloader facilities.
Otherwise I see no possible need for a combined bootloader+app.
Perhaps someone sees better than I do.
One can link the bootloader separately.
Move the text segment as directed.
When linking the app, use --just-symbols bootloader.elf .
You can combine the hex files or not,
whatever makes you feel good.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your answers and recommendations.

With the expression "combination" I mean, that it is one project folder, which contains code for the application and the bootloader. The Makefile generates two binaries: one binary contains the complete thing (application and bootloader), the other binary contains only the application.

So, when programming the first time, the complete binary is used; if later on an update is needed, the application section will be only transfered. So each function of the bootloader contains the section where it should go. Also I have to take care that no library function is called...

skotti

In the beginning was the Word, and the Word was with God, and the Word was God.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
When linking the app, use --just-symbols bootloader.elf
I never knew something like that could be done, so I just made macros to use functions inside the bootloader-
#define HEX2ASCII(byte) \
( (void(*)(uint8_t h)) &__vectors-8 )(byte)

(function table sits at flashend). I only have a few functions, so its pretty much overkill but I do it just because it can be done. I'll probably keep using my macro method since its simple enough for a few functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Having a fixed position jump table rather than building against a specific set of bootloader symbols is surely a safer option. Otherwise what happens when bootloader moves from V1.0 to V1.1 and now you have to have versions of the app code that either "know" about the V1.0 symbol addresses or the V1.1 symbol addresses? Far better to keep the "dynamic links" in a fixed place (isn't this where "thunks" came from?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Skeeve, me again...
If I understand you correctly, you have two projects; for the bootloader you just increase the start address when compiling. Later you put the compiled bootloader together with your application, when you need it for first-time-progamming.

@Curtvm: yes it's an interesting idea, but this is only for functions possible, which are not called during the flash process itself, I think. And you also depend on that the application section is always all right; if an update fails and the memory is corrupted you may have a problem. Or did I get it wrong?

As a result of your hints / our discussion, I can summarize, that it is more safe to build the bootloader once, test it and leave it, as it is. So, if you update the compiler one day, you do not need to test the bootloader again (maybe optimizing or inlining strategy has changed resulting in larger code and higher performance or vice versa).
You can put the binary bootloader with the application together to one file in a second step.

On the other hand, if you have a working combination of app+bl, you need not necesseraly change it, but keep an eye of the output, especially when you change compiler version or change optimzing parameters.

skotti

In the beginning was the Word, and the Word was with God, and the Word was God.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
And you also depend on that the application section is always all right; if an update fails and the memory is corrupted you may have a problem. Or did I get it wrong?
My bootloader stands on its own, and does not depend on anything else. There are a few functions inside the bootloader that CAN be used from an application if wanted, so unless the bootloader is missing, those functions will be available for any application that wants to use them.

So for example, that hex2ascii function inside the bootloader, is used by the bootloader to do its job and is its primary purpose. The HEX2ASCII macro is used in an application so it also can take advantage of that function inside the bootloader. The application depends on the bootloader always being there (it is), but the bootloader depnds on nothing else.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

to Curtvm:
OK, all right. I thought the other way around. Yes, than a jumping table is a good thing, especially if the bootloader contains different entry points...

In the beginning was the Word, and the Word was with God, and the Word was God.