Where is function pointer stored? - c

In an embedded environment, for example, I declared a look-up table in following way:
const Operation Vehicle_OpNotification[] =
{
{ OP_SET , &Vehicle_Notification_Set},
{ OP_GET , &Vehicle_Notification_Get}
};
May I know this function pointer is pointing to RAM address or ROM address?

That depends on your compiler and target environment, but most likely it points to ROM—executable code is almost always placed in read-only memory when available. You have to take special steps (like using a custom linker script or allocating dynamic memory and asking the operating system to mark it as writable and executable) to get executable code in non-read-only memory.

The linker should be able to generate a map-file where the location of each variable/constant defined at file-scope is shown. Example:
main.c:
static const int constant = 42;
static int volatile variable = 43;
int main (int argc, const char * argv[]) {
variable = constant;
return 0;
}
Generated map-file: (notice how the constant constant is placed in the same memory segment as the read-only code (TEXT), while the variable variable is placed in the DATA section)
# Sections:
# Address Size Segment Section
0x00001F6C 0x0000008F __TEXT __text
0x00001FFC 0x00000004 __TEXT __literal4
0x00002000 0x00000018 __DATA __data
0x00002018 0x0000001C __DATA __dyld
0x00003000 0x00000008 __IMPORT __pointers
0x00003040 0x00000005 __IMPORT __jump_table
# Symbols:
# Address Size File Name
0x00001F6C 0x00000040 [ 1] start
0x00001FAC 0x00000014 [ 1] dyld_stub_binding_helper
0x00001FC0 0x0000000E [ 1] __dyld_func_lookup
0x00001FCE 0x0000002D [ 2] _main
0x00001FFC 0x00000004 [ 2] _constant
0x00002000 0x00000004 [ 1] ___progname
0x00002004 0x00000004 [ 1] _environ
0x00002008 0x00000004 [ 1] _NXArgv
0x0000200C 0x00000008 [ 1] _NXArgc
0x00002014 0x00000004 [ 2] _variable
0x00002018 0x0000001C [ 1] __dyld#0
0x00003000 0x00000004 [ 2] _variable$non_lazy_ptr
0x00003004 0x00000004 [ 2] _constant$non_lazy_ptr
0x00003040 0x00000005 [ 0] _exit$stub

Its address will be entirely dependent on the location of the function pointed to; the linker will tell you that. Most often application code ie either all in RAM or all in ROM, though for some targets, it may be split for performance reasons if RAM execution is faster as it typically is on processors faster than around 100MHz.
If you need to determine this at runtime (if for example it may be either, and is dynamic), you can simply compare the address with the start and end of the relevant memory sections. These addresses may be emitted as symbols by the linker given an appropriate linker script, or they may be defined constants in a target header file or BSP for example.
All that said, I can think of few reasons you should need to know at run-time (unless you are considering self modifying code!).

This is dependent on architecture.
However, if you have some idea of the address ranges for ROM and RAM, you can check the function pointer to the address.
Or, as Mehrdad says, just try writing to the address, it should be easy to figure out from there.

It all depends on which compiler/processor you use. If I put your definition in Keil Uvision for 8051, surely would point to ROM because of the "CONST" definer although I could modify with XRAM or CODE. But for ARM depends on address and not definer.
Keil Uvision Example:
// For 8051 Keil
const char code romdata[2] = {0,1}; //<< this point to ROM/FLASH
const char xram ramdata[2] = {0,1}; // this point to external RAM
const char romdata[2] = {0,1}; // this point to ROM/FLASH

Related

setting stack pointer before jumping to app from bootloader

I am coding a bootloader for Nucleo-F429ZI. I have two different STM32 projects, one for the bootloader itself and an application to jump from the bootloader.
Linker script for bootloader
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K
}
Linker script for app
_estack = ORIGIN(RAM) + LENGTH(RAM);
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 64K
}
I did not forget to set the flash offset of the app.
system_stm32f4xx.c (in the app project)
#define VECT_TAB_BASE_ADDRESS FLASH_BASE // 0x8000000
#define VECT_TAB_OFFSET 0x00008000U
The tutorial of STMicroelectronics about bootloaders has the following code to jump
main.c (in bootloader project)
#define FLASH_APP_ADDR 0x8008000
typedef void (*pFunction)(void);
uint32_t JumpAddress;
pFunction Jump_To_Application;
void go2APP(void)
{
JumpAddress = *(uint32_t*)(FLASH_APP_ADDR + 4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(uint32_t*)FLASH_APP_ADDR); // in cmsis_gcc.h
Jump_To_Application();
}
cmsis_gcc.h (in bootloader project)
__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
}
As you can see, __set_MSP function sets the main stack pointer before jumping to FLASH_APP_ADDR + 4.
I found the memory location of the target place by debugging. FLASH_APP_ADDR + 4 caused to run Reset_Handler function of app project. Lets see what will be executed.
startup_stm32f429zitx.c (in the app project)
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr sp, =_estack /* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
First thing of what Reset_Handler does is setting the stack pointer. _estack was defined in linker script.
If Reset_Handler is setting stack pointer, why did we call the __set_MSP function? I remove the function __set_MSP and bootloding process is still working. However I examined some other bootloader codes and found the exact same logic.
I tried what i have said and could not find an explanation.
Cortex-M core the loads SP register with initial value from address FLASH_BASE+0 during boot sequence. Then jumps to the code entry point (Reset vector) from address FLASH_BASE+4. Any bootloader code mimics core behaviour. Note, that FLASH_BASE here is not necessarily actual flash base, but an abstract value, that depends on the used processor, and it's settings.
Provided Reset_Handler code loads the sp register with __estack (Main stack top) value, but it doesn't have to! Bootloader can not expect the main program to do it, but has perform the same boot sequence as the core after reset. This way the main code doesn't have to rely on knowing, who started it - core, bootloader, jtag, or something else.
I've seen startup code, that doesn't load SP, but disables interrupts with the first instruction. Or startup code, written in C, which could use stack with the first instruction.
The real question here could be: Why this startup code loads SP if it is already loaded? But perhaps it should be forwarded to the original code author.
Let's see what's happening line by line.
JumpAddress = *(uint32_t*)(FLASH_APP_ADDR + 4);
Okay, so we take FLASH_APP_ADDR, add 1 word to it, call it a pointer to a word, dereference it. So it's the content of 0x8008004 (which is the one word after start of the vector table - list of interrupt handler pointers). You can find it in the vector table in reference manual. Here is reference manual for your MCU. Page 375
Next,
Jump_To_Application = (pFunction) JumpAddress;
Okay, so we treat reset handler address as a void function(void).
Eventually, you get to the stack
__set_MSP(*(uint32_t*)FLASH_APP_ADDR);
This function, as we see from its source code, simply sets main stack pointer to its argument. The argument is take vector table address, treat it as a pointer to a word, dereference it. So it's the first word of that vector table. And the first word of the vector table is the main stack pointer auto-loaded after power on. By definition of the vector table. You reset the stack to cold boot value, same value as the first word of your Flash. Your bootloader has used some stack until this point, but it won't be needed anymore, and the bootloader function will never return and free that stack, so you just reset stack to its initial value for your program. It will reuse all stack used by the bootloader.
So right now you've reset the stack pointer and you assigned reset handler to the function you call. And then you, well, call it.
Your vector table and the program that the bootloader starts are two different entities in memory. If you don't need to remap the interrupt handlers at runtime, don't move the vector table. It will stay at the beginning of the flash and will lead to the default interrupt handlers. Just make sure the address you execute from contains executable code and you run it from the start (well, if you don't, you will hardfault).

Variables randomly changing, extremely odd behavior

I am experiencing extremely bizarre behavior where variables are randomly changing.
I have distilled it to the simplest example, encoder_1_position and encoder_2_position get updated with randomly values inside the NVIC_SetPriority(UART_IRQn,2); function. I have reordered declarations of the global variables in the file and I noticed it makes a difference as to what/if garbage gets added to them. I since disabled "remove unused sections" in the linker command and it seemed to fix the problem(apparently the BSS section was being tossed out) but I don't understand why particularly since every global variable I have is declared with volatile.
Reducing the buffer size from 1000 to 100 seems to correct the random change to the encoder variables, but I'm not confident it's an actual fix nor should it be required. The SAM3X8E has 65kbytes of ram - the stack shouldn't overflow regardless.
#include "sam.h"
#define HEAP_SIZE 0x500
#define STACK_SIZE 0x3500
int encoder_1_position = 0;
int encoder_2_position = 0;
void IntializeWatchdogTimer(void)
{
// disable watchdog timer
WDT->WDT_MR = WDT_MR_WDDIS;
}
void InitializeUart(void)
{
PMC->PMC_PCER0 = PMC_PCER0_PID8;// ID_UART 8
// baud rate is 84Mhz/(16*45) = 116667
UART->UART_BRGR = uint32_t(45);
// set to no parity
UART->UART_MR = UART_MR_PAR_NO;
// Enable transmit and receive
UART->UART_CR = UART_CR_TXEN|UART_CR_RXEN;
// Enable UART control of port A pin 8, 9
PIOA->PIO_PDR = PIO_PER_P8|PIO_PER_P9;
// Enable UART interrupt on RX RDY
UART->UART_IER = UART_IER_RXRDY;
// Set priority
NVIC_SetPriority(UART_IRQn,2);
NVIC_EnableIRQ(UART_IRQn);
}
int main(void)
{
__disable_irq();
IntializeWatchdogTimer();
SystemInit();
InitializeUart();
__enable_irq();
/* Initialize the SAM system */
//char* RX_message;
char TX_message[1000];
while (true)
{
int a = encoder_1_position;
int b = encoder_2_position;
}
}
readelf output:
Elf file type is EXEC (Executable file)
Entry point 0x80000
There are 2 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x010000 0x00080000 0x00080000 0x02a58 0x02a58 R E 0x10000
LOAD 0x020000 0x20000000 0x00082a58 0x001d4 0x00808 RW 0x10000
Section to Segment mapping:
Segment Sections...
00 .text
01 .relocate .bss .stack .heap
I since disabled "remove unused sections" in the linker command and it seemed to fix the problem(apparently the BSS section was being tossed out)
This is just a guess, but that could mean that your program loader is not processing the BSS section correctly. It is supposed to allocate and zero the memory region the linker assigned to the BSS, even if there are no bits to copy from the executable image to that range. (It's a little more complicated than that, but unless you are stuck writing the loader yourself, that should give you enough of an idea.)
but I don't understand why particularly since every global variable I have is declared with volatile.
volatile doesn't do what you think it does. (More detail.)

Is writing to a section not defined in linker file allowed?

In my linker file, I have the following memory sections.
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
mram (rwx) : ORIGIN = 0xA0000010, LENGTH = 1M
}
The actual address of the mram peripheral starts at 0xA0000000. In a C file I can write to a specific memory address as
(*(uint32_t *)(void *)0xA0000000) = 0xaabbccdd;
Will this cause any problems?
The space specified in the linker script defines where and what the linker can locate in the defined memory regions. It will not locate anything to the "hole" you have left at 0xA0000000 to 0xA000000F because it is not aware of it.
In that sense it is "safe" in that the linker will not attempt to use that space. It is entirely in the control of your code - you have taken responsibility for that region by not giving it to the linker. And indeed the statement:
(*(uint32_t *)(void *)0xA0000000) = 0xaabbccdd;
will write a 32 bit value to that location. The point is neither the compiler nor the linker will prevent you from doing what you will in that region.
What is less plausible is LENGTH = 1M. That would make your mram 0x100010 bytes long (i.e. 1M + 0x10). That is a problem because the linker is free to locate objects in the region 0x100000 to 0x10000F. The consequences of that depend on your hardware, but quite possibly it will wrap into the region 0x100000 to 0x10000F that you have attempted to hide from the linker. I would imagine that you need LENGTH = 1M - 0x10 or LENGTH = 0x0FFFF0.
Now while you can absolve the linker from managing that region in order to manage it in your code, it may not be the best approach. It would be better to create a linker symbol at the required absolute address.
So given:
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
mram (rwx) : ORIGIN = 0xA0000000, LENGTH = 1M
}
Your would create a linker symbol in mram:
SECTIONS
{
...
.mram :
{
reserved_mram = 0 ; /* address is zero offset from .mram1 */
. += 0x10 ; /* create 16 byte "hole" at address reserved_mram */
... /* other mram linker assignment follows */
} < mram
...
}
Then in your code you should be able to declare:
extern uint32_t reserved_mram[] ; // 4 x 32-bit word array.
And through reserved_mram you can access the memory at 0xA00000000 symbolically and the code is always in sync with the linker script so you can relocate the space easily without introducing a conflict.
Of course there is no bounds checking and no size information - you still need to confine your access to reserved_mram[0] to reserved_mram[3].
You might alternatively create a separate symbol for each location (with meaningful names specific to your application):
.mram :
{
reserved_mram1 = 0 ;
. += 4 ;
reserved_mram2 = . ;
. += 4 ;
reserved_mram3 = . ;
. += 4 ;
reserved_mram4 = . ;
. += 4 ;
... /* other mram linker usage follows */
} < mram
Then in your code:
extern uint32_t reserved_mram1 ;
extern uint32_t reserved_mram2 ;
extern uint32_t reserved_mram3 ;
extern uint32_t reserved_mram4 ;
Another alternative; you might create an independent section for the region, then create variables within it using __attribute__((section(.xxx))) directives in the code. e.g:
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
mram1 (rwx) : ORIGIN = 0xA0000000, LENGTH = 0x10
mram2 (rwx) : ORIGIN = 0xA0000010, LENGTH = 0xFFFF0
}
SECTIONS
{
...
.mram1 :
{
*(.mram1)
} < mram1
...
}
Then in your code:
uint32_t my_mram_data __attribute__ ((section (".mram1"))) ;
The variable my_mram_data will be created somewhare in .mram1, but the linker decides where. The advantage here is that you can create arbitrary variables in the code without modifying the linker script, and if you attempt to allocate to .mram1 more data than is available you will get a linker error.
Note that linker script syntax is arcane and varies between linkers - I am unassuming this relates to the GNU linker? But my linker foo is strictly on demand (i.e. I figure it out when I need to) and I make no claim that any of the above is complete or correct, or even the only possible solutions - regard it as illustrative, and refer to the linker documentation for accurate information.

