Check if N(large) bits are set - c

I want to check if any of the 1024 bits (128 bytes) are set. If all are clear, then I want to do something. Is it possible to do this quickly, i.e one instruction or do I have to loop through my bitmap?

As i have understood the questions, you want to check if any of the bit is set out of 1024 bits you have.
Assuming you are on 64 bit machine.
store the bits as array of unit64_t type which is 8 bytes.
So you have array of this kind.
uint64_t bits[16] = {0}; // 1024 bits
and to check your bit condition
for(int i = 0, j=0; i < 16; i++){
if(bits[i]) {
return FAIL_CONDITION;
}
}
return SUCCESS_CONDITION;

Check whether any data is non zero.
Let buffer be the data you want to check,
int n=128;
unsigned char *buffer = &data;
for(int i=0 ;i<n ; i++) {
if((*data)) { //If data is non zero any of the bit in the data is
// set, so quit from iterating.
break;
}
data++;
}

Related

C: Read values of entire flash memory of MCU

I want to read the values of the memory locations of the entire program flash memory of an MCU, in particular, the CC2538 on the OpenMote-CC2538. The read values are then computed into, currently, a large sum of all the values.
At this moment, I have the following code working to traverse the memory and get the values
uint64_t readMemory() {
unsigned char * bytes = (char *) 0x200000;
size_t size = 0x0007FFD4;
size_t i;
uint64_t amount = 0;
for (i = 0; i < size; i++) {
amount += bytes[i];
}
return amount;
}
uint64_t readFlashMemory() {
unsigned int * bytes = (int *) 0x200000;
size_t size = 0x0007FFD4;
size_t i;
uint64_t amount = 0;
for (i = 0; i < size; i+=4) {
amount += FlashGet(bytes);
bytes++;
}
return amount;
}
address 0x200000 and its size is 0x0007FFD4. The first function works with a char and goes to each address one by one, while the second one uses an existing function FlashGet(uint32_t) from the flash.c file, which is a direct access to a register (HWREG).
FlashGet requires a uint32_t address and returns a uint32_t value, as such it has a length of 4 and the address should be moved with 4 in the loop .The first function uses char for the addressing, which is a length of 1 and so the address should also move by 1 in the loop. Am I correct in these statements? If so, am I executing them correctly? For the second function, incrementing the pointer with 1 should move it with 4 due to it being of type uint32_t (similar to int).
However, the functions return a different value.
The first one returns: 674426297757
The second one returns: 8213668631160
As both functions should be doing the same, one or both must be incorrect and is not reading the entire program flash memory.
How can I fix both functions? Is there a better or easier way to read the entire memory when you have the starting address and size?
Consider you have a 4-byte flash memory with content
00 01 02 03
Adding by byte values will give you 0x000000000000006
Adding by 32-bit int values will give you 0x0000000003020100 assuming little-endian.

Storing the lowest level bits and returning a char

I'm working on an assignment that decodes a secret message stored in a PPM format picture. The first thing i need to do is find the length of the message, which is hidden in a single byte spread across the first 8 data bytes of the picture. After I have this, my logic is to create a method where I have a loop that shifts the bits 7 spots, records the first one, and when there are 8 bits, return the char that they represent.
So right now I'm trying to understand how this would work.
I was trying to get the value for the length of the hidden message.
I tried to do this manually to see how all the bits behaved.
fgets(str,64,fp);
char length[7];
length[0] = str[7];
length[1] = str[15];
length[2] = str[23];
length[3] = str[31];
length[4] = str[39];
length[5] = str[47];
length[6] = str[55];
length[7] = str[63];
printf(length);
So since the length is hidden in the lowest level bit of 8 bytes i used fgets(str,64,fp); and then stored each 8th value in an array. This returns "enpm0dp".
When I changed the array to int, the output was an arrow.
Can someone explain to me how to store bits into a byte and then return the char that corresponds to this value? Do i use an array of 8 bits? or store them in a string?
You seem to think that fgets() counts length in bits (64 for 8 bytes), but it really doesn't; it counts in characters. See the documentation.
Next, you seem to think that str is ana rray of bits, but arrays of bits don't exist like that in C.
You're going to have to consider an array of characters, which we'll assume is bytes:
unsigned char str[8];
if(fgets(str, sizeof str, fp))
{
unsigned char length = 0, i;
for(i = 0; i < sizeof str; ++i)
{
length >>= 1;
length |= str[i] & 0x80;
}
}

Processing Array Data

