Friday, June 16, 2023

How to properly do git rebase

https://verdantfox.com/blog/view/how-to-git-rebase-mainmaster-onto-your-feature-branch-even-with-merge-conflicts by Teddy Williams

 

Does your project prefer git rebase instead of git merge? Has your branch fallen out of sync with the main branch and you are unable to automate your rebase due to conflicts? If so, you might have run into rebase hell. This happens when you try to git rebase, solve your conflicts, and push to the main branch, only to find that the main branch is now, once again, out of sync in a never-ending loop. Let's break out of rebase hell with this short guide to rebasing.

The steps

  1. Go to the branch in need of rebasing
  2. Enter git fetch origin (This syncs your main branch with the latest changes)
  3. Enter git rebase origin/main (or git rebase origin/master if your main branch is named master)
  4. Fix merge conflicts that arise however you see fit
  5. After fixing merge conflicts, git add FILE previously merge conflicted files
  6. Enter git rebase --continue (or git rebase --skip if git complains that there were no changes after resolving all conflicts)
  7. Repeat as necessary as merge conflicts arise in the subsequent commits
  8. Once the rebase is complete, enter git push origin HEAD --force-with-lease

    This command pushes your rebase fixed branch to remote. The --force is important as it tells remote, "I know these changes are correct, accept them as is." Without the --force flag, your remote branch will continue to believe it is out of sync and will claim a merge conflict.

And that's it. You have now git rebased the main branch onto your feature branch and broken yourself out of rebase hell.

 

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/