Samraksh / eMote

eMote OS -- Multiple Ports (using .NET MF v4.3)
0 stars 0 forks source link

Stop using extern C #460

Open Nathan-Stohs opened 7 years ago

Nathan-Stohs commented 7 years ago

There has been a persistent myth that certain code sections require extern "C"

Example:

extern "C" 
{
    //UINT64  HAL_Time_CurrentTicks( UINT16 Timer = 1 );
    UINT64  HAL_Time_CurrentTicks(  );
    UINT64  Time_CurrentTicks    ( ); 
}

Technically speaking this isn't "wrong" but its putting the compiler through contortions that might for instance be hurting optimization and potentially causes headaches for developers.

I'm here to tell you that in the MF code there is exactly one time when you need extern "C" and in common use its not touched. The ONLY time you need it is when referencing HARDWARE interrupt vectors. So this means that if you are not the interrupt driver (STM32__AITC.cpp) then you don't need it. An example of a function that needs it is void __irq RTC_IRQHandler() which is implemented in aforementioned file. The only exception is that UART interrupt vector which is implemented directly in the UART driver for performance reasons.

In particular drivers and the typical interrupt handlers they use do not need extern "C" because they are merely derived from the hardware vectors. So for example from the radio driver which uses a GPIO handler does not need it and is typical:

// Declare
static void si446x_spi2_handle_interrupt(GPIO_PIN Pin, BOOL PinState, void* Param);
...

// Init
CPU_GPIO_EnableInputPin( SI446X_pin_setup.nirq_mf_pin, FALSE, si446x_spi2_handle_interrupt, GPIO_INT_EDGE_LOW, RESISTOR_DISABLED);
...

// Define
static void si446x_spi2_handle_interrupt(GPIO_PIN Pin, BOOL PinState, void* Param)
{ ... }

The first example I gave above showing use in the Time driver is completely gratuitous.

To give a little more technical detail, the only reason we need extern "C" at all is to link against the STM32 libraries, which are C-based. This lets the linker know that certain symbols will have C-style naming instead of what it expects which is C++ style naming (aka "mangled").