torstai 26. maaliskuuta 2015

Const vs non-const data

I've been working on STM32F4's USB now (while not otherwise occupied, so very slowly). The easiest way I figured out (considering my vast lack of deep knowledge of USB details) was to take standard peripheral driver provided by ST and adapt it for my use. So far I got it to compile but it doesn't work yet -- board isn't properly identified by Windows. So maybe later I got something there, but for now something different.

During the process I found numerous definitions in USB driver files in type of

USBD_CDC_INT_cb_TypeDef USBD_DCD_INT_cb =
  { USBD_DataOutStage,
    USBD_DataInStage,
    USBD_SetupStage, 
    ...
}

So what's wrong here? Well, strictly speaking nothing, it works fine (usually, but not in my case, but that is another thing, related to me using non-standard init code). However since these structs are typically not intended to be modified run-time they should be defined const.

So what it the difference?

If you define data non-const (like above), you strongly imply that you have intention to alter it during program execution. This of course means that the data must reside in RAM. And since this is embedded device, this means that compiler must store initial data somewhere (usually along program data in flash), allocate space for modifiable data in RAM and during program initialization copy the data from flash to RAM so it will be available when program starts. So effectively this wastes both RAM and execution time. Granted, not much, but when dealing with limited resources like so often in embedded devices it all counts. Especially when you have multiple this kind of structures in your program.

So when defining data in your program, make it const unless you absolutely intent to change it. Then linker can place the data in flash where it can be read just fine.

But wait, there is more.

Ever done a function with non-const data? (ignore buffer overflow possibility here, this is simplified example)

void sin(int angle)
{
  char sinvals[256] = { ... };
  ...
}


Since the data isn't const, it must be allocated in stack and initialized every single time the function is ran. When data is small there isn't that much overhead, but with large data it starts to get significant. And even more so in this kind of case where the function itself (typically) isn't much more than simple look-up.


Ei kommentteja:

Lähetä kommentti