I wrote this code to find the highest temperature pixel in a thermal image. I also need to know the coordinates of the pixel in the image.
void _findMax(uint16_t* image, int sz, sPixelData* returnPixel)
{
int temp = 0;
uint16_t max = image[0];
for(int i = 1; i < sz; i++)
{
if(max < image[i])
{
max=image[i];
//temp = i;
}
}
returnPixel->temperature = image[temp];
//returnPixel->x_location = temp % IMAGE_HORIZONTAL_SIZE;
//returnPixel->y_location = temp / IMAGE_HORIZONTAL_SIZE;
}
With the three lines commented out the function executes in about 2ms. With the lines uncommented it takes about 35ms to execute the function.
This seems very excessive seeing as the divide and modulus are only performed once after the loop.
Any suggestions on how to speed this up?
Or why it takes so long to execute compared to the divide on modulus not include?
This is executing on an ARM A9 processor running Linux.
The compiler I'm using is ARM v8 32-Bit Linux gcc compiler.
I'm using optimize -O3 and the following compile options: -march=armv7-a+neon -mcpu=cortex-a9 -mfpu=neon-fp16 -ftree-vectorize.
Your code is flawed.
Since temp is simply 0, the complier will generate machine codes that just executes returnPixel->temperature = image[0]; which gets finished in no time. There is nothing odd here.
You should modify the line to: returnPixel->temperature = max;
You could boost the performance significantly by utilizing neon. But that's another problem.
I am using Code Composer Studio to work with an MSP430 MCU. These are the specs that I am working with:
CCS version: 5.5
Compiler version: TI v4.1.9
Compiler Optimization Settings: Optimization = 0
MSP430: MSP430F5528
I'm starting with a working device and adding a new function to calculate the standard deviation of an array of measurements. The device has been working completely fine until I added the sqrt function in the below code:
double standardDeviation (int average, int measurements[], int positions){
double deviation = 0;
int i = 0;
for(i = 0; i <= positions; i++){
measurements[i] = measurements[i] - average;
measurements[i] = measurements[i] * measurements[i];
deviation += measurements[i];
}
deviation = deviation/positions;
deviation = sqrt(deviation);
return deviation;
}
Also, I have #include <math.h> at the header of my file.
When I comment out the line with sqrt, the device works as expected. The Inputs and outputs and array values are all working perfectly. The signalling LEDs are as they should be and I can see the array values while in debug mode are as they should be.
With the sqrt line included, firmware that is being debugged automatically starts running. When I pause the program, I get this error:
"Can't find a source file at "/tmp/TI_MKLIBSF5oIb/SRC/copy_decompress_rle.c"
Locate the file or edit the source lookup path to include its location."
With sqrt included, the device no longer functions as expected, even with deviation variable completely disassociated from any input or output of the device. After the firmware is uploaded on different occasions, the device has had all of the outputs turn on at once, none of the outputs turn on, and outputs randomly coming on and off. I cannot measure any values of the inputs because I can't pause the program.
Things I have tested:
Commenting out measurements[]*measurements[] to make sure the value does not get too large, same failure described above
Commenting out the line with sqrt, the device worked as expected
Replaced the variable inside the sqrt function with 4, same failure described above
Set all of the positions of the measurements[] array equal to 1, same failure described above
Defined variable deviation in header to use static memory instead of dynmaic
I have read tons of similar questions about this stuff here but still can't solve my problem.
I need to use this piece of assembly code in C file:
unsigned char * led = (char *) 0xC0;
for (int i = 0; i < 10; i++)
{
__asm
{
ror [led[i]],1
};
}
I just need to rotate all values in led variable by 1 bit. While using this code I get an Factor expected error. When i remove [] brackets around led value, it is end of line expected error.
Strange thing is the code bellow works perfectly:
__asm
{
nop
};
As you can see these samples look very similar but there is only one working properly. What am I doing wrong?
If it is relevant i try to make an easy application in CodeWarrior, which is IDE for embedded software development.
This is a homework assignment, I just want help with gdb, not specific answers.
I have no experience with gdb whatsoever and little terminal experience. I followed a simple example online to debug some code using gdb but in the example gdb pointed out that a problem happened when it ran the code. When I try to mimic the process for this assignment gdb doesn't say anything. I am still somewhat new to C, but I can see problems when I look at the code and gdb isn't saying anything.
Say the file is named test.c, in the terminal I type gcc test.c and it gives me a warning because printf() is there but #include <stdio.h> is not, which is good because that is supposed to be wrong.
It also produces a.out and if I run it in the terminal with ./a.out nothing happens. The terminal just is ready for my next input with no messages. If I type gdb ./a.out and then run it just tells me the program exited normally.
Can someone point out what I have to do to make gdb point to the errors please?
// insertion sort, several errors
int X[10], // input array
Y[10], // workspace array
NumInputs, // length of input array
NumY = 0; // current number of
// elements in Y
void GetArgs(int AC, char **AV) {
int I;
NumInputs = AC - 1;
for (I = 0; I < NumInputs; I++) X[I] = atoi(AV[I+1]);
}
void ScootOver(int JJ) {
int K;
for (K = NumY-1; K > JJ; K++) Y[K] = Y[K-1];
}
void Insert(int NewY) {
int J;
if (NumY = 0) { // Y empty so far,
// easy case
Y[0] = NewY;
return;
}
// need to insert just before the first Y
// element that NewY is less than
for (J = 0; J < NumY; J++) {
if (NewY < Y[J]) {
// shift Y[J], Y[J+1],... rightward
// before inserting NewY
ScootOver(J);
Y[J] = NewY;
return;
}
}
}
void ProcessData() {
// insert new Y in the proper place
// among Y[0],...,Y[NumY-1]
for (NumY = 0; NumY < NumInputs; NumY++) Insert(X[NumY]);
}
void PrintResults() {
int I;
for (I = 0; I < NumInputs; I++) printf("%d\n",Y[I]);
}
int main(int Argc, char ** Argv) {
GetArgs(Argc,Argv);
ProcessData();
PrintResults();
}
Edit: The code is not mine, it is part of the assignment
There are different kinds of errors. Some can be detected by programs (the compiler, the OS, the debugger), and some cannot.
The compiler is required (by the C standard) to issue errors if it detects any constraint violations. It may issue other errors and warnings when not in standards compliance mode. The compiler will give you more error diagnostics if you add the -Wall and -Wextra options. The compiler may be able to detect even more errors if you enable optimizations (-O0 through -O3 set different levels of optimization), but you may want to skip optimizations if you want to single-step in the debugger, because the optimizer will make it harder for the debugger to show you the relevant source-lines (some may be re-ordered, some may be eliminated).
The operating system will detect errors involving traversing bad pointers (usually), or bad arguments to system calls, or (usually) floating-point division by zero.
But anything that doesn't crash the program is a semantic error. And these require a human brain to hunt for them.
So, as Brian says, you need to set breakpoints and single-step through the program. And, as jweyrich says, you need to compile the program with -g to add debugging symbols.
You can inspect variables with print (eg. print Argc will tell you how many command-line arguments were on the run line). And display will add variables to a list that is displayed just before each prompt. If I were debugging through that for-loop in Insert, I'd probably do display J and display Y[J], next, and then hit enter a bunch of times watching the calculation progress.
If your breakpoint is deeply nested, you can get a "stack dump" with backtrace.
next will take you to the next statement (following the semicolon). step will take you into function calls and to the first statement of the function. And remember: if you're single-stepping through a function and get to the 'return' statement, use step to enter the next function call in the calling statement; use next at the return to finish the calling statement (and just execute any remaining function calls in the statement, without prompting). You may not need to know this bit just yet, but if you do, there you go.
From gdb, do break main, then run.
From there, next or step until you find where you went wrong.
I have a C code similar to:
int f() {
for (int i = 0; i < 100; i++) {
scanf flag;
if(flag)
scanf data1;
scanf data2;
}
}
I want to break the execution only when flag == 0. How should I set the breakpoint (using gdb)?
In the gdb console type
b (some_line) if flag == 0
EDIT:
If you can't print flag while stopped at some-line, then either:
- (A) your code is compiled with optimization (likely), or
- (B) you have a buggy compiler
If it's (A), add -O0 in addition to -g3.
If you can print flag, then you have a buggy version of GDB. Try upgrading to current 7.0.1 release.