简体   繁体   中英

Return value from function in "function pointer mode"

First, sorry for my English. I'm brazilian still trying to learn (english,and programming).

I'm trying to create a firmware application (STM32 uc), that access other firmware (my address was divided in BL + FWA + FWB), but I have one problem and can't find the reason. FWB needs to access a function on FWA, to use less flash area. I can access the function itself, execute any operations inside it, but when return is reached, it gives-me an HardFault. I'm using scatter file to use memory shared on both FWA and B.

  LR_IROM1 0x08004000 0x00004000  {    ; load region size_region
  ER_IROM1 0x08004000 0x00004000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 UNINIT 0x00001000  {  ; No init data
   *(.noinit)
  }
  RW_IRAM2 0x20001000 0x00004000  {
   .ANY (+RW +ZI) //RW data
  }
}

and my funcition is defined as

uint getInt(void) __attribute__((section(".ARM.__at_0x8006000")));//My fw was at 0x4000, total size is 0x4000,
                                                                  //so space is not the problem.
uint getInt(void){
    return 42;
}

On my application (running on FWA for testing itself, but no result), I'm trying to call it this way:

uint (*fun_ptr)(void) = (uint(*)(void))0x8006000;
uint _get_int= fun_ptr();
uint result = _get_int();

Edit: When using

IntFunc p =             getInt;
uint ccccc = p();
uint aaaa = getInt();

all options work correcty, the problem is when using address.

As I mentioned, I can enter the function "getInt()", I can execute any code instruction inside it, but when "return 42" is reached, I have a HardFault.

I find another way to do this, using structs, working, but I think that is very important to understand this problem, understand where is the error, this helps to don't make mistakes again.

EDIT 2: I want to understand the problem, not just simply get an solution. This method works to me: main.h file

typedef struct bootloaderApi bootloaderApi;
typedef   unsigned int (*do_something_t)(void);
struct bootloaderApi{
    do_something_t do_something;
};

and Main.c:

const struct bootloaderApi api __attribute__((section(".ARM.__at_0x8005000")))
= {.do_something = &getInt}; //address 0x5000 to test.

and using it as

struct bootloaderApi *apit = (struct bootloaderApi *)0x8005000;
uint pa = api.do_something();

it works correctly, pa returns me the uint 42.

Thanks.

Try:

uint (*fun_ptr)(void) = (uint(*)(void))0x8006001;

because all function pointers on this architecture must be odd.

The address is the real address of the first instruction (which is always even) plus one. The last bit indicates that the instruction uses the "thumb" instruction set, not the "arm" instruction set which is not available on this device.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM