difference between "loop_until_bit_is_set" macro and while() expression - c

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.

Related

Understanding the execution of command *__SIMD32(pIn)++ in embedded C

int8_t scratchbuffer[27000];
*pV = scratchbuffer;
*pSRC=pV;
*pIn=pSRC;
I need to understand solving of *__SIMD32(pIn)++
The definitions are mentioned below.
#define __SIMD32_TYPE int32_t
#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr))
Step by step, how do we reach to the output, and what would be the output ?
I tried searching internet for explanations, but couldn't find any.
It's just some preprocessor magic, *__SIMD32(pIn)++, with the definitions you show after the preprocessor becomes *(*(int32_t **) & (pIn))++. This gives you a 32 bit read of pIn, and then increments pIn by 32 bits. See here for more detail.

Running a block of code from RAM instead of flash

In the following program, what is the meaning of the line of code
fnRAM_code((volatile unsigned char *)FLASH_STATUS_REGISTER); // execute the command from SRAM
in the below section of code. I have some idea about what is happening here,In order to overcome read while write violation, copying the code from flash to RAM using the above lines of code. But what is exact meaning of these lines.
static int fnProgram(unsigned long *ptrWord, unsigned long *ptr_ulWord)
{
while ((FTFL_FSTAT & FTFL_STAT_CCIF) == 0) {} // wait for previous commands to complete
if ((FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_RDCOLERR)) != 0) { // check for errors in previous command
FTFL_FSTAT = (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_RDCOLERR); // clear old errors
}
FTFL_FCCOB0 = FCMD_PROGRAM; // enter the command sequence
FTFL_FCCOB1 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 16); // set address in flash
FTFL_FCCOB2 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 8);
FTFL_FCCOB3 = (unsigned char)((CAST_POINTER_ARITHMETIC)ptrWord);
FTFL_FCCOB7_4 = *ptr_ulWord++; // enter the long word to be programmed
FTFL_FCCOBB_8 = *ptr_ulWord; // enter the second long word to be programmed
uDisable_Interrupt(); // protect this region from interrupts
fnRAM_code((volatile unsigned char *)FLASH_STATUS_REGISTER); // execute the command from SRAM
uEnable_Interrupt(); // safe to accept interrupts again
return (FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_MGSTAT0)); // if there was an error this will be non-zero
}
The only code that needs to be in RAM is this:
static void fnFlashRoutineInRam(volatile unsigned char *ptrFTFL_BLOCK)
{
*ptrFTFL_BLOCK = FTFL_STAT_CCIF; // launch the command - this clears the FTFL_STAT_CCIF flag (register is FTFL_FSTAT)
while ((*ptrFTFL_BLOCK & FTFL_STAT_CCIF) == 0) {} // wait for the command to terminate
}
This looks like older NXP (former Freescale/Motorola) HCS08, HCS12 or Coldfire. On those devices, you have different cases when writing a flash driver: either you can execute it from flash or you cannot. This entirely depends on which "bank" the program flash belongs to: generally you cannot execute code on a MCU from the very same flash bank it is currently programming.
So ideally you put the flash programming code in another bank, but some devices only have one single flash bank. Then they provide a work-around by executing the code from RAM, which is kind of a quick & dirty fix.
Commonly they solve this by providing an array of raw data op codes. This array of op codes is copied to RAM and then they set a function pointer to point at the RAM address. I suspect fnRAM_code is such a function pointer. The (volatile unsigned char *)FLASH_STATUS_REGISTER part is simply passing on the address of the flash status register. Likely, FLASH_STATUS_REGISTER is synonymous with FSTAT.
The uDisable_Interrupt(); and uEnable_Interrupt(); should correspond to asm SEI and asm CLI respectively, blocking all maskable interrupts from triggering during the flash write, which would potentially cause the write to fail or the program to hang up.
There should be app notes available describing all of this in detail.
Please note that this code is very close to the hardware and relies on tons of poorly-defined behavior. I wouldn't count on it compiling as expected on anything but the Codewarrior compiler. gcc would for example spew out numerous strict aliasing bugs.

do ... while macro/function with different conditions

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.

C: switch case with hex value ignore the 0 in the front

I init a uint32 variable by shifting two uint8 variables.
uint32_t test = ((first_uint8 << 16) | second_uint8);
In my test, the value of test should be 0x00170001 (0x17<<16|0x01)
Then it runs into a switch case
switch(test) {
case 0x00170001:
//do sth
break;
default:
//printf invalid
break;
}
It should go to the first case, however, it always run into default.
Then I printf("%x", test), the result is 0x170001, which is equal to 0x00170001.
At last I try to modify it like this:
switch(test) {
case 0x170001:
//do sth
break;
default:
//printf invalid
break;
}
Then it works well.
So I'm curious about the result.
for a uint32_t variable, why 0x170001 does not equal to 0x00170001?
if it is caused by I didn't memset test by 0, then test should also not be equal to 0x170001, it should be 0x11170001 or something with a garbage first byte.?
is it caused by the compiler ignores the 0 in the front of hex value? I'm using Android NDK to compile my c code.
for a uint32_t variable, why 0x170001 does not equal to 0x00170001?
It does. 0x170001, 0x0170001 and 0x00170001 are all equal.
2.if it is caused by I didn't memset test by 0, then test should also not be equal to 0x170001, it should be 0x11170001 or something with a garbage first byte.?
It is not caused by a missing memset. Any assignment test = X will set all bits in test.
3.is it caused by the compiler ignores the 0 in the front of hex value? I'm using Android NDK to compile my c code.
That could explain it but I doubt it. I think it is more likely that your being tricked by something else. Perhaps you are not actually running the code, you think. If it really turns out that it makes a difference whether you write 0x170001 or 0x00170001, you should report it as a compiler bug - but be really sure before doing that.
See here for a working example compiled with gcc : http://ideone.com/UR566Q

The meaning of a single & in an if statement

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 */}

Resources