cortex m3, stm32L1XX bit-banding - c++

I'm following the guide given at micromouseonline . com/2010/07/14/bit-banding-in-the-stm32 . I'm using IAR EWARM and Cortex M3. Everything works fine but I'm not able to set the bits in a given address. Im using STM32L151xD and IAR EWARM compiler.
This is how they define the functions
#define RAM_BASE 0x20000000
#define RAM_BB_BASE 0x22000000
#define Var_ResetBit_BB(VarAddr, BitNumber) (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)) = 0)
#define Var_SetBit_BB(VarAddr, BitNumber) (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)) = 1)
#define Var_GetBit_BB(VarAddr, BitNumber) (*(vu32 *) (RAM_BB_BASE | ((VarAddr - RAM_BASE) << 5) | ((BitNumber) << 2)))
#define varSetBit(var,bit) (Var_SetBit_BB((u32)&var,bit))
#define varGetBit(var,bit) (Var_GetBit_BB((u32)&var,bit))
the call is :
uint32_t flags;
varSetBit(flags,1);
however, the bit 1 in flags is always 0 if I see using a debugger. The flags is assumed to be 0 at first. So, all the bits in flags will be 0. However, when i use varSetBit(flags,1), the answer at bit 1 is 0 again. I dont think im doing anything wrong. Is it a compiler problem? am i missing some settings? Any help will be appreciated.

I suspect that you misunderstand the purpose of the bit-banding feature.
With bit-banding, the application have access (read/write) to the micro-controller's registers bit by bit. This allows modifying a bit with a single store instruction instead of a read/modify/write sequence. For this to work, stm32 devices (or more generally Cortex M3 devices) have a specific address space where each bit of each register is mapped to a specific address.
Let's take an example, if you need to set the bit 3 of the register FOO:
Without bit-banding, you would have to write the following code:
FOO = FOO | 0b100;
This results from the assembler instructions in a load of the register FOO, a bit-wise OR operation and a store of the register FOO.
With bit-banding, you write:
varSetBit(FOO, 3);
which results to a simple store at the address computed by preprocessor from the varSetBit macro.
Now that is said, bit-banding only apply to the micro-controller's register. You can't use them to manipulate bits of your own variables as you do with your flags variable.
For more information read the ARM application note

Related

How are state flags represented and how bitwise OR is used to work with bit flags?