Get address of ram sections during runtime

I want to implement a stack usage monitor for my NRF52840-Mikrocontroller with Segger Embedded Studio.
To monitor the maximum stack usage, I need some information during runtime like the end address of the .bss segment, which is the start of my free memory.
My approach is, to fill the ram from the .tbss section until to the stackpointer with a magic word.
During runtime, the stack will grow and will overwrite my magic words with data.
In a cyclic check, I am able to dedicate the end of the stack. From that information, I can derive the approximate stack usage.
Is it possible to get the addresses from the picture below during runtime in my c (or ASM) Program?
Here is a part of my .map file, where for example the symbol __bss_start is defined. Is it possible to access this symbol from c code?
*(COMMON)
0x0000000020020ec4 __bss_end__ = (__bss_start__ + SIZEOF (.bss))
0x000000000001b8c8 __bss_size__ = SIZEOF (.bss)
0x0000000020020ec4 __bss_load_end__ = __bss_end__
0x0000000000000001 . = ASSERT (((__bss_start__ == __bss_end__) || ((__bss_end__ - __RAM_segment_start__) <= __RAM_segment_size__)), error: .bss is too large to fit in RAM memory segment)
0x0000000020020ec4 __tbss_load_start__ = ALIGN (__bss_end__, 0x4)
Thanks for your help, I have solved the Problem now.
To access the symbols of the .map file during runtime, I used the following code:
extern char __bss_end__;
int main()
{
char * bss = &__bss_end__;
}
After this line of code, the bss variable contains the start address of the bss-section.
With this code, I am able to get the addresses of the RAM segments during runtime to monitor my stack usage.

