I have a while loop in C program which was supposed to wait for system to tweak a single bit (bit0) ON and then continue execution. This bit or "flag" is located in a register (reg1). I have been trying to program this using bitwise & operator for masking my register like this.
unsigned int continue;
while(continue != (reg1 & bit0));
I end up getting an error: "Syntax error, multiple markers at this line, expected ')' before ';' token."
continue is a keyword. You can't use it as an identifier.
Change the name to something else and see if it works:
unsigned int cont = 0; // You also forgot to initialize.
while(cont != (reg1 & bit0));
Related
I am getting segment fault error in this function. Can someone tell why?
/* Looks for an addition symbol "+" surrounded by two numbers, e.g. "5+6"
and, if found, adds the two numbers and replaces the addition subexpression
with the result ("(5+6)*8" becomes "(11)*8")--remember, you don't have
to worry about associativity! */
if (buffer[i] == '+') {
for (startOffset = i;
startOffset - 1 >= 0 && isNumeric(buffer[startOffset - 1]);
--startOffset)
; // empty loop body
if (startOffset == i) // For further processing
continue;
for (remainderOffset = i;
remainderOffset + 1 < bufferlen && isNumeric(buffer[remainderOffset + 1]);
++remainderOffset)
; // empty loop body
if (remainderOffset == i)
continue;
strncpy(operand, &buffer[startOffset], i - startOffset);
operand[i - startOffset] = '\0';
string2int(value1, operand);
strncpy(operand, &buffer[remainderOffset], remainderOffset - i);
operand[remainderOffset - i] = '\0';
string2int(value2, operand);
sum = value1 + value2;
sprint(operand, "%d", sum);
operlength = strlen(operand);
strncpy(&buffer[startOffset], operand, operlength);
strcpy(&buffer[operlength], &buffer[remainderOffset + 1]);
bufferlen = bufferlen - (remainderOffset - startOffset + 1) + operlength;
}
Compile your program with the debugger flag in gdb like this cc -g "program name". If you have command line arguments, for the program execute gdb --args progname arg2 ...
It will load your program into a CLI utility which has the lines numbered. Type in 'break 32' for example and this will monitor variables on that line. At any rate, once you've compiled it with the debugger symbols and loaded it, type 'run' to start the program. If no break points are set or anything else funky, it will trigger the SEGV and tell you exactly which line of code triggered it. Run the debugger at least 3 times to make sure the segv fault is being triggered by the same line of code. Then check your memory bounds(is your array index outside of the allocated address space? You were tresspassing... Try inserting a printf line which prints off the array addresses and offset you are using to be sure your bounds aren't getting skewed; a side note, int conjunction with the gdb debugger using the breakpoint and typing 'step' on the CLI each time to step through each step, you can also at each step in your execution type in 'info locals' which will tell you the variables values in the stack space, i.e. your index variable value at each step. As an alternative to manually inserting printf lines) I am not a professional expert. It looks like continue on the 9th line is moot. Good luck!
This is going to be a bit abstract due to the specific ARM (LPCXpresso 1115R/303) Cortex M0 and the H6 bluetooth module, and with NXP software there are a ton of driver files that are linked so hopefully the code snip below will be enough to identify the problem.
I am creating a simple menu system through bluetooth. Everything works with communcation. I send the message from the board, it is visible on the phone, I respond and print the value in the console of the program. All are exactly what I want them to be. But this is what happens:
1) start debug session and resume
2) 1st menu sends to phone, correct.
3) Type response to phone and send, correct.
4) message appears in console exactly as entered from phone (Just the number 1 appears)
5) Have if loop that checks to see if Buffer value == '1';
6) must not == 1 because it never enters the loop.
7) reprints the value of the buffer, and it still equals 1.
The only hint I have is a warning that says "makes integer from pointer without a cast [-Wint-conversion]" on the assignment line as indicated below.
void ArmPeripheral() {
UARTCount = 0;
LPC_UART->IER = IER_THRE | IER_RLS; /* Disable RBR */
UARTSend( (uint8_t *)menu1, sizeof(menu1));
LPC_UART->IER = IER_THRE | IER_RLS | IER_RBR; /* Re-enable RBR */
while(1) {
if(UARTCount != 0){
printf("%s 1st print\n",UARTBuffer);
int bVal = UARTBuffer; // This is where the error occurs, tried uint8_t, did not work.
printf("%s This is bVal\n",bVal);
if(bVal == 1) { //have tried 1, '1', and "1" none work
printf("inside loop %s...\n",UARTBuffer);
printf("%s This is bVal\n",bVal);
LEDControl();
}
printf("%s second print\n",UARTBuffer);
UARTCount = 0;
}
}
}
enter image description here
Nevermind, it was just a simple pointer issue. UARTBuffer is a external volatile uint8_t in the UART.c file, and even though it is not defined as a pointer, it is pointing to a buffer somehow.
int bVal = *UARTBuffer;
if(bVal == '1') {
The above worked, but if anyone has any more in depth information that could explain why I would be interested in knowing. This is how I initialized the buffer:
extern volatile uint32_t UARTCount;
extern volatile uint8_t UARTBuffer[BUFSIZE];
I have the following code:
/* some calculation */
do {
/* data acquire and calculation */
} while (CONDITION);
My condition looks like one of the following:
(( A || B ) && C )
( A && C )
Note that I use these conditions with different statements for A, B and C. However the pre-calculation and everything inside the loop is always the same. I use this block several times in my code and wondered if there is a possibility to put it in a define or in a function to let the code look cleaner.
Is there a nice and reasonable way to achieve the loop with different statements?
I already thought about a function call in a while loop like
while (DoMyLoop( CONDITION, calculationParams ));
But with this solution I wouldn't have the pre-calculation in my one-liner.
How can I get my code block in a nice one-liner (or more if necessary, as long as it's easy to understand and maintain)?
Some additional (maybe irrelevant) information:
In my loop I receive a byte array and depending on the situation I have to loop until a specific bit changes, therefore the A or B.
C is a timeout condition.
Here is some code with variables
unsigned char data[10] = { 0 };
long intervalMS = 0;
/* precalc */
gettimeofday( &stopTimeout, NULL );
gettimeofday( &startTimeout, NULL );
do {
receiveCall( data );
gettimeofday( &stopTimeout, NULL );
intervalMS = (stopTimeout.tv_sec - startTimeout.tv_sec) * 1000 +
(stopTimeout.tv_usec - startTimeout.tv_usec) / 1000;
} while ( (data[0] & 0x01) && intervalMS < 200);
The A part of the condition can also look like ((data[2] & 0x02) || data[3] == 0x12).
What about next solution?
for (precalculation (); CONDITION; somethingWith (calculationParams));
precalculation () is executed once, the CONDITION is evaluated at every iteration and somethingWith (calculationParams) take the place in of the incrementation. The body of the for loop is empty.
Pure C beauty.
Obviously, precalculation and somethingWith (calculationParams) must become a new function.
First of all, please note that do {} while(something) is equivalent to something=true; while something{}. The former saves a bit of extra execution in case you don't want the initialization part.
How can I get my code block in a nice one-liner
There is nothing wrong with your code. } while ( (data[0] & 0x01) && intervalMS < 200); is perfectly clear to me - another C programmer.
You check if the lsb is set and you check a timer interval. The only way this code could be improved would be to explain why you check the lsb - which you can do with a comment (do you check if a number is odd or do you read a bit in bit-field etc).
Now what you can and should do, is to put the whole snippet inside a function and give it a meaningful name. There's the nice one-liner.
Came across a weird notation today while reading through some C code
Can anyone explain to me what the line do?
if ((dwEvent & EV_RXCHAR) && cs.cbInQue) { /* do stuff */}
if ((dwEvent & EV_RXCHAR) && cs.cbInQue) { /* do stuff */}
& is Binary And Operator. & is applied to every bit of both the variables .It checks ,
if result of dwEvent & EV_RXCHAR is non-zero then cs.cbInQue is checked if it is non-zero or not .
If both the conditions are true code in if block is executed .
if result of dwEvent & EV_RXCHAR is zero then without checking cs.cbInQue , code in else block is executed if present.
It masks (performs binary AND operation) dwEvent with EV_RXCHAR, checks if the result is non-zero, checks if cs.cbInQue is non-zero, if both are true, executes code in conditional statement.
This is not necessarily a "weird" notation. Many programmers use it as a shortcut instead of specifying (x & y) != 0.
It is a bitwise operation. You can read it here. link
Its short form to check if the any of the bits EV_RXCHAR are set by checking getting out those bits first (dwEvent & EV_RXCHAR). Then if any of these are set it
would also check if cs.cbInQue is also set then do the stuff.
eg:
unsigned int x = dwEvent & EV_RXCHAR;
if (x !=0)
if (cs.cbInQue != 0)
{ /* do stuff */}
this piece of code in running on ATmega2560, so what is the difference between these two:
while(UCSR0A & 0b00100000 == 0); // check UDRE0 bit if it is 1
and:
loop_until_bit_is_set(UCSR0A, UDRE0);
as you can see this is for UART transmission, but if i use the first one I could't get desired output on terminal, for example if i do printf("Hello world\n"); the actual terminal display is: HeHeHe....... However the latter one works. You can find this piece of code in stdio.h.
== has higher priority than &; also, no need to check for == 0 - you should try
while(!(UCSR0A & 0b00100000));
or rather, using bit macro
while(!(UCSR0A & _BV(UDRE0)));
instead.