How to evaluate digitalWrite at compile time?

What could be included in further releases, or for the forum.
Post Reply
danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

How to evaluate digitalWrite at compile time?

Post by danieleff » Mon May 29, 2017 4:22 am

If the parameters are constant, I want digitalWrite(pin, val) to evaluate it at compile time. Down to one instruction.
Currently pseudocode (the exact structure of pin_type is irrelevant):

Code: Select all

//variant.cpp
const pin_type variant_pins[] = {...}

//gpio.h
extern const pin_type variant_pins[];
inline void digitalWrite(pin, value) {...variant_pins[pin]...}

//x.ino
...gpio.h included...
digitalWrite(PA0, LOW);

//other.cpp
...gpio.h included...
digitalWrite(PA1, LOW);
Theoretically variant_pins[pin] could be evaluated at compile time (well, link time, but at compile time it could be a placeholder that the linker fills in), but it is not.

I could put the whole list into the header (as static local), which works, but then it is duplicated in every compilation unit when used.

I checked https://stackoverflow.com/q/5010216/834966 , https://stackoverflow.com/q/11403800/834966 , -fmerge-all-constants , -flto and god knows what already.
I always get either no compile time evaluation, or duplicated array.
Anybody knows some solution to this?

ag123
Posts: 798
Joined: Thu Jul 21, 2016 4:24 pm

Re: How to evaluate digitalWrite at compile time?

Post by ag123 » Mon May 29, 2017 9:11 am

i'm not too sure if c++ templates could help or perhaps some kind of pointer style codes is needed ?
i'm not too sure how to use those

Code: Select all

template<class T>
function(T&a) {
 static_cast<T&&>(a);
 }
stuff but i do see them in various c++ codes

stevestrong
Posts: 1813
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: How to evaluate digitalWrite at compile time?

Post by stevestrong » Mon May 29, 2017 9:25 am

I would define separate inline functions digitalSet(PIN) and digitalClear(PIN) something like this:

Code: Select all

inline void digitalSet(p) { PIN_MAP[p].dev->regs->BSRR = PIN_MAP[p].pin; }

danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: How to evaluate digitalWrite at compile time?

Post by danieleff » Thu Jun 01, 2017 5:16 am

Well it did need some trickery, making pin names constexpr int-convertable class instead of enum when compiling for c++, but now this

Code: Select all

void loop() {
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(LED_BUILTIN, LOW);
}
compiles to

Code: Select all

08002188 <loop>:
 8002188:	2202      	movs	r2, #2
 800218a:	4b04      	ldr	r3, [pc, #16]	; (800219c <loop+0x14>)
 800218c:	611a      	str	r2, [r3, #16]
 800218e:	615a      	str	r2, [r3, #20]
 8002190:	611a      	str	r2, [r3, #16]
 8002192:	615a      	str	r2, [r3, #20]
 8002194:	611a      	str	r2, [r3, #16]
 8002196:	615a      	str	r2, [r3, #20]
 8002198:	4770      	bx	lr
 800219a:	bf00      	nop
 800219c:	40010c00 	.word	0x40010c00
which is good enough

lacklustrlabs
Posts: 8
Joined: Fri May 05, 2017 12:35 pm

Re: How to evaluate digitalWrite at compile time?

Post by lacklustrlabs » Thu Dec 07, 2017 5:47 pm

Care to show the code?
The closest I've come to that result is to define a set of large constexpr functions (autogenerated) that a template class can operate on.
https://gitlab.com/LacklustrLabs/lacklu ... abs_gpio.h

The results are kind of clumsy, what I could use is a constexpr conversion of PIN_MAP in the core.

victor_pv
Posts: 1741
Joined: Mon Apr 27, 2015 12:12 pm

Re: How to evaluate digitalWrite at compile time?

Post by victor_pv » Sat Dec 09, 2017 2:49 am

It's likely used in the STM32Generic core that he maintains, the link should be here in the forum, in the cores section, first post from Roger.

victor_pv
Posts: 1741
Joined: Mon Apr 27, 2015 12:12 pm

Re: How to evaluate digitalWrite at compile time?

Post by victor_pv » Sat Dec 09, 2017 5:49 am

victor_pv wrote:
Sat Dec 09, 2017 2:49 am
It's likely used in the STM32Generic core that he maintains, the link should be here in the forum, in the cores section, first post from Roger.
Out of curisity I looked it up, is in this file, although there is another related, variant.h in each variant folder:
https://github.com/danieleff/STM32GENER ... pin_list.h

dannyf
Posts: 167
Joined: Wed May 11, 2016 4:29 pm

Re: How to evaluate digitalWrite at compile time?

Post by dannyf » Sat Dec 09, 2017 6:55 pm

If the parameters are constant, I want digitalWrite(pin, val) to evaluate it at compile time. Down to one instruction.
for what end?

presumably for efficiency. but that's not high on arduino's priority list: this thing is geared to people who want to write generic code with minimum efforts.

if you care about efficiency, you probably should have picked on some other tools.

trying to do what you are trying to do is like driving a pig through a square hole.

User avatar
ahull
Posts: 1650
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: How to evaluate digitalWrite at compile time?

Post by ahull » Sun Dec 10, 2017 7:20 am

dannyf wrote:
Sat Dec 09, 2017 6:55 pm
...
trying to do what you are trying to do is like driving a pig through a square hole.
That can work... if you choose the correct pig.

Image

;)
- Andy Hull -

Post Reply