Bit-Banding Updated

May 7th, 2013 5 comments

Last time, I wrote about bit-banding with ARM Cortex-Mx microcontrollers. Although I am not using my BitWord class in my current project, here is an improved, better documented and slightly better tested version of it:

// Copyright Software Integrity Ltd., 2013
#ifndef SWI_BIT_WORD_H
#define SWI_BIT_WORD_H

#include <limits>

namespace SOFTWARE_INTEGRITY
{
    // These constants should really be declared as static members of BitWord,
    // but then I would have to publish the .cpp file as well, to show the
    // definitions.

    static unsigned int * const pBase
        = reinterpret_cast<unsigned int *>(0x20000000U);
    static unsigned int * const pAlias
        = reinterpret_cast<unsigned int *>(0x22000000U);

    // The following assumes that the number of bits in an unsigned int is a
    // power of 2. Actually, we know it is because it's definitely 32 for the
    // Cortex Mx!
    static unsigned int const mask
        = std::numeric_limits<unsigned int>::digits - 1;

    // class BitWord...
    // Allows bit-banded variables of type BitWord to be defined.
    // The individual bits of a BitWord can be read, set and cleared atomically.
    // Implicit Bitword<->unsigned int conversions are supported.
    // The user must ensure that all BitWord objects are actually located in the
    // valid memory bit-band area (0x200xxxxx).
    // This class does not work for the peripheral bit-band area (0x400xxxxx)!
    class BitWord
    {
    public:
        // Constructor, which sets an initial value for the BitWord variable.
        // Also converts from unsigned int to BitWord type.
        BitWord(unsigned int value = 0):
            m_value(value),
            m_pBit(pAlias + ((&m_value - pBase) << 5))
        {
        }

        // Copy constructor.
        BitWord(const BitWord& orig):
            m_value(orig.m_value),
            m_pBit(pAlias + ((&m_value - pBase) << 5))
        {
        }

        // Converts from BitWord to unsigned int.
        operator unsigned int() const volatile
        {
            return m_value;
        }

        // Assignment from BitWord.
        volatile BitWord& operator=(const BitWord& rhs) volatile
        {
            m_value = rhs.m_value;
            return *this;
        }

        // Assignment from unsigned int.
        volatile BitWord& operator=(unsigned int rhs) volatile
        {
            m_value = rhs;
            return *this;
        }

        // Given a bit index, sets that bit in the BitWord.
        // Forces index into valid range first.
        void setBit(unsigned int index) volatile
        {
            index &= mask;
            m_pBit[index] = 1;
        }

        // Given a bit index, clears that bit in the BitWord.
        // Forces index into valid range first.
        void clearBit(unsigned int index) volatile
        {
            index &= mask;
            m_pBit[index] = 0;
        }

        // Given a bit index, reads that bit from the BitWord.
        // Forces index into valid range first.
        unsigned int readBit(unsigned int index) const volatile
        {
            index &= mask;
            return m_pBit[index];
        }

#ifdef  NO_PORTABILITY_ISSUES
        // Beware! Bit-indexing is not easy to re-implement on
        // microcontrollers without bit-banding.

        // Allows indexing of a BitWord object, e.g...
        //      BitWord x, y = 0x5a5a5a5aU;
        //      x[8] = y[3];
        // Forces index into valid range first.
        volatile unsigned int& operator[](unsigned int index) volatile
        {
            index &= mask;
            return m_pBit[index];
        }
#endif

    private:
        // Storage for the word-sized operand.
        volatile unsigned int m_value;

        // The aliased base address of m_value.
        volatile unsigned int * const m_pBit;
    };
}

#endif // SWI_BIT_WORD
Categories: ARM Cortex-M3, C/C++ Tags: ,

ARM Cortex Bit-Banding in C++

March 4th, 2013 1 comment

It has been a long time since I posted, so I’m posting this very technical article just to get into the swing of it again.

On LinkedIn (Cortex-M Programmers’s group) I started a discussion about accessing the bit-banding features present in many ARM Cortex-M3 chips, using C++. If you don’t know what I’m talking about, look away now! Read more…

