in this both the function why it is require to do WATCHDOG_RESET()? - c

void NS16550_putc(NS16550_t com_port, char c)
{
while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0);
//write to the THR
serial_out(c, &com_port->thr);
if (c == '\n')
//why do we require to call this watch dog reset
WATCHDOG_RESET();
}
char NS16550_getc(NS16550_t com_port)
{
while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
#ifdef CONFIG_USB_TTY
extern void usbtty_poll(void);
usbtty_poll();
#endif
//why do we require to call this watch dog reset
WATCHDOG_RESET();
}
//return the rbr value
return serial_in(&com_port->rbr);
}

I don't know the context of this code.
But most likely it's because you don't want your operation to last so long that the watchdog times out (and resets your device...)
for example,
while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
#ifdef CONFIG_USB_TTY
extern void usbtty_poll(void);
usbtty_poll();
#endif
//why do we require to call this watch dog reset
WATCHDOG_RESET();
}
In the above code, you're validating some condition repeatedly in this while loop, now this loop may run for a long time and if you don't reset your watchdog timer (or kick your watchdog), the watchdog'll likely time out eventually.

Related

"Result of function call is ignored": CodeWarrior. Why is it ignored?

Here's a pseudo-code(ish) that I'm trying to build.
This is the interrupt function. When switch 2 is pressed, the potval = 1. When switch 3 is pressed, potval = 2. Every time the switch is pressed, the potval is updated.
void interruptJ_function (void){ //if i change to int interruptJ_function, it says that it was expecting a void function
if(Pim.pifj.byte & 0x01) { //switch2 is pressed
potval = 1;
Pim.pifj.byte |= 0x01; //clear interrupt bit
//return potval; //doing this says the result is returned in void-result-function
}
else if(Pim.pifj.byte & 0x02) { //switch 3 is pressed
potval = 2;
Pim.pifj.byte |= 0x02; //clear interrupt bit
//return potval;
}
//return potval;
}
Here's the main.c.
int potval;
unsigned int i;
void main ()
{
adt(potval); //Warning: Result of function call is ignored
for (;;); //recurring loop until interrupt initiated
}
int adt(int potval, unsigned int i) {
if(potval == 1){
//for (;;){
while(potval==1){ //breaks when potval =2
i= Atd0.atddr[0].d10; //ATD bits
light7segment(i); // ATD changes number on 7segment display
m_delay(50);
}
}
else if (potval == 2){
light7segment(10); //ATD turns off 7segment display
}
}
Codewarrior gives this warning when you call a function with a return value but ignore checking that return value. As you do here:
adt(potval);
Normally the solution would be (void) adt(potval);.
Not in this case though, because the reason is a much more severe bug, namely that the function int adt(int potval, unsigned int i) doesn't return a value. On most Codewarrior target systems, it means that the caller code will grab some random value out of an accumulator, then run off into the woods. This bug could have be avoided if you had paid attention when the compiler said "return expected" in a different warning.

Delay within a timer (what is the correct approach)

I'm in a pickle regarding concepts relating to timers. How can I can I operate a "delay" inside a timer? This is the best way I can frame the question knowing full well what I'm trying to do is nonsense. The objective is: I wish to test the pinState condition 2 times (once initially and then 4 seconds later) but this all needs to happen periodically (hence a timer).
The platform is NodeMCU running a WiFi (ESP8266 chip) and coding done inside Arduino IDE.
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;
char auth[] = "x"; //Auth code sent via Email
char ssid[] = "x"; //Wifi name
char pass[] = "x"; //Wifi Password
int flag=0;
void notifyOnFire()
{
int pinState = digitalRead(D1);
if (pinState==0 && flag==0) {
delay(4000);
int pinStateAgain = digitalRead(D1);
if (pinStateAgain==0) {
Serial.println("Alarm has gone off");
Blynk.notify("House Alarm!!!");
flag=1;
}
}
else if (pinState==1)
{
flag=0;
}
}
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
pinMode(D1,INPUT_PULLUP);
timer.setInterval(1000L,notifyOnFire);
}
void loop()
{
//Serial.println(WiFi.localIP());
Blynk.run();
timer.run();
}
an easy fix would be to set the periodicity of the timer to be 4000L timer.setInterval(4000L,notifyOnFire); and in notifyOnFire use a static variable and toggle its value whenever notifyOnFire is called
void notifyOnFire()
{
static char state = 0;
if( state == 0)
{
/* Write here the code you need to be executed before the 4 sec delay */
state = 1;
}
else
{
/* Write here the code you need to be executed after the 4 sec delay */
state = 0;
}
}
The nice thing about static variables is that they are initialized only once at compile time and they retain their values after the scope of code changes (In this case function notifyOnFire exits).

