This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem in function pointer variable

Hello,
I have faced a problem with a function pointer variable. I have separated the uart module in two parts: HAL, which abstracts the hardware, and Service, which provides the uart service to the application. The interrupt routine is in HAL module, which has a function pointer variable that is called into the interrupt routine as interrupt handler. The actual interrupt handler function is in Service module. This function is assigned to the function pointer variable through a install function in the init routine.
It works in debug simulation, but when I load the hex file to the microcontroller the application does not work. Anyone can help me?

  • Your design, while nice, is rather a bad match for an 8051 controller. In a nutshell, 8051s hate function pointers in C programs. Any usage of them makes the compiler's and linker's job explosively harder. And function pointers in an interrupt handler are even worse.

    C51 interrupt handlers are best kept short. Really short. As a rule of thumb they shouldn't be calling any other functions if you can possibly help it --- much less refer to other functions via pointers.

    So I strongly advise to stop worrying about why exactly this doesn't work --- just don't do it.

  • All functions called within an interrupt must be reentrant. (it's a keil keyword).

    I have some code that calls queue functions from within a serial interrupt. It will make a disaster of the stack and data if you don't mark such functions reentrant, and of course I forgot this. So each time I attempted communication the system would have a seizure.

    The ISR has a seperate variable and data allocation from your main program. This is why you must set such functions you call from an ISR reentrant.

    In addition I concur with the prior suggestion. Keep interupts extremely simple with the C51. Remember your uC stack is < 256 bytes at best. Worst case is 128 bytes or less. Stack only uses data/idata space. You may be getting stack corruption by the way.

    Stephen

  • All functions called within an interrupt must be reentrant. (it's a keil keyword).
    what a waste, there is no need.

    Also as a general (not totally unbreakable) rule no functions should be called from ISRs.

    Erik

  • Well it's not always necessary but unfortunately it is necessary for certain things. In my case the serial port queue code was also the same as some other queues code so they shared common functions/routines. That's the way it goes.

    The most important thing was that it prevented the reinvention of bugs err new wheels. :D Bugs were (are) more expensive than code space I've decided.

    Stephen

  • first: All functions called within an interrupt must be reentrant. (it's a keil keyword).

    then: Well it's not always necessary

    correct: it is NEVER necessary unless you are doing the crazy (for C51) stuff of calling functions from both main and an ISR.

    Erik

  • "All functions called within an interrupt must be reentrant."

    No, that is not true at all.

    The point is that C51 functions are not inherently reentrant; so, if you need them to be so - eg, because you call them from both ISR and "main" code - then you must specifically make them so.
    eg, by use of the reentrant keyword.

  • Read: Application Note 129, "Function Pointers in C51"
    http://www.keil.com/appnotes/docs/apnt_129.asp

    And: BL51 User's Guide, "Function Pointers"
    http://www.keil.com/support/man/docs/bl51/bl51_ol_fp.htm
    and the linked articles...

    And, of course, do the Search for the very large amount of information already on the subject: www.keil.com/search.asp

  • This really doesn't sound like an appropriate way to be programming for an 8051!

    If you really need to program this way, then a different target would probably be better for you;
    Or, if you really need to use an 8051, then a different programming approach would probably be appropriate!

    Have you looked at the UART driver examples provided by Keil?
    They should be perfectly adequate:

    http://www.keil.com/download/docs/200.asp

    http://www.keil.com/download/docs/71.asp

  • If you really need to program this way, then a different target would probably be better for you;
    Or, if you really need to use an 8051, then a different programming approach would probably be appropriate!

    second the motion

    Erik