Electronics > Microcontrollers

Creating a portable and small I/O lib.

(1/6) > >>

Doctorandus_P:
I am having a lot of difficulty in deciding what sort of I/O abstraction I want to use in my own projects.
something like the "digialwrite()" in arduino, but then something that works properly and with zero overhead (compared to machine code)

When I started uC programming with the Atmel AVR's (10+ years before arduino existed). I used simple direct port manipulation:

--- Code: ---#define LED_PIN (1<<4)
#define LED_PORT  PORTD

// Turn the LED on:
LED_PORT &=~ LED_PIN;
--- End code ---

It works, is simple and fairly portable among different uC families, but it does not look pretty in the software, and I am looking for a method that is more readable in the source code. A few days ago I did a little experiment with a C++ class for an STM32.


--- Code: ---Tgpio::Tgpio( GPIO_TypeDef* portname, uint32_t bitname) {
the_port = portname;
the_bit = 1 << bitname;
}

void Tgpio::set( void) {
the_port->BSRR = the_bit;
}

void Tgpio::reset( void) {
the_port->BSRR = the_bit << 16;
}


static Tgpio led( GPIOC, 13);
led.set();


--- End code ---

And of couse the class declaration in the header file:

--- Code: ---class Tgpio {
public:
Tgpio(  GPIO_TypeDef * portname, uint32_t bitname); // Constructor.
void set( void);
void reset( void);

private:
GPIO_TypeDef * the_port;
uint32_t the_bit;
};
--- End code ---


This works, you can easily define more functions in the class, it looks proper in the code, and with the code completion, you can simply type the name of the led, a dot and your IDE gives you options what you can do with the led. A disadvantage is that it has runtime code overhead. I know something similar can be done with templates, but template syntax is quite difficult to write and debug, and I'm not sure if code completion works (in a bunch of different IDE's).

Now I am wondering how much of the code can be transferred from the runtime to compile time by using constructs such as const constexpr, declaring the class as static etc.

ejeffrey:
As long as you compile with optimizations simple functions like this will be inlined 100% as long as the function bodies are visible.

You need to put them in the header file and either explicitly declare them as online or include the body in the class declaration which implicitly declares them inline.

wek:
> it does not look pretty in the software

Who cares?

JW

NorthGuy:
Every programmer has OCD. Some more, some less. This is Ok.

One useful thing to realze is that: Your OCD is not your friend, your OCD is an enemy.

I use macros. Like

#define BLUE_LED_ON something-here

it's very easy to collect all the definitions into a special file, and simply edit it when you move to a different board, or different platform. This gives me endless opportunities - for example, if a new board doesn't have a blue LED I can generate nothing.

nctnico:
I agree with the macros Northguy is suggesting. I'm using these on any platform I'm writing embedded software for. I have 1 file (typically called hardware.h) where all the GPIOs and hardware related defines go into. GPIOs are very project specific so portability is not really an issue here.

#define PIN_BUZZER_EN (1<<10)
#define SET_BUZZER_EN()            GPIOC->BSRR = PIN_BUZZER_EN;
#define CLR_BUZZER_EN()            GPIOC->BRR = PIN_BUZZER_EN;

And use the set and clr macros throughout the rest of the core

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod