Which is the best way to override vPortSuppressTicksAndSleep (or others)?

I want to change sleep behaviour and for this I want to override vPortSuppressTicksAndSleep, which is the planned way I guess because it has attribute( ( weak ) ).
Now I created a new .c file with my own vPortSuppressTicksAndSleep in it, without attribute( ( weak ) ) and ran into these problems:

  • There are several defines in port.c needed in this function, I simply copied them to my file. But it is not so nice.

  • There are three static variables in port.c that I can’t access as extern in another file, I get linker errors

As another solution I tried to put my vPortSuppressTicksAndSleep in a file that I include at the end of port.c but that results in an error “redeclaration of…”

The only solution I see now is to change port.c directly, which I wanted to avoid and which would make the attribute( ( weak ) ) useless.

(working with STM CubeIDE with GCC 10.3.1)
Thanks for any help

The application is free to implement this function in whatever way they want. Which #defines and static variables are you talking about?

Here is a part of my .c file with the needed declarations:

// copies of needed macros and variable declarations from port.c:
#  define portNVIC_SYSTICK_CTRL_REG          (*((volatile uint32_t *)0xe000e010))
#  define portNVIC_SYSTICK_LOAD_REG          (*((volatile uint32_t *)0xe000e014))
#  define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile uint32_t *)0xe000e018))
#  define portNVIC_SYSTICK_CLK_BIT           (1UL << 2UL)
#  define portNVIC_SYSTICK_INT_BIT           (1UL << 1UL)
#  define portNVIC_SYSTICK_ENABLE_BIT        (1UL << 0UL)
#  define portNVIC_SYSTICK_COUNT_FLAG_BIT    (1UL << 16UL)
#  define portNVIC_PEND_SYSTICK_SET_BIT      (1UL << 26UL)
#  define portNVIC_PEND_SYSTICK_CLEAR_BIT    (1UL << 25UL)
#  ifndef configSYSTICK_CLOCK_HZ
#    define configSYSTICK_CLOCK_HZ          (configCPU_CLOCK_HZ)
/* Ensure the SysTick is clocked at the same frequency as the core. */
#  else
/* Select the option to clock SysTick not at the same frequency as the core. */
#    define portNVIC_SYSTICK_CLK_BIT_CONFIG (0)
#  endif
#  define portNVIC_SYSTICK_INT_BIT (1UL << 1UL)

#  if (configUSE_TICKLESS_IDLE == 1)
extern uint32_t xMaximumPossibleSuppressedTicks;
#  endif /* configUSE_TICKLESS_IDLE */
#  if (configUSE_TICKLESS_IDLE == 1)
extern uint32_t ulTimerCountsForOneTick;
#  endif /* configUSE_TICKLESS_IDLE */
#  if (configUSE_TICKLESS_IDLE == 1)
extern uint32_t ulStoppedTimerCompensation;
#  endif /* configUSE_TICKLESS_IDLE */

Those #defines and those static variables are specific to the SysTick timer. If you write your own version of vPortSuppressTicksAndSleep(), presumably you would use a different timer. Thus you wouldn’t need access to those #defines and static variables.

As @jefftenney explained, you should not need to use those if you are writing your own version of vPortSuppressTicksAndSleep. What problem are you trying to solve?

A complete solution can look like this:

(this is for using STM32 low power timer, not mine)

As you can see, really only the interfaces of FreeRTOS are used.
If you actually want to keep using Systick, maybe what you want to solve can already be achieved with configPRE_SLEEP_PROCESSING or configPOST_SLEEP_PROCESSING.