snprintf() prints garbage floats with newlib nano

I am running a bare metal embedded system with an ARM Cortex-M3 (STM32F205). When I try to use snprintf() with float numbers, e.g.:
float f;
f = 1.23;
snprintf(s, 20, "%5.2f", f);
I get garbage into s. The format seems to be honored, i.e. the garbage is a well-formed string with digits, decimal point, and two trailing digits. However, if I repeat the snprintf, the string may change between two calls.
Floating point mathematics seems to work otherwise, and snprintf works with integers, e.g.:
snprintf(s, 20, "%10d", 1234567);
I use the newlib-nano implementation with the -u _printf_float linker switch. The compiler is arm-none-eabi-gcc.
I do have a strong suspicion of memory allocation problems, as integers are printed without any hiccups, but floats act as if they got corrupted in the process. The printf family functions call malloc with floats, not with integers.
The only piece of code not belonging to newlib I am using in this context is my _sbrk(), which is required by malloc.
caddr_t _sbrk(int incr)
{
extern char _Heap_Begin; // Defined by the linker.
extern char _Heap_Limit; // Defined by the linker.
static char* current_heap_end;
char* current_block_address;
// first allocation
if (current_heap_end == 0)
current_heap_end = &_Heap_Begin;
current_block_address = current_heap_end;
// increment and align to 4-octet border
incr = (incr + 3) & (~3);
current_heap_end += incr;
// Overflow?
if (current_heap_end > &_Heap_Limit)
{
errno = ENOMEM;
current_heap_end = current_block_address;
return (caddr_t) - 1;
}
return (caddr_t)current_block_address;
}
As far as I have been able to track, this should work. It seems that no-one ever calls it with negative increments, but I guess that is due to the design of the newlib malloc. The only slightly odd thing is that the first call to _sbrk has a zero increment. (But this may be just malloc's curiosity about the starting address of the heap.)
The stack should not collide with the heap, as there is around 60 KiB RAM for the two. The linker script may be insane, but at least the heap and stack addresses seem to be correct.
As it may happen that someone else gets bitten by the same bug, I post an answer to my own question. However, it was #Notlikethat 's comment which suggested the correct answer.
This is a lesson of Thou shall not steal. I borrowed the gcc linker script which came with the STMCubeMX code generator. Unfortunately, the script along with the startup file is broken.
The relevant part of the original linker script:
_estack = 0x2000ffff;
and its counterparts in the startup script:
Reset_Handler:
ldr sp, =_estack /* set stack pointer */
...
g_pfnVectors:
.word _estack
.word Reset_Handler
...
The first interrupt vector position (at 0) should always point to the startup stack top. When the reset interrupt is reached, it also loads the stack pointer. (As far as I can say, the latter one is unnecessary as the HW anyway reloads the SP from the 0th vector before calling the reset handler.)
The Cortex-M stack pointer should always point to the last item in the stack. At startup there are no items in the stack and thus the pointer should point to the first address above the actual memory, 0x020010000 in this case. With the original linker script the stack pointer is set to 0x0200ffff, which actually results in sp = 0x0200fffc (the hardware forces word-aligned stack). After this the stack is misaligned by 4.
I changed the linker script by removing the constant definition of _estack and replacing it by _stacktop as shown below. The memory definitions were there before. I changed the name just to see where the value is used.
MEMORY
{
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
}
_stacktop = ORIGIN(RAM) + LENGTH(RAM);
After this the value of _stacktop is 0x20010000, and my numbers float beautifully... The same problem could arise with any external (library) function using double length parameters, as the ARM Cortex ABI states that the stack must be aligned to 8 octets when calling external functions.
snprintf accepts size as second argument. You might want to go through this example http://www.cplusplus.com/reference/cstdio/snprintf/
/* snprintf example */
#include <stdio.h>
int main ()
{
char buffer [100];
int cx;
cx = snprintf ( buffer, 100, "The half of %d is %d", 60, 60/2 );
snprintf ( buffer+cx, 100-cx, ", and the half of that is %d.", 60/2/2 );
puts (buffer);
return 0;
}

Resources