• AVR Freaks

Hot!Can I call static function by pointer from another object?

Author
kaamil1984
Junior Member
  • Total Posts : 55
  • Reward points : 0
  • Joined: 2014/05/01 14:02:25
  • Location: Chair at the desk in my workshop ;)
  • Status: offline
2021/02/17 14:51:20 (permalink)
0

Can I call static function by pointer from another object?

Hi guys,
 
I wrote simple timer library, which allows me to execute functions with specyfic delay without blocking.
 
app_timer.h file:
 

 
#ifndef TIMER_SM_H
#define TIMER_SM_H
 
#define MAX_TIMER_INSTANCES 16
 
typedef struct {
uint32_t endTicks;
void (* endCallback)(); // NULL tells that this timer is not in use
} timer_sm_t;
 
volatile uint32_t app_timer_ms_x10;
volatile timer_sm_t timers[MAX_TIMER_INSTANCES];
 
void TIMER_10MS_Callback(void);
void TIMER_Initialize(void);
void TIMER_Start(void (* cb)(void), uint32_t ms_x10);
 
#endif /* TIMER_SM_H */
 

 
app_timer.c file:
 

 
#include <stdint.h>
#include <stddef.h>
#include "app_timer.h"
 
// Call this every 10ms from some timer
void TIMER_10MS_Callback(void)
{
app_timer_ms_x10++;

uint8_t i;
for (i = 0; i < MAX_TIMER_INSTANCES; i++) {
if (timers[i].endCallback != NULL)
{
if (timers[i].endTicks == app_timer_ms_x10)
{
timers[i].endCallback();
timers[i].endCallback = NULL;
}
}
}
}
 
// Call this initializer once before using TIMER_Start(...) function
void TIMER_Initialize(void) {
// set 0/NULL in all structs
uint8_t i;
for (i = 0; i < MAX_TIMER_INSTANCES; i++) {
timers[i].endCallback = NULL;
}

// reset timer_sys_tick
app_timer_ms_x10 = 0;
}
 
// Schedule function execution after specyfic time
void TIMER_Start(void (* cb)(void), uint32_t ms_x10) {

// find first free timer
uint8_t i;
for (i = 0; i < MAX_TIMER_INSTANCES; i++) {
if (timers[i].endCallback == NULL)
{
timers[i].endCallback = cb;
timers[i].endTicks = app_timer_ms_x10 + ms_x10;
return; // for
}
}
// AppException(APP_EXC_ALL_TIMERS_IN_USE); todo: port AppException to 8bit
return;
}
 

 
I'm passing function pointer and delay in tens of milliseconds in this version. My timer library will start this function at the right time.
 
--- 
 
Now I want to pass static function there, like this:
 
some_other.c file:

 
#include "app_timer.h"

#include "mcc_generated_files/pin_manager.h"

void initiate_reset_cm(void)
{
CM_RST_SetLow(); // pull reset low
TIMER_Start(finish_reset_cm, 10); // pull reset high after 10*10ms
}

static void finish_reset_cm(void)
{
CM_RST_SetHigh();
}

 
I have added "static" keyword to allow regular calls only for
initiate_reset_cm
function.
 
 
THE QUESTION:
 
Can I be sure this function will be properly called by pointer from outside when it is static?
 
I can't find anything about calling static functions by pointer in "MPLAB® XC8 C Compiler User’s Guide".
I know that 8-bit PIC devices have long and short addressing and I'm a bit worried, that at some compilation something will be optimized, function will move far away and some "undefined behavior" will happen.
post edited by kaamil1984 - 2021/02/17 14:53:06
#1

3 Replies Related Threads

    Aussie Susan
    Super Member
    • Total Posts : 3855
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: Can I call static function by pointer from another object? 2021/02/17 18:28:00 (permalink)
    +1 (1)
    My understanding is that as long as the function is referenced then it will not be 'optimised away' and setting up the pointer that function should be enough of a reference. This is a fairly standard 'C' thing to do.
    However there are others who can give a more authoritative response.
    I really wanted to respond to this topic with a word of caution: you don't show how the 'TIMER_10MS_Callback()' is called but if it from the ISR then you need to be VERY careful that the functions being called execute very quickly, never block or do other things that would normally be frowned on in a ISR.
    Susan
    #2
    NKurzman
    A Guy on the Net
    • Total Posts : 19185
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Can I call static function by pointer from another object? 2021/02/17 21:13:21 (permalink)
    +1 (1)
    For normal C compilers it should work.
    No I’m not sure why you would want to use a static function that way. Why make it static if your intent purposely get around the static key word.
    For XC8 with his compiled stack the chances of it working are mixed since The compiler will have to determine that a pointer is going to be used to call that function and properly place it on the compiled stack. You might need to switch to the simulated stack if you really need to do this.
    #3
    Mysil
    Super Member
    • Total Posts : 4130
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: Can I call static function by pointer from another object? 2021/03/01 19:28:57 (permalink)
    +2 (2)
    Hi,
    Yes,
    a function with static linkage may be called from another  compilation unit,
    on the condition that the function pointer is a global pointer variable that is available as an extern  pointer in the code where the function will be called.
    This work also in XC8, where calls by function pointers are used for Interrupt Handlers,
    and Callback Handlers in MCC.
    I have used Callback Handlers defined with static linkage, called from pointers in other compilation units.
     
    The following statement define storage for the array of timer objects containing function pointers,
    and should not be in a header file:
    volatile timer_sm_t timers[MAX_TIMER_INSTANCES];

    Instead, storage should be defined in a single .c source file, and extern declaration be made available in the header file:
    extern volatile timer_sm_t timers[MAX_TIMER_INSTANCES];

     
        Mysil
     
    #4
    Jump to:
    © 2021 APG vNext Commercial Version 4.5