Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to writing masks for 32 bit microcontrollers

I am working on a project that involves programming 32 bit ARM micro-controllers. As in many embedded software coding work, setting and clearing bits are essential and quite repetitive task. Masking strategy is useful when working with micros rather than 32 bits to set and clear bits. But when working with 32 bit micro-contollers, it is not really practical to write masks each time we need to set/clear a single bit.

Writing functions to handle this could be a solution; however having a function occupies memory which is not ideal in my case.

Is there any better alternative to handle bit setting/clearing when working with 32 bit micros?

like image 607
gbudan Avatar asked May 22 '14 20:05

gbudan


1 Answers

In C or C++, you would typically define macros for bit masks and combine them as desired.

/* widget.h */
#define WIDGET_FOO 0x00000001u
#define WIDGET_BAR 0x00000002u

/* widget_driver.c */
static uint32_t *widget_control_register = (uint32_t*)0x12346578;

int widget_init (void) {
    *widget_control_register |= WIDGET_FOO;
    if (*widget_control_register & WIDGET_BAR) log(LOG_DEBUG, "widget: bar is set");
}

If you want to define the bit masks from the bit positions rather than as absolute values, define constants based on a shift operation (if your compiler doesn't optimize these constants, it's hopeless).

#define WIDGET_FOO (1u << 0)
#define WIDGET_BAR (1u << 1)

You can define macros to set bits:

/* widget.h */
#define WIDGET_CONTROL_REGISTER_ADDRESS ((uint32_t*)0x12346578)
#define SET_WIDGET_BITS(m) (*WIDGET_CONTROL_REGISTER_ADDRESS |= (m))
#define CLEAR_WIDGET_BITS(m) (*WIDGET_CONTROL_REGISTER_ADDRESS &= ~(uint32_t)(m))

You can define functions rather than macros. This has the advantage of added type verifications during compilations. If you declare the function as static inline (or even just static) in a header, a good compiler will inline the function everywhere, so using a function in your source code won't cost any code memory (assuming that the generated code for the function body is smaller than a function call, which should be the case for a function that merely sets some bits in a register).

/* widget.h */
#define WIDGET_CONTROL_REGISTER_ADDRESS ((uint32_t*)0x12346578)
static inline void set_widget_bits(uint32_t m) {
    *WIDGET_CONTROL_REGISTER_ADDRESS |= m;
}
static inline void set_widget_bits(uint32_t m) {
    *WIDGET_CONTROL_REGISTER_ADDRESS &= ~m;
}
like image 130
Gilles 'SO- stop being evil' Avatar answered Sep 17 '22 18:09

Gilles 'SO- stop being evil'