I have an issue with passing data between arrays for processing that I can't seem to iron out. (I'm running the code on a Nios II processor)
HAL Type Definitions:
alt_u8 : Unsigned 8-bit integer.
alt_u32 : Unsigned 32-bit integer.
The core in my FPGA takes in a 128 bits at a time for data processing. I have this working in my original code by passing 4 x 32 bit unsigned int to the function:
alt_u32 load[4] = {0x10101010, 0x10101010, 0x10101010, 0x10101010};
The function processes this data and using another array I retrieve the info.
data_setload(&context,&load); //load data
data_process(&context); //process
memcpy(resultdata,context.result,4*sizeof(unsigned int));
for(i=0; i<4 ; i++){
printf("received 0x%X \n",resultdata[i]); //print to screen
}
Above works perfectly, but when I try combine it with the second part it does not work.
I have a buffer used to store data:
alt_u8 rbuf[512];
When the data buffer becomes full I'm trying to transfer the contents of 'rbuf' to the array 'load'. The main problem is load[4] takes 4 by 32 bit unsigned int for processing. So I want to 'fill up' these 4 by 32 bit unsigned int with data from rbuf, process the data and save the result to an array. Then loop again and fill the array load[4] with the next set of data (from rbuf) and continue until rbuf is empty. (and pad with zeros if necessary)
alt_u8 rbuf[512];
alt_u8 store[512];
alt_u32 resultdata[512];
alt_u32 *reg;
int d, k, j;
for (j=0; j<512; j++){
read_byte(&ch); //gets data
rbuf[j]=ch; //stores to array rbuf
}
printf(" rbuf is full \n");
memcpy(store,rbuf,512*sizeof(alt_u8)); //store gets the value in rbuf.
for(k=0;k<16;k++) //for loop used take in 4 chars to one unsigned 32 bit int
{
for(d=0;d<4;d++) //store 4 chars into an one 32 bit unsigned int
{
*reg = (*reg<<8 | store[d]) ;
}
reg =+1; //increment pointer to next address location(not working properly)
} //loop back
reg = 0; //set pointer address back to 0
for(j=0;j<16;j++) //trying to process data from here
{
memcpy(load,reg,4*sizeof(alt_u32)); //copy first 4 locations from 'reg' to 'load'
data_setload(&context,&load); //pass 'load' to function
data_process(&context); //process 128 bits
memcpy(resultdata,context.result,4*sizeof(alt_u32)); //results copied to 'resultdata'
*reg = *reg + 4; //increment pointer address by 4?
*resultdata = *resultdata+4; //increment resultdata address by 4 and loop again
}
/** need to put data back in char form for displaying***/
for(k=0;k<16;k++) //for loop used take chars from 32 unsigned int
{
for(d=4;d>=0;d--) //loads 4 chars FROM A 32 unsigned int
{
store[d] = *resultdata;
*resultdata = *resultdata>>8;
}
resultdata =+1; //increment pointer next address location
}
for(d=0; d<512 ; d++){
printf("received 0x%X ",store[d]);
The end goal is to take:
Array_A of unsigned 8 bit copy it into an Array_B[4] of unsigned 32 bit >> Process the Array_B[4] with my HDL code. It requires the input to be 128bits.
Then loop back and take the next 128 bits and process them.
reg is defined but not initialized, so it will be a null pointer and you are triying to write a value to it (*reg assigns value, reg assigns address).
Also, the k-d loop is wrong. If you got reg initialized correctly, then a really easy way to do that is:
for(k=0;k<16;k += 4) //for loop used take chars from 32 unsigned int
{
*rbuf = *((alt_u32*)&store[k]);
rbuf++;
}
that loop will take the four intengers stored as bytes in the beginning of store and copies them to where rbuf is pointing.
I'm nearly shure that's not what you want to achieve, but is what your code was trying to do. If you want to fully copy the store to where rbuf points then you can do this:
for(k=0;k<512;k += 4) //for loop used take chars from 32 unsigned int
{
*rbuf = *((alt_u32*)&store[k]);
rbuf++;
}
That will copy all the values stored at store to rbuf.
Also, a better, faster, and cleaner way:
memcpy(rbuf, &store, 512);
rbuf += 512 / sizeof(alt_u32);
Finally, if you just want to fill load with the first four integers, then you can do that:
for(k = 0; k < 4; k++)
{
load[k] = *((alt_u32*)&rbuf[k * 4]);
}
or
memcpy(&load, &rbuf, 4 * sizeof(alt_u32));
then you don't need store for noting.
Finally, here is a full rewriten function with the minimum memory usage and best performance:
alt_u8 rbuf[512];
alt_u32 resultdata[128]; //fixed its size to 128, (512 / sizeof(alt_u32))
int j;
//Do the loop to load data in rbuf
for (j=0; j<512; j++)
read_byte(&rbuf[j]);
printf(" rbuf is full \n");
//Loop through rbuf in 4 * 32 bits per iteration (4*4 bytes)
for(j = 0; j < 512; j+= sizeof(alt_u32) * 4)
{
data_setload(&context, (alt_u32*)&rbuf[j]); //I assume this function expects an alt_u32 pointer to 4 alt_u32 values
data_process(&context);
memcpy(&resultdata[j / sizeof(alt_u32)], context.result, sizeof(alt_u32) * 4);//I assume context.result is a pointer, if not then add & before it
}
//Print received data
for(j=0; j<512 ; j++){
printf("received 0x%X ",rbuf[d]);

Why does memset put a wrong value?

I'm trying to fill zero regions in a matrix using memset() in this way:
unsigned short *ptr;
for(int i=0; i < nRows; ++i)
{
ptr = DepthMat.ptr<unsigned short>(i); /* OCV matrix of uint16 values */
for(int j=0; j<nCols; ++j)
{
uint n=0;
if(ptr[j] == 0) /* zero region found */
{
d_val = ptr[j-1]; /* saves last non-zero value */
while(ptr[j+n] == 0)
{ /* looks for non zero */
++n;
}
d_val = (d_val < ptr[j+n] ? d_val : ptr[j+n]);
memset( ptr+j, d_val, n*sizeof( ptr[0]) );
j += n;
}
}
}
I look for sequences of zero, then I store the positions (ptr+j-1 and ptr+j+n) and the values of the zero regions boundaries, and finally I use memset() to replace the zeros with d_val.
The problem is that when I check the values stored they don't match with d_val, for example, I put the value '222' but I get '57054'.
Any clue?
The value argument to memset() is only a single byte, even though the type for the argument is int.
The manual page describes the function as:
memset - fill memory with a constant byte
So, no more than the least-significant 8 bits of d_val will be written to memory. Since you're treating the memory as an array of short, you get "mangled" values that consist of the same byte repeated through the bytes of the short.
In ... short, don't do this; use a for loop to do a repeated write of actual shorts.
memset writes one char at a time, while you're accessing them as short. 57054 = 222*256+222

C - converting to 2s complement

I've decided to do it this way
flip numbers 0=1, 1=0
add 1 to LSB
if carry, loop until array[i]==0
But I'm stuck on the last point; how can I say that in a conditional loop?
You are talking about extended arithmetic. Most processors have carry-out and overflow results from every addition operation, but C does not provide access to them.
Your problem is that numbers get longer as they get bigger. If you're at the last bit you have, and you need to carry out, you need another bit! That means you need to reallocate the array of bits (if you are using an array).
Of course, a more practical solution is to use native integers rather than individual bits, since your processor already handles two's-complement quite nicely. Then, you know that adding one results in a carry-out if the original number is equal to (unsigned) -1. The fundamental problem remains; if you need to carry out of the last unsigned you need to allocate another.
So you you store your number as an array of ints, which represent bits.
In the code example you attached you forgot to increment the i variable, and to check if it exceeded the size of your array.
You could write something like this (I assume the size of the array is 5):
for (i = 0; i < 5; i++)
{
if (array1[i] == 1)
array1[i] = 0;
else // we found a 0
array1[i] = 1;
break;
}
I'm not quite sure what you're doing, but maybe this will help:
#define countof(x) (sizeof(x) / sizeof(x[0]))
// an 8-bit number
int byte[8] = {0, 1, 1, 0, 1, 1, 1, 0}; // 1 = on, 0 = off
// flip all bits
for (size_t i = 0; i < countof(byte); ++i)
{
byte[i] = !byte[i];
}
// add one
for (size_t i = 0; i < countof(byte); ++i)
{
if (byte[i]) // if on
{
byte[i] = 0; // "add 1, reset to zero", and carry (no break)
}
else // if off
{
byte[i] = 1; // turn on
break; // nothing to carry, stop adding
}
}
(I don't know how to push you in the right direction without just explaining the code, sorry. I think you're close enough this is still helpful.)
You see, when you add one, if the bit is already one, reset it to zero, and continue along the bits. If the bit is zero, set it to one, then break out of the loop. (Nothing to carry, so we're done adding.)
Hope that helps. By the way, you'll note the bits are being stored "backwards" in the code above. The LSB is at index 0.
You can do 2's complement in a much easier way like bellow:
go unchanged till you find an 1.
just after getting the first 1, flip the next coming 0's to 1 and 1's to Zeros and continue doing this. if the MSB becomes 0, it means overflow occurred.
you can check the validity of the algorithm by yourself. and the implementation should be like bellow:
// an 8-bit number
int number[8] = {0, 1, 1, 1, 0, 1, 0, 0};
int i;
bool gotFirstOne = false;
// flip bits after you first encountered an 1
for (i = 0; i < 8; i++)
{
if(gotFirstOne == false){
if(number[i] == 1) {
gotFirstOne = true;
}
}
else {
number[i] = !number[i];
}
}
if(number[7] == 0) {
printf("Overflow occurred");
}
Cheers!!!!
My Answer to 2's complement, remember this is for 12 bit complement, you can change mask or integer type as per your requirement. This is working perfectly, also can do it using a Macro.
int twos_compliment(unsigned short a)
{
int result;
result = 0x0FFF&a;
result = (((result&0x800)?(0<<11):(1<<11))|((result&0x400)?(0<<10):(1<<10))
|((result&0x200)?(0<<9):(1<<9))|((result&0x100)?(0<<8):(1<<8))
|((result&0x080)?(0<<7):(1<<7))|((result&0x040)?(0<<6):(1<<6))
|((result&0x020)?(0<<5):(1<<5))|((result&0x010)?(0<<4):(1<<4))
|((result&0x008)?(0<<3):(1<<3))|((result&0x004)?(0<<2):(1<<2))
|((result&0x002)?(0<<1):(1<<1))|((result&0x001)?0:1));
return result=result+1;
}

Resources