cpu: Add bit manipulation macros for Cortex-M#6916
Conversation
|
Nice! Some thoughts:
Looking forward to using this for gpio, so with LTO, a |
|
Static inline might work, didn't test yet. |
|
The static inline method seems like it would be best, I found a bunch of mistakes where I missed the address-of operator which was hidden by the cast in the macro version. I will update this PR soon-ish |
3d02631 to
3811708
Compare
|
OK to squash? |
d3c03a3 to
195c125
Compare
|
Another thought: why the fallback for Cortex-M0(+)? IMHO the bitbanging is only used in CPU specific code anyway, and in that code path it should be clear which target is worked on, right? |
|
Another thought: why the fallback for Cortex-M0(+)? IMHO the bitbanging is only used in CPU specific code anyway, and in that code path it should be clear which target is worked on, right? |
|
sorry, wrong button + browser lag... |
|
|
I see, never mind then. |
|
@haukepetersen this is an example of a specific implementation for a kinetis m0+ |
|
@haukepetersen Also, using these functions in the STM common drivers might make sense in some situations, it will use bit-banding on the M3 and up, but still compile cleanly on the low end devices. In Kinetis we use these macros to avoid having to disable IRQs or using mutexes while messing with clock gate registers (since the registers are shared between many different peripheral drivers) |
7cb89b8 to
a5e2d80
Compare
|
I accidentally squashed while rebasing, sorry for that. Anyway, this PR is ready for review and testing. Murdock is fine except for squashing the fixups. |
|
Changes look good to me, but I don't have a board around today, so can test only tomorrow. But please feel free to squash and make Murdock happy with that! |
c3e0cba to
f4334db
Compare
|
Would it make sense to have the interface globally (not only for cortexm)? @gebart what do you think? Otherwise, functions within "bitband.h" should be prefixed with "bitband_*". |
|
@kaspar030 It does make sense to rename the header. I guess it would be possible to move the fallback to a global header and keep the bitband.h part inside cortexm. |
|
I don't quite see the reason to make this global (yet), this is something cpu-arch internal and some other CPU arch that supports this might bring its own style of handling this, so why force this header on every arch?! |
f4334db to
37592ab
Compare
The underlying bitbanding is architecture dependend, but "set bit N of the int at addr A" is not. Currently, we probably use e.g., |
|
|
||
| #if DOXYGEN | ||
| /** @brief Flag for telling if the CPU has hardware bit band support */ | ||
| #define CPU_HAS_BITBAND 1 || 0 (1 for Cortex-M3 and up, 0 for Cortex-M0) |
There was a problem hiding this comment.
I am seeing this style of documenting the first time. Shouldn't this go into some sort of @brief statement?
|
@kaspar030 The bitband accesses to RAM on CM3 is restricted to a part of the address space (0x20000000-0x2xxxxxxx), so it may hardfault on CPUs where some RAM is addressed below 0x20000000, e.g. Kinetis. Also there's the issue of non-atomicity in the generic implementation, if the access is already protected by a lock or disabled IRQs then another call to irq_disable/irq_restore will bloat the code a lot. The CM3 bitband accesses are atomic for free, and the number of CPU cycles for a hardware read-modify-write cycle via bitbanding is the same as for a software read-modify-write. |
37592ab to
5bcbbba
Compare
|
@gebart Ok so we can't make this (easily) generic. I guess then it is fine to merge as is. I'll take last look over the code now. |
| * @param[in] ptr pointer to target word | ||
| * @param[in] bit bit number within the word | ||
| */ | ||
| static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit) |
There was a problem hiding this comment.
Should we rename the functions to bitband_*()?
There was a problem hiding this comment.
I'd rather rename the header bit.h if it is necessary, since bit banding is only one of the implementations
cpu/cortexm_common/include/cpu.h
Outdated
| #include "sched.h" | ||
| #include "thread.h" | ||
| #include "cpu_conf.h" | ||
| #include "bitband.h" |
There was a problem hiding this comment.
Is this include necessary? It does include both ways...
There was a problem hiding this comment.
Convenience or lazy, this makes the big macros immediately available in all files using cpu.h
There was a problem hiding this comment.
but doesn't this contradict the 'import only what is neccessary' thing that has impacts to the build process/speed?!
There was a problem hiding this comment.
addressed, moved include to the consumers
5bcbbba to
0cd14d4
Compare
kaspar030
left a comment
There was a problem hiding this comment.
The bit.h header guard needs fixing. Other than that I'm fine with that header. Can't really test, as I don't have the hardeare...
cpu/cortexm_common/include/bit.h
Outdated
| * @author Joakim Nohlgård <[email protected]> | ||
| */ | ||
|
|
||
| #ifndef BITBAND_H |
There was a problem hiding this comment.
Hm, somehow this file triggers an encoding bug in the headercheck script. I suspect the beautiful a with "a" circle on top in your name. ;)
Unfortunately I cannot reproduce the bug locally.
Anyhow, this define (and the closing endif comment) need to be adapted to the file rename.
dist/tools/headerguards/check.sh | patch -p0 should do that for you.
There was a problem hiding this comment.
updated, the headerguards script worked fine on my machine locally to fix it automatically like you wrote.
|
@gebart please squash! Could anyone with a kinetis do a quick check? |
8a93387 to
35cd5f7
Compare
|
squashed |
35cd5f7 to
a63c0a8
Compare
|
reworded commit msg on kinetis commit |
|
This one looks in good shape: just a test remains. Is there someone with this board who can test ? Otherwise @gebart, can you provide a copy of the output of the uart/timer test applications for the boards you have ? |
IMO a little trust goes a long way here. |
+1. So an ACK would be enough then |
|
ACK. Let's see how long it takes until we want to use |

This PR introduces a new header
bitband.hwhich provides macros for using the bit banding memory region found in Cortex-M3 and above, as well as a fall back for Cortex-M0 and Cortex-M0+ without bit banding.Some Cortex-M0+ devices have their own bit manipulation equivalents, such as the Bit Manipulation Engine in Kinetis M0+ devices. On such CPUs, define
BITBAND_MACROS_PROVIDEDto 1 and provide your own macros.The new macros are named bit_set32, bit_set16, and bit_set8, for setting single bits (i.e. writing a 1), and bit_clear32, bit_clear16, and bit_clear8 for clearing single bits (i.e. writing a 0).
The suffix numbers are the memory access width, some in-cpu modules have 8 bit or 16 bit registers which may require memory accesses to be the correct width to avoid undefined behaviour (Kinetis UART module is one example where using 32 bit access can mess up internal states).
This PR is a prerequisite for an upcoming Kinetis FRDM-KW41z port.