I have searched information on Bit-Banding in Cortex-M3 and M4 with the GNU GCC ARM EABI NONE, I have seen basic examples on the internet but none works with GNU GCC also seems that no intention to have such feature implemented.
Can someone tell me if the LD via memory remapping really work? the best approach?
What is the best way?
> none works with GNU GCC
can you be more specific on how you tested this?
I use bit banding for the peripheral memory range without problems, but by using direct access, without any expectations from the linker scripts.
Hi!
Liviu (ilg), I'm using to show my students the impact of Bit-Banding when migrating from AVR to ARM and unlike the technique used both for access to bit-fields in IO ports.
In case I did some testing with their own Arduino IDE, and enter the code below, and made the dump and the code is mixed C and Assembly, did nothing more than the statement of the variable and then assigns the value 1 to she.;
0008014c <loop>: ;volatile __attribute__((bitband, at(0x20000004))) uint32_t myFlag =0 ; ;void loop() { ; myFlag = B00000001; 8014c: 4b01 ldr r3, [pc, #4] ; (80154 <loop+0x8>) 8014e: 2201 movs r2, #1 80150: 601a str r2, [r3, #0] ;} 80152: 4770 bx lr 80154: 200708f0 .word 0x200708f0 I figured it did not reach the goal because of the memory address that is the variable, and then I search the internet in the ARM GCC site for windows saw the post that is the link to follow that would not be supported yet.
0008014c <loop>: ;volatile __attribute__((bitband, at(0x20000004))) uint32_t myFlag =0 ; ;void loop() { ; myFlag = B00000001; 8014c: 4b01 ldr r3, [pc, #4] ; (80154 <loop+0x8>) 8014e: 2201 movs r2, #1 80150: 601a str r2, [r3, #0] ;} 80152: 4770 bx lr 80154: 200708f0 .word 0x200708f0
I figured it did not reach the goal because of the memory address that is the variable, and then I search the internet in the ARM GCC site for windows saw the post that is the link to follow that would not be supported yet.
Question #228758 : Questions : GNU ARM Embedded Toolchain
Moreover, I suspect that lack a directive in the command, would it? But in issue up says it is not supported.
carlosdelfino, I'm not sure I understand what you want to show to your students.
bit-banding basically maps each bit to a word address, so a simple pointer arithmetic does the trick
(PERIPHERAL_BITBAND_BASE + (((registerAddress - PERIPHERAL_BASE) * 8) + bitNumber) * 4)
a functional template can be seen in an older µOS++ repository: micro-os-plus-iii-alpha/BitBand.h (the implementation needs some updates for the new µOS++ code style and C++ 14 goodies, but is functional).
This is a guess only, but I think carlosdelfino is teaching the students that if you need to set or clear a single bit, you can use a single write-cycle instead of read+modify+write cycle (3 or 4 clock cycles).
On AVR, it's necessary to read, then use either AND or OR and then write back the modified value.
That has a terrible disadvantage on the AVR. If you write to a port from an interrupt and you want to change a single bit from task-time, you risk that the interrupt will run in the middle of your read-modify-write cycle, which means that the values your interrupt writes will be available on the port for only a short time, then it's quickly changed back to what it was by your task-time.
To fix that, you can disable interrupts and re-enable them after updating the port at task-time (now 5 clock cycles were used instead of only 1 on ARM).
So one topic is the atomic access, the other topic is saving CPU-time on accessing the same port from both interrupt code and task-time code.
Exactly @Jensbauer
View all questions in GNU Toolchain forum