• AVR Freaks

AnsweredHot!choose custom address for an object

Page: < 12 Showing page 2 of 2
Author
Antipodean
Super Member
  • Total Posts : 1903
  • Reward points : 0
  • Joined: 2008/12/09 10:19:08
  • Location: Didcot, United Kingdom
  • Status: offline
Re: choose custom address for an object 2020/07/30 06:57:29 (permalink)
+2 (2)
crosland
As I've said before, it was very easy in C18. I used function pointers at a known addresses. If the bootloader or the app were modified then everything still worked as the function pointers remained at their known addresses.

Ah, yes, the good old jump table as used in CP/M bios and OS modules. Smile: Smile

Do not use my alias in your message body when replying, your message will disappear ...

Alan
#21
visenri
Starting Member
  • Total Posts : 14
  • Reward points : 0
  • Joined: 2017/10/25 15:30:29
  • Location: 0
  • Status: offline
Re: choose custom address for an object 2020/07/30 16:38:27 (permalink) ☄ Helpfulby pajuhesh80 2020/08/17 02:22:00
+2 (2)
pajuhesh80
I wrote my bootloader and used __reentrant and fixed address for shared functions but I can't call them.
I used some strange pointers and even asm("goto 0xABC") and asm("call 0xABC"). Pointers are compiler but have no effect. Inline assemblies stop normal code execution but still not working.
I checked map file. All functions are placed where I set.



I explained this with a lot of detail (and disassembly outputs), but the f*u*c*k*i*n*g forum ruined all my text with an access denied message (normally I copy it before posting, but not this timemad: mad), so, I'll resume it:
 
This is where you define the address and function prototype.
#ifndef FOO_H
#define FOO_H

#include <xc.h>
#define SHARED_FOO_ADDRESS 0xDD0
__reentrant extern int sharedFoo(int value) __at(SHARED_FOO_ADDRESS);

#endif /* FOO_H */

 
No need to use function pointers, this works for me, it calls address 0xDD0:
#include <xc.h>
#include "foo.h"

void main(void) 
{
    if(sharedFoo(11) == 13)
    {
        NOP();
    }
    while(1){}
}

 
This also works:
#include <xc.h>
#include "foo.h"

void main(void) 
{
    int (* pSharedFoo)(int) = sharedFoo;
    if(pSharedFoo(10) == 12)
    {
        NOP();
    }
    while(1){}
}

 
Look at the dissasembly and simulate them in MPLABX and you'll see both examples work.
 
IMHO this should work, but does not, as you've already seen (anyway as we all know casting numbers to pointers is not the best practice), we are in an undefined behavior field:
int (* pSharedFoo)(int) = (int (*)(int))(SHARED_FOO_ADDRESS);

 
ONE MORE IMPORTANT TRAP FOR YOUNG PLAYERS:
Functions that use the reentrant model will pass values back to the calling function via
btemp variables, provided the value is 4 bytes or less in size. The W register will be
used to return byte-sized values for enhanced mid-range device functions that are not
variadic. For objects larger than 4 bytes in size, they are returned on the stack.
Reentrant PIC18 functions that return a bit do so using bit #0 in btemp0; other
devices use the carry bit in the STATUS register.

  • No problems with parameters.
  • Potential problems with return values smaller than 5 bytes, because as far as I know btemp address is not guaranteed to be always at the same address. So use global variables with absolute addresses or variables > 4 bytes.
 
 
#22
pajuhesh80
Super Member
  • Total Posts : 101
  • Reward points : 0
  • Joined: 2019/12/08 11:23:37
  • Location: Nowshahr, Mazandaran, Iran
  • Status: offline
Re: choose custom address for an object 2020/08/14 04:55:02 (permalink)
0
I tried what you said visenri. I used Reentrant stack type for my bootloader. I can see "CALL    0xA18, 0" in disassembly of both bootloader and main app. 0xA18 is address of Bootloader() function which configures MCU for boot and USB communication and starts processing USB data.
However, MCU shows strange behavior when I call Bootloader() from main app. To test it, I wrote some code to fall in an infinite loop if Bootloader() is called from main app. However, MCU skips it, initializes USB, jumps to main app, and calls Bootloader() again. Windows says USB device not recognized continuously meanwhile. It will continue doing so until I connect boot pin to GND to force MCU to enter bootloader mode. My bootloader decides to call Bootloader() or go to main app start address in main() function based on boot pin and program memory status. So each time main app calls Bootloader() and those strange things happen, program starts from address 0.
What is going on? Is it related to memory banks?
Also, because of this bad designed forum, I'm angry from Microchip, too! But I think it's better to remove that phrase from your post to keep here neat and friendly!

Slow and Steady!
#23
Page: < 12 Showing page 2 of 2
Jump to:
© 2020 APG vNext Commercial Version 4.5