If we open a file for reading, we may define one or more state flags,
for example: ios::out as well as ios::out | iso::app
I read about the bitwise OR, and how it "merges" the two bit sets,
for example: 1010 | 0111 = 1111
now that being said, I do not understand how it works "behind the scenes" when we use a method like ifstream.open(filename, stateflagA | stateflagB | stateflagC) and so on.
Can someone elaborate more on the inner workings of these state flags and their memory representation?
EDIT:
To give more emphasis on what i am trying to understand (if it helps),
I would assume that the open method could receive one or more state flags as separate arguments in the signature, and not delimited by a bitwise OR, so i want to understand how the bitwise OR works on these state flags to produce a different final state when combining several flags, and as a result allows me to use only one argument for a state flag or a set of state flags.
ie:
ifstream.open(filename, stateflagA | stateflagB | stateflagC)
and NOT
ifstream.open(filename, stateflagA , stateflagB , stateflagC)
Bit flags are represented in the same exact way all integral values are represented. What makes them "flags" is your program's interpretation of their values.
Bit flags are used for compact representation of small sets of values. Each value is assigned a bit index. All integer numbers with the bit at that index set to 1 are interpreted as sets that include the corresponding member.
Consider a small example: let's say we need to represent a set of three colors - red, green, and blue. We assign red an index of zero, green and index of 1, and blue an index of two. This corresponds to the following representation:
BINARY DECIMAL COLOR
------ ------- -----
001 1 Red
010 2 Green
100 4 Blue
Note that each flag is a power of two. That's the property of binary numbers that have a single bit set to 1. Here is how it would look in C++:
enum Color {
Red = 1 << 0
, Green = 1 << 1
, Blue = 1 << 2
};
1 << n is the standard way of constructing an integer with a single bit at position n set to 1.
With this representation in hand we can construct sets that have any combination of these colors:
BINARY DECIMAL COLOR
------ ------- -----
001 1 Red
010 2 Green
011 3 Red+Green
100 4 Blue
101 5 Blue+Red
110 6 Blue+Green
111 7 Blue+Green+Red
Here is when bit operations come into play: we can use them to construct sets and check membership in a single operation.
For example, we can construct a set of Red and Blue with an | like this:
Color purple = Red | Blue;
Behind the scenes, all this does is assigning 5 to purple, because 4 | 1 is 5. But since your program interprets 5 as a set of two colors, the meaning of that 5 is not the same as that of an integer 5 that represents, say, the number of things in a bag.
You can check if a set has a particular member by applying & to it:
if (purple & Red) {
// returns true
}
if (purple & Green) {
// returns false
}
The flags used by I/O library work in the same way. Some of the flags are combined to produce bit masks. They work in the same way as individual flags, but instead of letting you find membership they let you find set intersection in a single bit operation:
Color yellow = Blue | Green;
Color purple = Red | Blue;
Color common = yellow & purple; // common == Blue
If we take the GNU libstdc++ implementation and look at how these are actually implemented, we find:
enum _Ios_Openmode
{
_S_app = 1L << 0,
_S_ate = 1L << 1,
_S_bin = 1L << 2,
_S_in = 1L << 3,
_S_out = 1L << 4,
_S_trunc = 1L << 5,
_S_ios_openmode_end = 1L << 16
};
These values are then used as this:
typedef _Ios_Openmode openmode;
static const openmode app = _S_app;
/// Open and seek to end immediately after opening.
static const openmode ate = _S_ate;
/// Perform input and output in binary mode (as opposed to text mode).
/// This is probably not what you think it is; see
/// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch27s02.html
static const openmode binary = _S_bin;
/// Open for input. Default for #c ifstream and fstream.
static const openmode in = _S_in;
/// Open for output. Default for #c ofstream and fstream.
static const openmode out = _S_out;
/// Open for input. Default for #c ofstream.
static const openmode trunc = _S_trunc;
Since the values are chosen as 1 << n, they are exactly one "bit" each, which allows us to combine then using | (or) - as well as other similar operations.
So app in binary is 0000 0001 and bin is 0000 0100, so if we do app | bin as a mode for opening the file, we get 0000 0101. The internals of the impplementation of fstream can then use
if (mode & bin) ... do stuff for binary file ...
and
if (mode & app) ... do stuff for appending to the file ...
Other C++ library implementations may choose a different set of bit values for each flag, but will use a similar system.
"Behind the scene", in the memory of the computer every information is ultimately coded as a group of bits. Your CPU is wired to perform basic binary algebra operations (AND, OR, XOR, NOT) on such elementary information.
C++ operators | & and ^ just give direct access to these CPU operations on any integral types. For flag management it's wise to use an unsigned integral type such as unsigned int or unsigned char.
An express overview:
the trick is that every flag corresponds to a fixed bit. This is usually done with a power of 2 constant (ex: 1,2,4,8 which are binary coded as 0001,0010, 0100 and 1000).
constants are named because it's clearer than using litterals (ex: const unsigned FlagA=1, FlagB=2, FlagC=4;)
binary AND x & y ensures that only bits that are 1 in both x and y remain 1. So this is used to reset flags by "anding" with a value where the flag is 0. So x & FlagB reset all flags exept flag B
binary OR x | y any bits that are 1 either in x or y become 1. So it's used to set flags. Example: x | FlagB sets the flag B.
a binary AND is also a quick way to check if a flag is set: (x & FlagB) will be true if and only if the flag B was set.
EDIT: About your specific question on ifstream::open() parameters: it's a design choice, for convenience. As you can see there are 6 flags that influence the way the file is handled (some of them being used very rarely). So instead of providing each of the 6 flags every time, the standard decide that you'd provide them combined in an openmode. Variable number of arguments would not have been an alternative, as the called function would have to know how many arguments you've provided.

How to implement bit vectors with bitwise operations?

