Sunday, July 30, 2017

General C/C++ lambda's and calling C code before main

I've been working on a few small projects, EtherCAT and QuadCopter IO board with USB EEM using STM32 micro-controllers. During this projects found couple interesting C++/C concepts:

  • Using Lambda functions for C callbacks
    • Simplifies static C++ functions to allowing C to call a C++ functions.
  • using GCC init to invoke C functions from C++ initialization.
    • One issue in creating projects is how to control or startup threads, init code etc in the proper order without #include every function.

Lambda Functions for C callbacks

lwIP has an asynchronous interface allowing the programmer not to create a thread to wait on socket events, all of the events occur within lwIP worker thread.  Using the same thread alleviates locking


err_t            tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
                              u16_t port, tcp_connected_fn connected);

The above function starts the TCP connection with the IP address in the function.  So, function requires a C callback function.  

 err = tcp_connect(m_conn, &ipaddr, PORT, [](void *arg, struct tcp_pcb *tpcb, err_t err) -> err_t
                                         {
                                              class *pToClass = reinterpret_cast<class *>(args));
                                              return pToClass->connect(tpcb, err);
                                         }

From the code above, a lambda is used without any capture arguments, this allows the lambda to be callable from C.  So, now the connect function can also be a protected function.  So, no static function needs to be declared. 

Using C++ constructor to invoke a C function before main


Here is a simple function:

static void _startUpUdpServices(void) __attribute__((constructor (102)));
void _startUpUdpServices(void) 
{

    regStartUpFunction(StartUpPriority::_6, "udpServices", (startUpFunctor_t)startUpUDPServices);
}




The __attribute__((constructor (102))); Puts the function in the .init section and orders it to be at 102.  So _startUpUdpServices function will be called before main.  This makes it easy to register a system without calling the function.  nothing is worse then spegitti code to debug.  Now, it is possible to order using higher numbers.  I took a little more time and create anoterh class to register function and order them.

If you have any questions let me know...