Categories: ARM Cortex-M3, C/C++ Tags: ,

Slides from Embedded Masterclass 2012

July 16th, 2012 2 comments

The slides from my workshop “Robust Concurrent Programming in C++” at the recent Embedded Masterclass in Cambridge are available here:

Embedded Masterclass 2012 SWI Workshop Slides

Please note that there were also some hands-on exercises during the workshop, to which the slides refer. However, the source code for these exercises, and their solutions, is not publicly available. If you attended the workshop and have lost the code, or you have some other reason to want it, please contact me by email.

I also presented a short talk, “Programming small systems in C++“, at the event. The slides for this are available here:

Embedded Masterclass 2012 SWI Talk Slides

 

Categories: No Category Tags:

Embedded Masterclass, Cambridge, UK, 27/06/12

June 11th, 2012 2 comments

I will be presenting a Workshop – Robust Concurrent Programming in C++ – at this year’s Embedded Masterclass Read more…

Categories: News Tags:

Dynamic Memory Software Updated

February 29th, 2012 No comments

After a bit of a lull, I have resumed work in earnest on what will become, I hope, a useful and fairly comprehensive C++ software library for embedded and real-time developers. To begin with, I am updating the Dynamic Memory Classes which I first published on this blog about two years ago. The first instalment – the “Pooled” class and its ancillaries – is now available for subscribers to download. Just go to the Subscribers page and follow the guidance there in order to get hold of the software. Read more…

WCP: How does your software stack up?

October 18th, 2011 2 comments

When we link our programs together, the success of the operation reassures us that all our code and our static and global(?!) variables fit into the available memory. But what about the function parameters, the local variables and various other unknowns which go on the stack?

When someone mentions dynamic memory allocation, the worst-casers amongst us – which should be all of us – immediately start ranting against heap allocation and advocating either the somewhat safer use of fixed-size-block pools, or the ostensibly even safer but often design-compromising measure of banning of dynamic allocation altogether. But heaps and pools I’ve covered before on this blog. What we all tend to brush under the carpet is the admission that the implicit use of the stack in all our programming (in C and C++ at least) is also dynamic allocation and deserves much more careful consideration than we tend to give it. Read more…

Categories: Software Design Tags: ,

ARM Cortex PendSV problem & solution(?)

September 27th, 2011 1 comment

Anyone using PendSV on Cortex (e.g. to implement an RTOS scheduler) should read this!

[Edited 29/09/11] It appears that there may or may not be a problem; the argument continues on the Embedded Gurus blog. If you’re tinkering with PendSV, it would be good to read the article (and the comments to it) anyway.

 

Categories: No Category Tags:

WCP: Uncertain Times…

September 20th, 2011 1 comment

Timing issues are often important in systems containing software but, ultimately, all timing is determined by hardware. Let’s pursue this by splitting a hypothetical system into (1) the software we’re designing and (2) the platform it’s intended to run on. We also need to consider (3) the toolchain. To be a little more precise: Read more…

Categories: Software Design Tags: ,

WCP: The Worst Case Principle

September 8th, 2011 No comments

My last article, Whatever Happened to the Worst Case?, was a bit of a rant but it promised further articles on the subject. This is the first of these, which does no more than describe what I mean by the “Worst Case Principle”, or WCP. I am using WCP as both a label in the title and as a tag to identify each of the articles. The series is intended to provoke thought, not to be a complete treatise on designing robust software. That would fill a whole book – at least! Read more…

Categories: Software Design Tags: ,

Whatever Happened to the Worst Case?

August 25th, 2011 6 comments

I’m dismayed about sloppy attitudes to design. I suspect they’re creeping across from consumer-focused software, where raw average speed is everything and an occasional glitch doesn’t matter. Well, I’m sorry, but as that kind of thinking creeps towards the vehicles I may travel in, or possibly the new nuclear power plant to be commissioned up the road from here, I feel the need to voice my concerns. Read more…

Categories: Software Design Tags: ,