Friday, August 5, 2022

GCC ARM Cortex M4 backtrace print from target

To do a more verbose crash logging from HardFault handler (or assert statement) the Backtrace library can be used: https://github.com/red-rocket-computing/backtrace

Don't forget to add -funwind-tables to compiler flags. For function names to be available -mpoke-function-name needs to be added as well (increases binary size!).

Backtrace only records function name and execution address but it can be easily extended to include the stack pointer information which can help to detect stack overflow related problems.

 

Additional resources to consider:

https://alexkalmuk.medium.com/how-stack-trace-on-arm-works-5634b35ddca1
https://maskray.me/blog/2020-11-08-stack-unwinding
https://github.com/ccoffing/airbag_fd/
https://github.com/bakerstu/openmrn/blob/62683863e8621cef35e94c9dcfe5abcaf996d7a2/src/freertos_drivers/common/cpu_profile.hxx#L162
https://stackoverflow.com/questions/6254058/how-to-get-fullstacktrace-using-unwind-backtrace-on-sigsegv
https://stackoverflow.com/questions/47331426/stack-backtrace-for-arm-core-using-gcc-compiler-when-there-is-a-msp-to-psp-swit
https://stackoverflow.com/questions/70652306/how-does-stack-unwinding-in-cortex-m-devices-works
https://stackoverflow.com/questions/59855643/unwind-backtrace-for-different-context-on-freertos
https://gcc.gnu.org/onlinedocs/gcc-10.3.0/gcc/ARM-Options.html#ARM-Options

Thursday, June 23, 2022

C++: consteval in C++17

 

template <auto V>
static constexpr auto force_consteval = V; 
#define STRINGHASH(str) force_consteval<stringhash(str)> 

C++ get declared type info

Useful for automating some compile-time initialization in combination with consteval or constexpr:

#include "string.h"
#include "stdlib.h"
#include <iostream>

template <class T>
constexpr std::string_view type_name()
{
    using namespace std;
#ifdef __clang__
    string_view p = __PRETTY_FUNCTION__;
    return string_view(p.data() + 34, p.size() - 34 - 1);
#elif defined(__GNUC__)
    string_view p = __PRETTY_FUNCTION__;
#  if __cplusplus < 201402
    return string_view(p.data() + 36, p.size() - 36 - 1);
#  else
    return string_view(p.data() + 49, p.find(';', 49) - 49);
#  endif
#elif defined(_MSC_VER)
    string_view p = __FUNCSIG__;
    return string_view(p.data() + 84, p.size() - 84 - 7);
#endif
}

static char x[] = "Test";

int main() {
    std::cout << type_name<decltype(x)>() << "\r\n";
    std::cout << type_name<std::decay<decltype(x)>::type>();
}


Wednesday, March 16, 2022

Scope mutex locking on FreeRTOS

Class:

/** 
  * @brief The FreeRtosScopedLock class, provides an RAII 
  *        style approach to locking a FreeRTOS mutex, 
  *        similar to C++11 std::scoped_lock<> */class FreeRtosScopedLock

{

public:

    explicit FreeRtosScopedLock(SemaphoreHandle_t mutex) :

            mMutex(mutex)

    {

        xSemaphoreTakeRecursive(mMutex, portMAX_DELAY);

        //for demo, assume success

    }


    ~FreeRtosScopedLock()

    {

        xSemaphoreGiveRecursive(mMutex);

        //for demo, assume success

    }


private:

    SemaphoreHandle_t mMutex;

};

 

Usage example: 

bool AccessMyDeviceNewStyle()

{

    ScopedLock lockItDown(mDevMutex);


    if (!SomeGuardCheck())

    {

        return false;

    }


    if (!AnotherGuardCheck())

    {

        return false;

    }


    //Do Stuff


    return true;

}

Godbolt compile explorer 

 

References:

https://covemountainsoftware.com/2019/11/26/why-i-prefer-c-raii-all-the-things/

https://blogs.sw.siemens.com/embedded-software/2017/03/27/more-on-c-with-an-rtos/ 

https://embeddedartistry.com/blog/2018/02/08/implementing-stdmutex-with-freertos/