I am studying a question in the book Programming Pearls, and they recommended this function to set a bit in a bit vector. I'm a bit confused at to what it does.
#define BITSPERWORD 32
#define MASK 0x1F
#define SHIFT 5
#define N 1000000
int a[1 + N/BITSPERWORD];
void set(int i){
a[i >> SHIFT] |= (1 << (i & MASK));
}
Here is my (probably wrong) interpretation of this code.
if i = 64,
1) first, it takes i and shifts it to the right by SHIFT (which is 5) bits. This is equivalent to DIVIDING (not multiplying, as I first thought) i by 2^5. So if i is 64, the index of a is 2 (64 / 2^5)
2) a[2] |= (1 << (64 & MASK))
64 & 1 = 1000000 & 01 = 1000001.
So 1 gets left shifted how many bits????
It seems how this method works, even though I feel like there are better ways to set a bit. Is to find the index of the ith bit it essentially divides by 32 because that is the number of bits per word.
Since the operator used here is | the function is setting the bit to one not toggling the bit
0x1F is actually 31 and when anded with the i you get the remainder (not sure why they just didn't use %)
And lastly the shift takes the 1 to the proper location and or's it with the right slot in the vector.
If you are planning to use this code
you could write it a lot clear without defines and using more obvious methods of doing it, I doubt it would make a difference in speed.
Also you should probably just use std::bitset
the use of the mask to get the remainder particularly annoyed me because I'm pretty sure it would not necessarily work for every number, 31 happens to work because it's all 1's

logical operations between chunks of memory?

I want to or two big chunks of memory... but it doesn't work
Consider I have three char * bm, bm_old, and bm_res.
#define to_uint64(buffer,n) {(uint64_t)buffer[n] << 56 | (uint64_t)buffer[n+1] << 48 | (uint64_t)buffer[n+2] << 40 | (uint64_t)buffer[n+3] << 32 | (uint64_t) buffer[n+4] << 24 | (uint64_t)buffer[n+5] << 16 | (uint64_t)buffer[n+6] << 8 | (uint64_t)buffer[n+7];}
...
for (unsigned int i=0; i<bitmapsize(size)/8; i++){
uint64_t or_res = (to_uint64(bm_old,i*8)) | (to_uint64(bm,i*8));
memcpy(bm_res+i*sizeof(uint64_t), &or_res, sizeof(uint64_t));
}
bm_res is not correct!
Have any clue?
Thanks,
Amir.
Enclose the definition of to_uint64 in parentheses () instead of braces {} and get rid of the semicolon at the end. Using #define creates a macro whose text is inserted verbatim wherever it's used, not an actual function, so you were attempting to |-together two blocks rather than those blocks' "return values."
I think you need to advance your output pointer by the correct size:
memcpy(bm_res + i * sizeof(uint64_t), &or_res, sizeof(uint64_t));
^^^^^^^^^^^^^^^^^^^^
Since bm_res is a char-pointer, + 1 advances by just one byte.
You're incrementing bm_res by one for every eight-byte block you move. Further, you never increment bm or bm_old at all. So you're basically tiling the first byte of or_res over bm_res, which is probably not what you want.
More importantly, your code is byte-order sensitive - whether or_res is represented in memory as least-order-byte first or highest-order-byte first matters.
I would recommend you just do a byte-by-byte or first, and only try to optimize it if that is too slow. When you do optimize it, don't use your crazy to_uint64 macro there - it'll be slower than just going byte-by-byte. Instead, cast to uint64_t * directly. While this is, strictly speaking, undefined behavior, it works on every platform I've ever seen, and should be byteorder agnostic.

What does "variable|variable" mean in C++?

I was looking into this ITE8712 watchdog timer demo code when I saw this:
void InitWD(char cSetWatchDogUnit, char cSetTriggerSignal)
{
OpenIoConfig(); //open super IO of configuration for Super I/O
SelectIoDevice(0x07); //select device7
//set watch dog counter of unit
WriteIoCR(0x72, cSetWatchDogUnit|cSetTriggerSignal);
//CloseIoConfig(); //close super IO of configuration for Super I/O
}
and, I wonder what is meant by this line:
cSetWatchDogUnit|cSetTriggerSignal
because the WriteIoCR function looks like this:
void WriteIoCR(char cIndex, char cData)
{
//super IO of index port for Super I/O
//select super IO of index register for Super I/O
outportb(equIndexPort,cIndex);
//super IO of data for Super I/O
//write data to data register
outportb(equDataPort,cData);
}
So cIndex should be 0x72, but what about the cData? I really don't get the "|" thing as I've only used it for OR ("||") in a conditional statement.
It's a bitwise or, as distinct to your normal logical or. It basically sets the bits in the target variable if the corresponding bit in either of the source variables was set.
For example, the expression 43 | 17 can be calculated as:
43 = 0x2b = binary 0010 1011
17 = 0x11 = binary 0001 0001
==== ====
"or" them: 0011 1011 = 0x3b = 59
See this answer for a more thorough examination of the various bitwise operators.
It's typically used when you want to manipulate specific bits within a data type, such as control of a watchdog timer in an embedded system (your particular use case).
You can use or (|) to turn bits on and and (&) to turn them off (with the inversion of the bitmask that's used to turn them on.
So, to turn on the b3 bit, use:
val = val | 0x08; // 0000 1000
To turn it off, use:
val = val & 0xf7; // 1111 0111
To detect if b3 is currently set, use:
if ((val & 0x08) != 0) {
// it is set.
}
You'll typically see the bitmasks defined something like:
#define B0 0x01
#define B1 0x02
#define B2 0x04
#define B3 0x08
#define B4 0x10
or:
enum BitMask {
B0 = 0x01,
B1 = 0x02,
B2 = 0x04,
B3 = 0x08,
B4 = 0x10
};
As to what this means:
WriteIoCR (0x72, cSetWatchDogUnit|cSetTriggerSignal);
More than likely, 0x72 will be an I/O port of some sort that you're writing to and cSetWatchDogUnit and cSetTriggerSignal will be bitmasks that you combine to output the command (set the trigger signal and use a unit value for the watchdog). What that command means in practice can be inferred but you're safer referring to the documentation for the watchdog circuitry itself.
And, on the off chance that you don't know what a watchdog circuit is for, it's a simple circuit that, if you don't kick it often enough (with another command), it will reset your system, probably by activating the reset pin on whatever processor you're using.
It's a way to detect badly behaving software automatically and return a device to a known initial state, subscribing to the theory that it's better to reboot than continue executing badly.
That's a bitwise or.
It is used here to combine flags.
x | y is generally used with Plain Old Datas in C/C++. It means bitwise OR.
e.g.
char x = 0x1, y = 0x2;
x | y ==> 0x3
[Note: operator | can be overloaded for class/struct according to your need.]
| is a bitwise or. It toggles the bits on (1 instead of 0) if one OR the other of the same bit in either integer is on.
|| is the logical or. It returns true if one OR the other are true.
OK, here's why you use a bitwise or, or see them used, in this sort of situation.
Often times, those variables are flags that are used to pack multiple pieces of data into one char
If cSetWatchDogUnit and
cSetTriggerSignal
have non-overlapping bits (imagine cSetWatchDogUnit = 1 << 0 and cSetTriggerSignal = 1 << 1 you can check later to see if they are set with a bitwise and, like this contrived example:
if cData & cSetWatchDogUnit
do something
if cData & cSetTriggerSignal
do something else
The whole time, both of these flags can be packed into and passed around in a single char. That way, you don't end up passing an array of bools, you can add new constants cSetSomeOtherDamnfoolThing = 1 << 2 and you can refer to flags as variables in your code.

Doing 64 bit manipulation using 32 bit data in Fixed point arithmetic using C

I am stuck with a problem. I am working on a hardware which only does support 32 bit operations.
sizeof(int64_t) is 4. Sizeof(int) is 4.
and I am porting an application which assumes size of int64_t to be 8 bytes. The problem is it has this macro
BIG_MULL(a,b) ( (int64_t)(a) * (int64_t)(b) >> 23)
The result is always a 32 bit integer but since my system doesn't support 64 bit operation, it always return me the LSB of the operation, rounding of all the results making my system crash.
Can someone help me out?
Regards,
Vikas Gupta
You simply cannot reliably store 64 bits of data in a 32-bit integer. You either have to redesign the software to work with 32-bit integers as the maximum size available or provide a way of providing 64 bits of storage for the 64-bit integers. Neither is simple - to be polite about it.
One possibility - not an easy one - is to create a structure:
typedef struct { uint32_t msw; uint32_t lsw; } INT64_t;
You can then store the data in the two 32-bit integers, and do arithmetic with components of the structure. Of course, in general, a 32-bit by 32-bit multiply produces a 64-bit answer; to do full multiplication without overflowing, you may be forced to store 4 16-bit unsigned numbers (because 16-bit numbers can be multiplied to give 32-bit results w/o overflowing). You will use functions to do the hard work - so the macro becomes a call to a function that accepts two (pointers to?) the INT64_t structure and returns one.
It won't be as fast as before...but it has some chance of working if they used the macros everywhere that was necessary.
I assume that the numbers that you are trying to multiply together are 32-bit integers. You just want to generate a product that may be larger than 32 bits. You then want to drop some known number of least significant bits from the product.
As a start, this will multiply the two integers together and overflow.
#define WORD_MASK ((1<<16) - 1)
#define LOW_WORD(x) (x & WORD_MASK)
#define HIGH_WORD(x) ((x & (WORD_MASK<<16)) >> 16)
#define BIG_MULL(a, b) \
((LOW_WORD(a) * LOW_WORD(b)) << 0) + \
((LOW_WORD(a) * HIGH_WORD(b)) << 16) + \
((HIGH_WORD(a) * LOW_WORD(b)) << 16) + \
((HIGH_WORD(a) * HIGH_WORD(b)) << 32)
If you want to drop the 23 least-significant bits from this, you could adjust it like so.
#define WORD_MASK ((1<<16) - 1)
#define LOW_WORD(x) (x & WORD_MASK)
#define HIGH_WORD(x) ((x & (WORD_MASK<<16)) >> 16)
#define BIG_MULL(a, b) \
((LOW_WORD(a) * HIGH_WORD(b)) >> 7) + \
((HIGH_WORD(a) * LOW_WORD(b)) >> 7) + \
((HIGH_WORD(a) * HIGH_WORD(b)) << 9)
Note that this will still overflow if the actual product of the multiplication is greater than 41 (=64-23) bits.
Update:
I have adjusted the code to handle signed integers.
#define LOW_WORD(x) (((x) << 16) >> 16)
#define HIGH_WORD(x) ((x) >> 16)
#define ABS(x) (((x) >= 0) ? (x) : -(x))
#define SIGN(x) (((x) >= 0) ? 1 : -1)
#define UNSIGNED_BIG_MULT(a, b) \
(((LOW_WORD((a)) * HIGH_WORD((b))) >> 7) + \
((HIGH_WORD((a)) * LOW_WORD((b))) >> 7) + \
((HIGH_WORD((a)) * HIGH_WORD((b))) << 9))
#define BIG_MULT(a, b) \
(UNSIGNED_BIG_MULT(ABS((a)), ABS((b))) * \
SIGN((a)) * \
SIGN((b)))
If you change your macro to
#define BIG_MULL(a,b) ( (int64_t)(a) * (int64_t)(b))
since it looks like int64_t is defined for you it should work
While there are other questions raised by sizeof(int64_t) == 4, this is wrong:
#define BIG_MULL(a,b) ( (int64_t)(a) * (int64_t)(b) >> 23)
The standard requires intN_t types for values of N = 8, 16, 32, and 64... if the platform supports them.
The type you should use is intmax_t, which is defined to be the largest integral type the platform supports. If your platform doesn't have 64-bit integers, your code won't break with intmax_t.
You might want to look at a bignum library such as GNU GMP. In one sense a bignum library is overkill, since they typically support arbitrary sized numbers, not just a increased in fixed size numbers. However, since it's already done, the fact that it does more than you want might not be an issue.
The alternative is to pack a couple 32-bit ints into a struct similar to Microsoft's LARGE_INTEGER:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
And create functions that take parameters of this type and return results in structs of this type. You could also wrap these operations in a C++ class that will let you define operator overloads that let the expressions look more natural. But I'd look at the already made libraries (like GMP) to see if they can be used - it may save you a lot of work.
I just hope you don't need to implement division using structures like this in straight C - it's painful and runs slow.