Processing Array Data - c

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]);

Related

Check if N(large) bits are set

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++;
}

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.

Understanding And Getting info of Bitmap in C

I am having a hard time understanding and parsing the info data present in a bitmap image. To better understand I read the following tutorial, Raster Data.
Now, The code present there is as follows, (Greyscale 8bit color value)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*-------STRUCTURES---------*/
typedef struct {int rows; int cols; unsigned char* data;} sImage;
/*-------PROTOTYPES---------*/
long getImageInfo(FILE*, long, int);
int main(int argc, char* argv[])
{
FILE *bmpInput, *rasterOutput;
sImage originalImage;
unsigned char someChar;
unsigned char* pChar;
int nColors; /* BMP number of colors */
long fileSize; /* BMP file size */
int vectorSize; /* BMP vector size */
int r, c; /* r = rows, c = cols */
/* initialize pointer */
someChar = '0';
pChar = &someChar;
if(argc < 2)
{
printf("Usage: %s bmpInput.bmp\n", argv[0]);
//end the execution
exit(0);
}
printf("Reading filename %s\n", argv[1]);
/*--------READ INPUT FILE------------*/
bmpInput = fopen(argv[1], "rb");
//fseek(bmpInput, 0L, SEEK_END);
/*--------DECLARE OUTPUT TEXT FILE--------*/
rasterOutput = fopen("data.txt", "w");
/*--------GET BMP DATA---------------*/
originalImage.cols = (int)getImageInfo(bmpInput, 18, 4);
originalImage.rows = (int)getImageInfo(bmpInput, 22, 4);
fileSize = getImageInfo(bmpInput, 2, 4);
nColors = getImageInfo(bmpInput, 46, 4);
vectorSize = fileSize - (14 + 40 + 4*nColors);
/*-------PRINT DATA TO SCREEN-------------*/
printf("Width: %d\n", originalImage.cols);
printf("Height: %d\n", originalImage.rows);
printf("File size: %ld\n", fileSize);
printf("# Colors: %d\n", nColors);
printf("Vector size: %d\n", vectorSize);
/*----START AT BEGINNING OF RASTER DATA-----*/
fseek(bmpInput, (54 + 4*nColors), SEEK_SET);
/*----------READ RASTER DATA----------*/
for(r=0; r<=originalImage.rows - 1; r++)
{
for(c=0; c<=originalImage.cols - 1; c++)
{
/*-----read data and print in (row,column) form----*/
fread(pChar, sizeof(char), 1, bmpInput);
fprintf(rasterOutput, "(%d, %d) = %d\n", r, c, *pChar);
}
}
fclose(bmpInput);
fclose(rasterOutput);
}
/*----------GET IMAGE INFO SUBPROGRAM--------------*/
long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, offset, SEEK_SET);
for(i=1; i<=numberOfChars; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
/* calculate value based on adding bytes */
value = (long)(value + (*ptrC)*(pow(256, (i-1))));
}
return(value);
} /* end of getImageInfo */
What I am not understanding:-
I am unable the understand the 'GET IMAGE INTOSUBPROGRAM' part where the code is trying to get the image infos like no of rows,columns, etc. Why are these infos stored over 4 bytes and what is the use of the value = (long)(value + (*ptrC)*(pow(256, (i-1)))); instruction.
Why there unsigned char dummy ='0' is created and then ptrC =&dummy is assigned?
Why can't we just get the no of rows in an image by just reading 1 byte of data like getting the Greyscale value at a particular row and column.
Why are we using unsigned char to store the byte, isn't there some other data type or int or long we can use effectively here?
Please help me understand these doubts(confusions!!?) I am having and forgive me if they sound noobish.
Thank you.
I would say the tutorial is quite bad in some ways and your problems to understand it are not always due to being a beginner.
I am unable the understand the 'GET IMAGE INTOSUBPROGRAM' part where the code is trying to get the image infos like no of rows,columns, etc. Why are these infos stored over 4 bytes and what is the use of the value = (long)(value + (ptrC)(pow(256, (i-1)))); instruction.
The reason to store over 4 bytes is to allow the image to be sized between 0 and 2^32-1 high and wide. If we used just one byte, we could only have images sized 0..255 and with 2 bytes 0..65535.
The strange value = (long)(value + (*ptrC)*(pow(256, (i-1)))); is something I've never seen before. It's used to convert bytes into a long so that it would work with any endianness. The idea is to use powers of 256 to set the *ptrC to the value, i.e. multiplying first byte with 1, next with 256, next with 65536 etc.
A much more readable way would be to use shifts, e.g. value = value + ((long)(*ptrC) << 8*(i-1));. Or even better would be to read bytes from the highest one to lower and use value = value << 8 + *ptrC;. In my eyes a lot better, but when the bytes come in a different order, is not always so simple.
A simple rewrite to be much easier to understand would be
long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char ptrC;
long value = 0L;
int i;
fseek(inputFile, offset, SEEK_SET);
for(i=0; i<numberOfChars; i++) // Start with zero to make the code simpler
{
fread(&ptrC, 1, 1, inputFile); // sizeof(char) is always 1, no need to use it
value = value + ((long)ptrC << 8*i); // Shifts are a lot simpler to look at and understand what's the meaning
}
return value; // Parentheses would make it look like a function
}
Why there unsigned char dummy ='0' is created and then ptrC =&dummy is assigned?
This is also pointless. They could've just used unsigned char ptrC and then used &ptrC instead of ptrC and ptrC instead of *ptrC. This would've also shown that it is just a normal static variable.
Why can't we just get the no of rows in an image by just reading 1 byte of data like getting the Greyscale value at a particular row and column.
What if the image is 3475 rows high? One byte isn't enough. So it needs more bytes. The way of reading is just a bit complicated.
Why are we using unsigned char to store the byte, isn't there some other data type or int or long we can use effectively here?
Unsigned char is exactly one byte long. Why would we use any other type for storing a byte then?
(4) The data of binary files is made up of bytes, which in C are represented by unsigned char. Because that's a long word to type, it is sometimes typedeffed to byte or uchar. A good standard-compliant way to define bytes is to use uint8_t from <stdint.h>.
(3) I'm not quite sure what you're trying to get at, but the first bytes - usually 54, but there are othzer BMF formats - of a BMP file make up the header, which contains information on colour depth, width and height of an image. The bytes after byte 54 store the raw data. I haven't tested yopur code, but there might be an issue with padding, because the data for each row must be padded to make a raw-data size that is divisible by 4.
(2) There isn't really a point in defining an extra pointer here. You could just as well fread(&dummy, ...) directly.
(1) Ugh. This function reads a multi-byte value from the file at position offset in the file. The file is made up of bytes, but several bytes can form other data types. For example, a 4-byte unsigned word is made up of:
uint8_t raw[4];
uint32_t x;
x = raw[0] + raw[1]*256 + raw[2]*256*256 + raw[3]*256*256*256;
on a PC, which uses Little Endian data.
That example also shows where the pow(256, i) comes in. Using the pow function here is not a good idea, because it is meant to be used with floating-point numbers. Even the multiplication by 256 is not very idiomatic. Usually, we construct values by byte shifting, where a multiplication by 2 is a left-shift by 1 and hence a multiplication by 256 is a left-shift by 8. Similarly, the additions above add non-overlapping ranges and are usually represented as a bitwise OR, |:
x = raw[0] | (raw[1]<<8) | (raw[2]<<16) | (raw[3]<<24);
The function accesses the file by re-positioning the file pointer (and leaving it at the new position). That's not very effective. It would be better to read the header as an 54-byte array and accessing the array directly.
The code is old and clumsy. Seeing something like:
for(r=0; r<=originalImage.rows - 1; r++)
is already enough for me not to trust it. I'm sure you can find a better example of reading greyscale images from BMP. You could even write your own and start with the Wikipedia article on the BMP format.

