RISCV External Interrupt Handler with FreeRtos

Dear All,
I’m facing a problem during integrating my code with FreeRtos plateform.
I’m using External interrupt handler on RISCV with FPGA.

The External interrupt Handler generate interrupt on change with 3 push buttons.

First push button initialize, the second will turn on the power supplies for my project and third will Resume the 3-tasks, which are first suspended in main function.
if i switch off the 3rd push button then the task will be Suspended.
The problem is if i turn on all the push buttons and task runs then there is no error, but if i turn on and off push buttons either it’s 1st or 3rd( i mean to say if i generate more interrupt by using external interrupt Handler) then task are failed and halted.
i can not understand what is the problem.
without Enabling the Hall_enable interrupts and without push buttons, the tasks work properly.
please guide me.
Thank you very much

More detail is needed to know where to begin - but to start with can you please confirm whether you are having a problem generating interrupt, executing interrupt handlers, or designing your FreeRTOS application to work with the interrupt handlers?

Hello Richard,
I’m having a problem to develop FreeRtos application to work with RISCV External interrupt handler.
Thank you

Can you confirm that you have the external interrupts working in that when you press the buttons the interrupts execute?

If so (I think that is what you mean), then is the problem that your interrupt handler is supposed to unblock a task but isn’t? If so then please post the interrupt handler code and the task code (cut down the task code just to show the relevant bits).

Hello Richard,
Thank you very much for your reply.
Yes the external interrupts are working and i also have 3 LED’S for each button to show interrupts.
Yes i can explain the problem with a code.

i have 3 tasks
let’s say 1,2 and 3

if interrupt from button 1 or 2(which will turn ON or OFF 1st and 2nd LED) come then
all three tasks are suspended.
else if interrupt on 3rd button(which will turn on 3rd LED) arrive then it will resume all the tasks.

SO when all 3 LED’s are ON then tasks are resume.
what i observe is if all 3 LED’s are ON then everything is working properly, i checked with printf but if i switch off 3rd LED(or all) then tasks are suspended, but after 2 or 3 minutes if i resume all tasks then the printf comes very fast from each tasks and then printf slow down(according to given delay). sometimes task continue to run but most of the time it failed.
i thinks when task are suspended printf continue to execute and when i resume the task then printf will show on console speedily.

i’m using semaphore mutex for each task and VTaskDelay for the task delay.

 int main()
   {
            fsm _fsm=
            {
                    _device,
                    _algorithm,

            };

              xTaskCreate(Task1, "Task1",1024, &_fsm, 5, NULL);
              xTaskCreate(Task2, "Task2", 300, &_device, 4,NULL);
              xTaskCreate(Task3, "Task3", 512, &_fsm, 3, NULL);

  PLIC_init();
  PLIC_SetPriority(External_2_IRQn, 1);
  PLIC_EnableIRQ(External_2_IRQn);
  HAL_enable_interrupts();
  vTaskStartScheduler();
while(1)
{

}

 }

 void External_2_IRQHandler()

 {

     interrupt_state= GPIO_get_irq(&g_gpio_in);

      bit_state=GPIO_get_outputs(&g_gpio_out);
switch(interrupt_state)
    {

case 1:
           if ( bit_state==0x00)

                      {
    bit_state=0x1;
                   }

     else if (bit_state==0x01)
 {
             bit_state=0x0;
       }

         break;

The same code for interrupt 2 and 4 with LED 2 and 3
and on end just write the gpio out

             } //switch

           GPIO_set_outputs(&g_gpio_out, bit_state);

     } //externa_2_handler


 void Task1(fsm _fsm)
 {

while(1)
{
if( gatekeeper != NULL )
{
if (xSemaphoreTake(gatekeeper,12))
     {

 if (bit_state==0x7)
    {
Read_data(_fsm._device);

    }

 if (bit_state==0x1 || bit_state==0x2)
    {
        printf("task 1 is doing nothing \n");
    }

 xSemaphoreGive(gatekeeper);
 }
else
{
   printf("task 1 is failed \n");
}
}
   vTaskDelay(6);
            } 
}

The other two tasks(Task2 and Task3) have the same logic but they will wait for semaphore 6msec

       (xSemaphoreTake(gatekeeper,6)

and both have

        vTaskDelay(6);

For three tasks the delay is right with respect to synchronization…?
because the 1st task will with for 12msec to wait for semaphore and delay 6msec to avoid to call the task1 again and Task2, and Task3 accept the semaphore in 6 msec and after 12msec the Task1 execute again…?

as i have already said if i switch off 3rd button and after 3 minutes i resume all tasks then the printf comes very fast more than the sampling time and Task2 and 3 failed because Task1 is already failed and both are not taking semaphore on a predefined time.
EDITED

I’m using UDP Stack for Ethernet communication.
I came to know after 3 or 4 minuts i received this info:

Info: No packet was received until timeout.

with respect to the Error Number

pdFREERTOS_ERRNO_EWOULDBLOCK which mean

“If no bytes are received before the configured block time expires then -pdFREERTOS_ERRNO_EWOULDBLOCK is returned.”

This is my Task1 and if this task failed it will wait for timeout to receive and until then the other Task2 and Task 3 are also failed because of not getting semaphore and they will show again printf with a Task1 timeout INFO.

How we can solve this problem, i tried to by changing the receive time but it’s giving the same error.

Thank you very much.

The logic is still not clear to me, but a few points to start off with:

_fsm is allocated on the tack of main(). That will get overwritten unless configISR_STACK_SIZE_WORDS is defined. See here: https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html#RISC-V-INTERRUPT_STACK

I would recommend removing everything from the application other than the code logic that services the interrupts and blocks/unblocks tasks. Once you get that logic behaving as you intend you can add in the other stuff.

Have you tried your code without printf()? printf() being non re-entrant, or using some kind of buffering, or unexpectedly calling malloc(), or something else might actually be the cause of your issues.