Problem with the interrupt

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi all,

   

I'm not sure if I will explain well my problem, but I will try to do my best. I have written a function that do some things with the ESP8266 module to see if it will work fine. After that I have tried to move that function to the interrupt from the Timer to ensure that this function will be called every once in a while. Unfortunately after that The device stops working. All I can see is the fact that it tries to send the beginning of that function and then it freezes. I'm not sure what could possibly be the cause of that problem. Could someone help me? I'm attaching my whole project. The function which I'm talking about is void WIFI_SEND() in the main.c file And the interrupt is CY_ISR(InterruptHandler) also in that file.

0 Likes
10 Replies
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Two problems:

   
        
  • you do a long-running task in an interrupt, which is something you never should do
  •     
  • you don't clear the interrupt flag, which means even when the timer triggers again, the ISR won't be started
  •    
   

To solve #1, your ISR should just a flag variable (which must be volatile), and your main loop just checks for that flag.

0 Likes
Anonymous
Not applicable

Thanks for that, thought that It would be the best to do the sending during the interrupt, also my tutor said that I should have done that this way... guess he was wrong.

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

Well, you _can_ do it that way, but it can cause interesting problems. For example, when your UART uses an interrupt for itself (when you are using large buffers), this one might be blocked because your ISR already runs.

0 Likes
Anonymous
Not applicable

If the function is fast, then it will be fine to do it in the interrupt, but generally you only set flags, or set variable values in the interrupt, rather than calling an entire function.

   

Using a flag set in the interrupt to determine whether or not to run the function in main-line that you need timed is a safer way to do it.

   

Personally, I've written functions to run in the ISR, but generally I restrict it to start/stopping a timer, or setting a flag for starting a different function.

0 Likes
Anonymous
Not applicable

Thank You all for replies I did as You suggested and now it works 🙂

0 Likes
Anonymous
Not applicable

Actually I wrote that a little too soon. I'm not sure why when I put it in main like that:

   

if (flag_interruptclock == 1)
        {
            UART_UartPutString("wchodzi w mejnie w przerwanie\r\n");
            WIFI_SEND();
            flag_interruptclock = 0;
        }

   

it always waits for some data from the keyboard. The rest of the main remained the same

0 Likes
Anonymous
Not applicable

Note: CySoftwareReset() will reset all variables and code back to the start conditions, and thus calling it in your ISR will basically restart your program from main() again.

   

It could be the code is waiting for the UART response based on a large UART string being sent out? (Seems weird)

   

Are you calling any CySysPm... functions? They will put the CPU to sleep until an interrupt occurs.

0 Likes
Anonymous
Not applicable

Yes I know that it will reset whole program, I did it on purpose. I think that the problem right now is that when in main at some point code goes into load_buff function and waits there until some command from the keyboard will be sent, but I'm not sure. And I would like to make something like "if key pressed go to load_buff else ignore it" so that it will not freeze at that moment. I'm not putting CPU to sleep 

0 Likes
Anonymous
Not applicable

In your load_buff function, it blocks until a valid/visible character is received. If you have it exit the while loop or not enter it when the uart character value returned is 0, then it shouldn't block on it.

   

Change load_buff() to this:

   

void load_buff(uint8 *buffer) {

   

uint8 ch = 0;

   

uint8 check = 0;

   

uint8 cnt = 0;

   

while(check == 0){
        ch = UART_UartGetChar();
        if(ch != 0u && is_char_visible(ch)){
            buffer[cnt]=ch;
            if(cnt<CMD_BUFF_LEN){
                cnt++;
            }
            if(ch == CR_CHAR_VALUE){
                buffer[--cnt]=0;
                check=1;
            }
        } else if (ch == 0) {

   

            //No vali uart character, return from read loop

   

            check = 1;

   

        }
    }

   

}

0 Likes
Anonymous
Not applicable

Yes thank You for that, actually I wrote else break; instead of what You propose few days ago and it works just fine so I think it will stay that way 🙂

0 Likes