How do I read in data from an external binary file that needs differing byte lengths per element?

Here's the situation. I have to read in data from an external binary file and display the data in order and so that it makes sense to the user.
The file has data stored as follows: the first 4 bytes are an integer, then the next 8 bytes are a floating decimal, followed by the next 8 bytes (float), etc. So I need to read in 4 bytes initially, then repeatedly 8 bytes after that... until the file has no data left to read.
I have read the file in such a way that it stores its data into an array i[NUM] (where NUM is the number of elements), and each element contains 4 bytes. By doing this, I have accidentally 'split' the floats in half, the first half being stored in i[1] and the second half in i[2], also a float in i[3] and i[4], etc.
Now I am in the process of trying to 'stitch' the two halves of each float back together again in order to display them, but I am stuck.
Any suggestions are greatly appreciated.
My code so far:
#include "stdafx.h"
#include "stdio.h"
#define NUM 15
int main(void)
{
//initialising
int i[NUM], j, k;
float temp[NUM];
char temp_c[NUM];
int element_size = 4;
int element_number = NUM;
for(k=0; k<NUM; k++)
{
i[k] = 0; //clear all cells in i[]
temp[k] = 0; //clear all cells in temp[]
}
//file reading
FILE *fp;
fp = fopen("C:\\data", "rb+");
fread(&i, element_size, element_number, fp); //reads 'data' to the end and then stores each element into array i[]
fclose(fp); //close the file
//arrange and print data here
printf("Data of File\n\nN = %d",i[0]);
//this is where the rest fell apart
//No idea how to go about it
return 0;
}
If you're sure that the float is 8 bytes and the int is 4 then you can do this (probably in a loop with variables instead of the fixed indices I've used):
memcpy(&temp[0], &i[1], 8);
I'm assuming that your code for creating the file was a fwrite where you wrote the 4-byte int, then wrote the 8-byte floats.
Then you can output the floats with printf("%f\n", temp[0]); or whatever.
NB. You can avoid your initialization loop by initializing the arrays directly: int i[NUM] = { 0 }; etc. This only works for 0, not for other values.

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

Resources