Global variable being reset after each call

In my project I'm using a global variable but it's not working as expected because it is initialized everytime it's executed and honestly I don't know what could be going on.
The variable is cookingSignalReceived.
The program is structured as follows:
//File Controller.c:
while (1)
{
Controller_Run_State_Machine();
}
void Controller_Run_State_Machine(void)
{
/* start of activity code */
Inputs_ReadSensors();
Comms_CheckReceivedData();
Controller_UpdateSTM();
}
The problem is inside Comms file:
//File Comms.c
uint8_t cookingSignalReceived = 0;
void Comms_CheckReceivedData(void)
{
/* start of activity code */
uint8_t uartDataAvailable = Comms_R_UART0_checkIfDataAvailable();
if (uartDataAvailable == 1)
{
Comms_ParseReceivedCommand();
}
}
void Comms_ParseReceivedCommand(void)
{
/* start of activity code */
/* UserCode{499E2AA6-1F61-4753-9221-77F85E7B5D92}:YjMeKqu95e */
uint8_t CRC_check_OK = 0;
uint8_t* buffer;
/* UserCode{499E2AA6-1F61-4753-9221-77F85E7B5D92} */
Comms_R_UART0_resetFlag_dataAvailable();
buffer = Comms_R_UART0_getBuffer();
CRC_check_OK = Comms_crcCheck(buffer);
if (CRC_check_OK == 1)
{
Comms_processMessage(buffer); //<-- Variable is used in this function
}
}
Global variable is used inside Comms_processMessage(). The issue is that every time that the function is called, the global variable is set to the initial value. Do you find anything strange here?
EDITED:
void Comms_processMessage(uint8_t* buffer)
{
/* UserCode{BCB3B791-2DF9-492b-B53B-6FEB24BD8F77}:eyCoSfmCKb */
uint8_t message = buffer[0];
uint8_t param1 = buffer[1];
uint8_t param2 = buffer[2];
//---------------------------------------------------------------------
// START COOKING 1ST STEP REQUEST
//---------------------------------------------------------------------
if (message == MSG_COOK_1ST && param1 == START_PARAM)
{
// Wait for second frame
cookingSignalReceived = 1;
#ifdef DEBUG
R_UART0_Send("Cook 1st step!!", sizeof(char) * 15);
#endif
}
//---------------------------------------------------------------------
// START COOKING 2ND STEP REQUEST
//---------------------------------------------------------------------
else if (message == MSG_COOK_2ND && param1 == START_PARAM)
{
// Wait for second frame
if (cookingSignalReceived == 1)
{
Controller_signalsBufferEnqueue(cookingSignal);
}
#ifdef DEBUG
R_UART0_Send("Cook 2nd step!!", sizeof(char) * 15);
#endif
}
}
Note that my original idea was to use a local static variable but I was having the same issue so I tried with a global variable.
In certain cases the MCUs restart because unrecoverable errors or bad hardware settings. This should be the problem! A cause of this MCUs behaviour may be also bad pointers management.

How to use global variables on a state machine

I made this state machine :
enum states { STATE_ENTRY, STATE_....} current_state;
enum events { EVENT_OK, EVENT_FAIL,EVENT_REPEAT, MAX_EVENTS } event;
void (*const state_table [MAX_STATES][MAX_EVENTS]) (void) = {
{ action_entry , action_entry_fail , action_entry_repeat }, /*
procedures for state 1 */
......}
void main (void){
event = get_new_event (); /* get the next event to process */
if (((event >= 0) && (event < MAX_EVENTS))
&& ((current_state >= 0) && (current_state < MAX_STATES))) {
state_table [current_state][event] (); /* call the action procedure */
printf("OK 0");
} else {
/* invalid event/state - handle appropriately */
}
}
When I modify a global variable in one state the global variable remain the same , and I need that variable in all the states . Do you now what could be the problem ?
My Global variable is this structure:
#if (CPU_TYPE == CPU_TYPE_32)
typedef uint32_t word;
#define word_length 32
typedef struct BigNumber {
word words[64];
} BigNumber;
#elif (CPU_TYPE == CPU_TYPE_16)
typedef uint16_t word;
#define word_length 16
typedef struct BigNumber {
word words[128];
} BigNumber;
#else
#error Unsupported CPU_TYPE
#endif
BigNumber number1 , number2;
Here is how I modify:
//iterator is a number from where I start to modify,
//I already modified on the same way up to the iterator
for(i=iterator+1;i<32;i++){
nr_rand1=661;
nr_rand2=1601;
nr_rand3=1873;
number2.words[i]=(nr_rand1<<21) | (nr_rand2<<11) | (nr_rand3);
}
This is just in case you may want to change your approach for defining the FSM. I'll show you with an example; say you have the following FSM:
You may represent it as:
void function process() {
fsm {
fsmSTATE(S) {
/* do your entry actions heare */
event = getevent();
/* do you actions here */
if (event.char == 'a') fsmGOTO(A);
else fsmGOTO(E);
}
fsmSTATE(A) {
event = getevent();
if (event.char == 'b' || event.char == 'B') fsmGOTO(B);
else fsmGOTO(E);
}
fsmSTATE(B) {
event = getevent();
if (event.char == 'a' ) fsmGOTO(A);
else fsmGOTO(E);
}
fsmSTATE(E) {
/* done with the FSM. Bye bye! */
}
}
}
I do claim (but I believe someone will disagree) that this is simpler, much more readable and directly conveys the structure of the FSM than using a table. Even if I didn't put the image, drawing the FSM diagram would be rather easy.
To get this you just have to define the fsmXXX stuff as follows:
#define fsm
#define fsmGOTO(x) goto fsm_state_##x
#define fsmSTATE(x) fsm_state_##x :
Regarding the code that changese number2:
for(i=iterator+1;i<32;i){
nr_rand1=661;
nr_rand2=1601;
nr_rand3=1873;
number2.words[i]=(nr_rand1<<21) | (nr_rand2<<11) | (nr_rand3);
}
I can't fail to note that:
i is never incremented, so just one element of the array is changed (iterator+1) over an infinite loop;
even if i would be incremented, only the a portion of the words array it's changed depending on the value of iterator (but this might be the intended behaviour).
unless iterator can be -1, the element words[0] is never changed (again this could be the intended behaviour).
I would check if this is really what you intended to do.
If you're sure that it's just a visibility problem (since you said that when you declare it as local it worked as expected), the only other thing that I can think of is that you have the functions in one file and the main (or where you do your checks) in another.
Then you include the same .h header in both files and you end up (due to the linker you're using) with two different number2 because you did not declare it as extern in one of the two files.
Your compiler (or, better, the linker) should have (at least) warned you about this, did you check the compilation messages?
This is not an answer - rather it is a comment. But it is too big to fit the comment field so I post it here for now.
The code posted in the question is not sufficient to find the root cause. You need to post a minimal but complete example that shows the problem.
Something like:
#include<stdio.h>
#include<stdlib.h>
#include <stdint.h>
typedef uint32_t word;
#define word_length 32
typedef struct BigNumber {
word words[4];
} BigNumber;
BigNumber number2;
enum states { STATE_0, STATE_1} current_state;
enum events { EVENT_A, EVENT_B } event;
void f1(void)
{
int i;
current_state = STATE_1;
for (i=0; i<4; ++i) number2.words[i] = i;
}
void f2(void)
{
int i;
current_state = STATE_0;
for (i=0; i<4; ++i) number2.words[i] = 42 + i*i;
}
void (*const state_table [2][2]) (void) =
{
{ f1 , f1 },
{ f2 , f2 }
};
int main (void){
current_state = STATE_0;
event = EVENT_A;
state_table [current_state][event] (); /* call the action procedure */
printf("%u %u %u %u\n", number2.words[0], number2.words[1], number2.words[2], number2.words[3]);
event = EVENT_B;
state_table [current_state][event] (); /* call the action procedure */
printf("%u %u %u %u\n", number2.words[0], number2.words[1], number2.words[2], number2.words[3]);
return 0;
}
The above can be considered minimal and complete. Now update this code with a few of your own functions and post that as the question (if it still fails).
My code doesn't fail.
Output:
0 1 2 3
42 43 46 51

Function pointers in FSM

HI.. I want an example of how to implement FSM using function pointers in C.
See this simple example on how to implement a finite state machine in C.
An example is too big to write as an answer here.
Here's an existing example, which I found by Googling for state machine c "function pointer": Implementing Efficient State Machines
Here is a little demo of using function pointers in ARDUINO. This example does not allow for concurrency. It perfectly transferable to normal C if make write the setup and loop inside main()
Each state is a void() function. Each state function is responsible for reading input and setting output. When this is done the function should return immediately. It will be called again directly. The function is also responsible for state-transition by calling the leave function immediately before returning. Each state function should have a static long variable for timekeeping.
A global variable state is set to point to the initial state in the setup routine.
I wanted timekeeping in the different states so i implemented the state transitions by 2 functions:
void enter(long *stateTime), this should be called the very first thing when entering the state functions. It activates the state if inactive end keeps time.
void leave(void (*next)(), long *statetime), this changes the global state pointer and deactivates the current state.
void (*state)();//function pointer for state machine
long prevMillis = 0;//timekeeper
const int LEDPIN = 13;
int counter1 = 0;
void enter(long *statetime){
if(*statetime==-1){//check for passive state
prevMillis = millis();//set timemark when entering state
}//if(statetime==0)
*statetime = millis()-prevMillis;//keep time
}//enter()
void leave(void (*next)(), long *statetime){
*statetime=-1;//set state to passive
state=next;//point to next state
}//leave()
void off500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>499){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off500ms()
void off2s(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, LOW);
if(stateMillis>1999){//check if time is up
leave(on500ms, &stateMillis);
}//if(stateMillis>499)
}//off2s()
void on500ms(){
static long stateMillis;//timer for this state
enter(&stateMillis);//update timer
digitalWrite(LEDPIN, HIGH);
if(stateMillis >499){//time is up
if(++counter1==6){//number of blinks
leave(off2s, &stateMillis);
counter1=0;//reset counter
}else{//if(++counter1==6)
leave(off500ms, &stateMillis);
}//if(++counter1==6)
}//if(stateMills>499)
}//on500ms
void setup(){
pinMode(LEDPIN, OUTPUT);
state = on500ms;//set initial state
}/setup()
void loop(){
state();//start FSM
}//loop
I would say initialize a array of pointers to event handlers. So each element of a array is a function pointer to a particular event which is part of an enum.
if foo is your array of function pointers which is initialized to event then call foo[event]() when any event occurs.
Try coding for calling a function pointer first, next you can move to array and come back to SO if there are more doubts.
For a start you can read about function pointers here.
State transtion code can be utilize either by array or switch case. Written under if else directive.
#include <stdio.h>
#include <stdlib.h>
int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);
enum state_codes lookup_transitions(enum state_codes, enum ret_codes);
/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};
enum ret_codes { ok, fail, repeat};
struct transition {
enum state_codes src_state;
enum ret_codes ret_code;
enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
{entry, ok, foo},
{entry, fail, end},
{foo, ok, bar},
{foo, fail, end},
{foo, repeat, foo},
{bar, ok, end},
{bar, fail, end},
{bar, repeat, foo}};
int main(int argc, char *argv[]) {
enum state_codes cur_state = entry;
enum ret_codes rc;
int (* state_fun)(void);
for (;;) {
state_fun = state[cur_state];
rc = state_fun();
if (end == cur_state)
break;
cur_state = lookup_transitions(cur_state, rc);
}
return EXIT_SUCCESS;
}
/*
* lookup_transition() function has time complexity of class O(n).
* We can optimize it.
* */
enum state_codes
lookup_transitions(enum state_codes cur_state, enum ret_codes rc)
{
#if 0
switch (cur_state) {
case entry:
cur_state = ((rc == ok) ? (foo) : (end));
break;
case foo:
cur_state = ((rc == ok) ? (bar) : ((rc == fail) ? (end) : (foo)));
break;
default:
cur_state = ((rc == ok) ? (end) : ((rc == fail) ? (end) : (foo)));
break;
}
return cur_state;
#else
char arr_size = (sizeof(state_transitions) / sizeof(state_transitions[0])); /* This can be shifted to main function to avoid redundant job. */
char count;
for (count = 0; count < arr_size; count++) {
if ((state_transitions[count].src_state == cur_state) && (state_transitions[count].ret_code == rc)) {
return (state_transitions[count].dst_state);
}
}
#endif
}
int entry_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN ENTRY STATE.\nEnter 0/1: ");
scanf("%d", &st);
rc = ((st == 1) ? (fail) : (ok));
return rc;
}
int foo_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN FOO STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int bar_state(void)
{
int st;
enum ret_codes rc;
printf("YOU ARE IN BAR STATE.\nEnter 0/1/2: ");
scanf("%d", &st);
rc = ((st == 0) ? (ok) : ((st == 2) ? (repeat) : (fail)));
return rc;
}
int exit_state(void)
{
printf("YOU ARE IN EXIT STATE.\n");
exit(EXIT_SUCCESS);
}

Resources