C: simple code not working as expected (PIC micro) - c

This line isn't working as expected:
uartPushPos = (uartPushPos + 1) % UART_TX_BUFF_LENGTH;
However this below, which in theory does the same, does work:
//if (uartPushPos == UART_TX_BUFF_LENGTH - 1){
if (uartPushPos >= UART_TX_BUFF_LENGTH - 1){
uartPushPos = 0;
} else {
uartPushPos++;
}
UartPopPos is type char, and UART_TX_BUFF_LENGTH is a preprocessor variable set to 16.
Why does the second code segment work, but not the first?
If it makes much of a difference, I'm using the SourceBoost BoostC compiler for the PIC microcontroller 16f.
Thanks

They are different if uartPushPos is less than 0, or if it is more than or equal to UART_TX_BUFF_LENGTH.
See also Mod of negative number is melting my brain

Related

Selectively ignoring parts of a randomly generated sequence of numbers (in C)

I have a question that may be hard to understand -- but I will try my best to explain.
I'm programming the Simon Game in C. This implementation specifically read/writes to a hardware DAQ module that has a 4 LED display, and 4 corresponding toggle switches.
As per the rules of the Game, I've seeded and generated a random sequence of numbers between 0 and 3 (sequence length is arbitrarily 5). In the Game, if the player presses the wrong switch (i.e. blue is shown but you press green), the game ends and restarts.
The way I've set up the Game looks like this:
(I haven't included the code for function "blinkLED" here -- it turns the actual LED on/off.)
void runSimon(void){
int sequence[MAX_SEQ_LEN];
int i;
int count = 0;
// Seeds the random number generator.
srand((unsigned)time(NULL));
// Generate the random LED sequence & store it as an array.
for (i = 0; i < MAX_SEQ_LEN; i++){
sequence[i] = (rand() % NUM_LEDS);
}
// The game begins!
while (continueSuperLoop() == TRUE){
// Loop the game while the sequence length is less than the pre-defined maximum (currently it's 5).
while (count < MAX_SEQ_LEN){
for (i = 0; i <= count; i++){
// Blink the first 'count' LEDs in the sequence, one at a time.
blinkLED(sequence[i], 1, ONE_SEC);
//
//
//THE ISSUE SHOULD BE HERE (!)
//
// Monitors whether or not the player has made a mistake...if so, blink the red LED thrice, then restart the game.
if (digitalRead(sequence[ !i ] == SWITCH_ON)){
blinkLED(LED_1_R, 3, HALF_SEC);
Sleep(3 * ONE_SEC);
continue;
}
// Monitors whether or not the correct switch is being pressed -- waits for it to be released
while (digitalRead(sequence[i]) == SWITCH_ON){}
}
count++;
}
// If 'count' is equal to 'MAX_SEQ_LEN', the green LED blinks 3x to indicate the player has won .
if (count == MAX_SEQ_LEN){
blinkLED(LED_0_G, 3, HALF_SEC);
Sleep(3 * ONE_SEC);
}
}
}
Where I indicated an issue, I'm not sure how the "digitalRead(sequence[ ! i ]" behaves; I need this line to read every switch that's not supposed to be pressed.
I don't think the compiler understands what I'm trying to do here, though -- for example, if the first number in the sequence is 3 (representing the 4th LED), I need to specify that every other number (0, 1, 2) and its corresponding switch should not be pressed.
Would a solution be to store the current number in the sequence, having a set of four TRUE/FALSE flags for each LED, and monitoring the three non-current numbers and their corresp. switches to see if they are pressed?
I'm getting quite frustrated with writing this program. I'm pretty new to programming. Any help is appreciated.
I'm not sure I understand the rules of this game correctly but one thing that jumps out instantly is
digitalRead(sequence[ !i ]
I think you want
!digitalRead(sequence[ i ]
Also, you need to fix your game flow. Right now it's:
1. Light LED.
2. Check if user pressed the right button.
You need to wait for some time before checking a switch or wait for ANY switch to be pressed and see if it's the correct one. So something like this:
1. Light LED.
2. Wait for timeout or ANY switch to be pressed.
3. If timeout: error
4. else: check if switch that was pressed is correct.
In C, ! operator is a unary NOT. When applied to an integer i, it is equivalent to if (i == 0) return 1; else return 0;. Then you are using !i as an index for sequence array, so it will be either sequence[0] or sequence[1], and clearly this is not what you want. Also your == is inside of digitalRead call :)
I would suggest explicitly checking for every other button not to be pressed. Like this:
int isOtherPressed = 0;
for (ledId = 0; ledId < NUM_LEDS; ledId++) {
if (ledId != sequence[i] && digitalRead(ledId) == SWITCH_ON) {
isOtherPressed = 1;
}
}
if (isOtherPressed) {
// restart the game
}
However, I'm suspicious about the whole gameplay you have, but maybe it's just because I don't know how digitalRead works. For example, the way you use continue doesn't seem to stop the game. Maybe you meant break?

In C, how to convert several boolean to int whose bits value are the results of differents tests

I want to convert several tests to an int which bits are the results of a test:
int i=0;
if (m>speed0) i|=0B00001;
if (m>speed1) i|=0B00010;
if (m>speed2) i|=0B00100;
if (m>speed3) i|=0B01000;
That seems very slow. Are there a better way ? Speed is very important (i'm on arduino)
One thing you could try is to build an "if-ladder" to only make one write to i; by rolling the lower bits into each the higher test's value, and reversing the order of the tests.
int i;
if (m > speed3) i = B00001111;
else if(m > speed2) i = B00000111;
else if(m > speed1) i = B00000011;
else if(m > speed0) i = B00000001;
else
i = 0;
This also cuts away the read-modify-write, since it always does a single write to i. You're still going to have to profile this, I really can't say if it's going to be faster.
Oh, and the thing that looks like a binary prefix (the B) is an Arduino-ism, not standard in C. I think it's just 256 preprocessor macros.
What about this one:
int i = (m>speed0) |
((m>speed1)<<1) |
((m>speed2)<<2) |
((m>speed3)<<3)
This will remove the branches so you will not suffer from branch mispredictions. This code should be very fast. However, note that a very good optimizing compiler might be able to transform your code to equivalent code and elide the branches. But with my solution, you can be sure that you will not suffer branch misses even with a poor optimizer.
Edit:
However, since you are on Arduino, branch misses are not an issue. Then, your code should be fine as well. Simply benchmark it. If yours is too slow try mine. But I guess, both should be fine.
I would go with an "if binary tree" since it is scalable and should have a performance of log2(n):
int i = 0; // Default m < speed 0
if(m > speed2)
if (m > speed3)
i = B00001111; // m > speed 3
else
i = B00000111; // m > speed 2
else
if(m > speed1)
i = B00000011; // m > speed 1
else if(m > speed0)
i = B00000001; // m > speed 0
Do profile this since jumps and memory access times are highly dependent on hardware architecture.

C - While and IF statements - Trying to timeout after X time

I am having difficulties with the below code;
int i = 0;
int x = 0;
int ch ;
int n;
while((i < sizeof(buffer) - 1) && (x < (TIMER_FREQ*30)))
{
//getkey_serial0 returns either a (int)character or 0 if nothing on
//UART0
if((ch = getkey_serial0) == 0)
{
x++; //Increment X as there is nothing being received.
}
else
{
if(ch == '\n')
{
n++;
}
if(n < 8){ //Yes I can simplify this but for some reason
} //I only just noticed this :/ Anyway, it is
else{ //just here to avoid saving info I don't need
buffer[i] = ch ;
i++;
}
}
}
As the input it is reading in is the results of a wireless scan the number of entries scanned can vary greatly, and so I need to be able to avoid infinitely looping.
Originally I just read up to 11 \n's but this was rubbish as I kept missing SSID's which I needed, so I decided I needed some sort of timer or method to help me break after X amount of time.
TIMER_FREQ is defined as 10.
Clearly I am doing something stupid so any suggestions or tips would be greatly appreciated.
I generally prefer suggestions to help me try and think out the problem as opposed to fixed code posts :) I always seem to miss something simple despite my best efforts!
Thanks
EDIT: I should mention, this is on an embedded system (ARM7)
You should have access to a general purpose timer interrupt -- commonly called sys_tick().
The general practice in such "bare metal" applications is to configure the interrupt to fire every n milliseconds (10 ms is frequently used on my Cortex M3). Then, have the ISR update a counter. You'll want to ensure the counter update is atomic, so use a 32-bit, properly-aligned variable. (I'm assuming your processor is 32-bit, I can't recall for certain). Then your "application" code can poll the elapsed time as needed.
BUT - this timer discussion might be moot. In my ARM9 applications, we tie an interrupt to the UART's receive buffer. The associated ISR captures the keystroke and then performs any buffer management. Is that an option for you?
Do you really mean:
if((ch = getkey_serial0) == 0) { ...
Or do you actually mean:
if((ch = getkey_serial0()) == 0) { ...
If the latter, this is why your program never returns zero as you are giving it a function pointer. Does your program have many warnings at build?
If you want to time things, look into time(). It will let you see the system's wall clock, so you can determine if too many seconds have elapsed.

why am I getting a segfault error from the following code in C?

I have a project due in my operating systems class where I'm supposed to simulate a translation lookaside buffer.
I'm writing a method that will be called after a TLB-miss. It's supposed to find the next entry in the TLB that is either empty or has not been hit in awhile, delete that entry, and replace it with the entry from the page table that was last called. The data from the page table entry is given when the method is called.
Void tlb_insert(VPAGE_NUMBER new_vpage, PAGEFRAME_NUMBER new_pframe, BOOL new_mbit, BOOL new_rbit)
{
// Starting at the clock_hand'th entry, find first entry to
// evict with either valid bit = 0 or the R bit = 0. If there
// is no such entry, then just evict the entry pointed to by
// the clock hand.
int m;
int evct = clock_hand;
for (m = clock_hand; m < (num_tlb_entries); m++){
if (tlb[m].vbit_and_vpage & VBIT_MASK == 0 || tlb[m].mr_pframe & RBIT_MASK == 0){
evct = m;
break;
}
}
// Then, if the entry to evict has a valid bit = 1,
// write the M and R bits of the of entry back to the M and R
// bitmaps, respectively, in the MMU (see mmu_modify_rbit_bitmap, etc.
// in mmu.h)
if (tlb[evct].vbit_and_vpage & VBIT_MASK == 1){
PAGEFRAME_NUMBER pfr = tlb[evct].mr_pframe & PFRAME_MASK;
int val1 = tlb[evct].mr_pframe & RBIT_MASK;
int val2 = tlb[evct].mr_pframe & MBIT_MASK;
mmu_modify_rbit_bitmap (pfr, val1);
mmu_modify_mbit_bitmap(pfr, val2);
}
// Then, insert the new vpage, pageframe, M bit, and R bit into the
// TLB entry that was just found (and possibly evicted).
tlb[evct].vbit_and_vpage = VBIT_MASK | new_vpage;
tlb[evct].mr_pframe = new_mbit | (new_rbit | new_pframe);
// Finally, set clock_hand to point to the next entry after the
// entry found above.
clock_hand = evct + 1;
}
//Writes the M & R bits in the each valid TLB
//entry back to the M & R MMU bitmaps.
void tlb_write_back()
{
int n;
for (n = 0; n < num_tlb_entries; n++){
if (tlb[n].vbit_and_vpage & VBIT_MASK == 1){
PAGEFRAME_NUMBER pfr = tlb[n].mr_pframe & PFRAME_MASK;
int val1 = tlb[n].mr_pframe & RBIT_MASK;
int val2 = tlb[n].mr_pframe & MBIT_MASK;
mmu_modify_rbit_bitmap (pfr, val1);
mmu_modify_mbit_bitmap(pfr, val2);
}
}
}
I'm getting a segfault from the lines:
tlb[evct].vbit_and_vpage = VBIT_MASK | new_vpage;
tlb[evct].mr_pframe = new_mbit | (new_rbit | new_pframe);
VBIT_MASK is a previously defined variable to mask out the bit I now want to insert. I am not sure if I am misunderstanding how to use bitmasks, or if there is something more seriously wrong with my code. I realize that it would be too much to ask anyone to go through the whole thing in detail, but if anyone had any suggestions for what direction I should be thinking in to fix this, I'd appreciate it!
I draw your attention to how surprisingly low & is in this table:
$ cat /usr/share/misc/operator
Operator Associativity
-------------------------------------------------------------
() [] -> . left to right
! ~ ++ -- - (type) * & sizeof new delete right to left
->* .* left to right
* / % left to right
+ - left to right
<< >> left to right
< <= > >= left to right
== != left to right
& left to right
^ left to right
| left to right
&& left to right
|| left to right
?: right to left
= += -= *= /= %= <<= >>= &= ^= |= throw right to left
?: (C++, third operand) right to left
, left to right
$FreeBSD: src/share/misc/operator,v 1.2.22.1 2009/05/31 18:14:24 ed Exp $
Segfaults are extremely easy to find, assuming the right tools. Normally I just start gdb, look at the backtrace and know the reason at once. So, instead of going through your code (which I don't have), I just give you a general recipe to find any segfault (and many other errors):
If you are using GCC on a Linux system, I recommend you to (re-)compile your code with -Wall -g -ggdb -O0. -Wall will display interesting warnings, which are often the cause for undefined behavior or segfaults, and -g -ggdb adds some useful debugging information to your code and -O0 disables optimization (so that counter variables inside loops aren't optimized out and so on).
After that, you should start the debugger with gdb ./yourprog. Then write run to start your program. After your program has crashed, you will see something like "got segfault, program exited with ...'. Type bt which displays a backtrace (i.e. the stack of function calls including the line numbers and so on.). Just look at the list and search for the first top-most file which is part of your program. With that, you will now know the exact location (file and line number) where the segfault is happening, and normally its extremely easy to decide whats the cause if you know the exact line (just think about what might be unitialized or NULL in that statement).
Alternatively, you can also set a breakpoint yourfile.c:123 at that line (in this example line number 123) and display the content of your variables with print your_var_or_pointer. Examine all variables in that line - now you should finally know whats the cause :D
(PS: I can not give you advice how to debug in other environments such like Visual Studio and so on, but the idea is the same. They all come with an excellent debugger included!)

How to NOT use while() loops in verilog (for synthesis)?

I've gotten in the habit of developing a lot testbenches and use for() and while() loops for testing purpose. Thats fine. The problem is that I've taken this habit over to coding for circuits which should be synthesizable. XST and others refuse to synthesize code (without additional modification to synthesis parameters) such as:
while (num < test_number)
begin
.
.
.
num = num+1;
end
This is bad coding style because to the synthesizer test_num is an int with value 2^32! or it sees it as unbounded parameter. Either way, its a bad coding habit. But I'm so used to doing this in C and testbenches. What would be the equivalent synthesizable of code of the above code segment?
Thanks!
Synthesis tools vary but generally a loop can be synthesized so long as the number of iterations is known a to the synthesis tool. So,
for ( i = 0; i < 10; i = i + 1 )
is OK because the tool knows there are 10 loop iterations. But
reg [10:0] r;
for ( i = 0; i < r; i = i + 1 )
is not OK because r is a variable r's value is unknown at synthesis time.
Think of loops in RTL code as creating a known fixed number of copies of a piece of logic.
You need to have a clock to control it to start.
always #(posedge clk or negedge rst_n)
if (!rst_n)
num <= 32'b0; // or whatever your width is.
else
if (num < test_number)
num <= num + 1'b1;
If your synthesis tool does not support while or for loops, then don't use a loop. Just expand your code out.
wire [1:0] addr;
reg [3:0] wren;
always #(posedge clk) begin
wren[0] <= (addr == 2'd0);
wren[1] <= (addr == 2'd1);
wren[2] <= (addr == 2'd2);
wren[3] <= (addr == 2'd3);
end
I am unfamiliar with XST, but some synthesis tools do support loops (Synopsys, for example).

Resources