watchdog for roundrobin tasks

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

watchdog for roundrobin tasks

Jump to solution
1,565 Views
amleng
Contributor IV

Hi ,

I wrote a sample code (please see the attachment) to use  watchdog timer for two roundrabin tasks. when I have only one task (e.g. only simulated_ISR_task_1) it  works well but when I add the second task  (simulated_ISR_task_2) it stops work. I've check the MQX  plugin tool. it didn't show any error or something wrong! any
suggestion?

 

Regards

 

#include <mqx.h>
#include <bsp.h>
#include <event.h>
#include <watchdog.h>

 

/* Task IDs */
#define MAIN_TASK 5
#define ISR_1_TASK 6
#define ISR_2_TASK 7

/* Function prototypes */
extern void simulated_ISR_task_1(uint_32);
extern void simulated_ISR_task_2(uint_32);
extern void main_task(uint_32);
extern void handle_watchdog_expiry_1(pointer);
extern void handle_watchdog_expiry_2(pointer);

const TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice */
{ MAIN_TASK, main_task, 2000, 8, "service", MQX_AUTO_START_TASK, 0, 0 },
{ ISR_1_TASK, simulated_ISR_task_1, 2000, 9, "simulated_ISR1", MQX_TIME_SLICE_TASK, 0, 1 },
{ ISR_2_TASK, simulated_ISR_task_2, 2000, 9, "simulated_ISR2", MQX_TIME_SLICE_TASK, 0, 1 },
{ 0 } };

/*TASK*-----------------------------------------------------
*
* Task Name : simulated_ISR_task
* Comments :
* This task opens a connection to the event group. After
* delaying, it sets the event bits.
*END*-----------------------------------------------------*/

void handle_watchdog_expiry_1(pointer td_ptr)
{
pointer event_ptr;
_mqx_uint event_bits;

printf("expire_1\n\r");
fflush(stdout);
}

void handle_watchdog_expiry_2(pointer td_ptr)
{
pointer event_ptr;
_mqx_uint event_bits;

printf("expire_2\n\r");
fflush(stdout);
}

void simulated_ISR_task_1(uint_32 initial_data)
{
pointer event_ptr;
MQX_TICK_STRUCT ticks;
_mqx_uint result;

_time_init_ticks(&ticks, 10);

result = _watchdog_create_component(BSP_TIMER_INTERRUPT_VECTOR,
handle_watchdog_expiry_1);

printf(" restart1 \n");

while (TRUE)
{
result = _watchdog_start_ticks(&ticks);
_time_delay(100);
_watchdog_stop();
}
}

void simulated_ISR_task_2(uint_32 initial_data)
{
pointer event_ptr;
MQX_TICK_STRUCT ticks;
_mqx_uint result;

_time_init_ticks(&ticks, 10);

result = _watchdog_create_component(BSP_TIMER_INTERRUPT_VECTOR,
handle_watchdog_expiry_2);

printf(" restart2 \n");

while (TRUE)
{
result = _watchdog_start_ticks(&ticks);
_time_delay(100);
_watchdog_stop();
}
}

/*TASK*-----------------------------------------------------
*
* Task Name : service_task
* Comments :
* This task creates an event group and the simulated_ISR_task
* task. It opens a connection to the event group and waits.
* After the appropriate event bit has been set, it clears
* the event bit and prints "Tick."
*END*-----------------------------------------------------*/

void main_task(uint_32 initial_data)
{
pointer event_ptr;
_task_id task_id_1, task_id_2;
_mqx_uint event_bits;

/* Create the ISR task */
task_id_1 = _task_create(0, ISR_1_TASK, 0);
if (task_id_1 == MQX_NULL_TASK_ID)
{
printf("Could not create simulated_ISR1_task \n");
_task_block();
}

/* Create the ISR task */
task_id_2 = _task_create(0, ISR_2_TASK, 0);
if (task_id_2 == MQX_NULL_TASK_ID)
{
printf("Could not create simulated_ISR2_task \n");
_task_block();
}

while (TRUE)
{
_time_delay(1000);
}
}

/* EOF */

 

0 Kudos
1 Solution
805 Views
c0170
Senior Contributor III

Hello amleng,

 

watchdog component can register only one function to the interrupt vector,  the second time it fails because it was initialized already.

 

   _lwsem_wait((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
   if (kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] != NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, MQX_OK);
      return(MQX_OK);
   } /* Endif */

 

Regards,

MartinK

View solution in original post

0 Kudos
6 Replies
805 Views
drummer
Contributor IV

I know its not related to your problem but I'm curious why are you using fflush(stdio)?

Why flush?

What does it do?

0 Kudos
805 Views
c0170
Senior Contributor III

Hi drummer,

 

fflush causes any buffered data in stream to be written to file. It returns 0 if it succeeded, otherwise EOF. You can check some reference webpages to find out more information.

 

Its fflush(stdout), it shall not be used with stdin because this behavior is undefined.

 

Regards,

MartinK

0 Kudos
805 Views
drummer
Contributor IV

thanks for your response.

I have a task that looks after serial communications on one of three serial ports of the MCF52259.

Since the hardware interface is RS485 I control the direction through an I/O that is controlled by a timer.

All I have to do is turn on the I/O and timer isr turns it off. I used to wait until the timer was finished through 10 millisecond

time delays but thought that fflush would be faster since I don't need to time out anymore.

Like this...

 

ioctl(rsi_enable_fh, GPIO_IOCTL_WRITE_LOG1, NULL);
_time_delay(1);
rsi_timer = ((no_bytes + 1) * 44000/rsi_baud);
_io_write (rsi_fh, snd_buf,no_bytes );
fflush(rsi_fh);
// while(rsi_timer > 0)
// _time_delay(10);

 

I let it run all last night and came back with the task in a "task queue blocked" and it never came back.

I am still using MQX version 3.6.

I suspect it was stuck in the fflush but can't be certain.

0 Kudos
805 Views
VinGanZ
Contributor III

i have also similar situation of "Task Queue Blocked". how did you solve it?

0 Kudos
806 Views
c0170
Senior Contributor III

Hello amleng,

 

watchdog component can register only one function to the interrupt vector,  the second time it fails because it was initialized already.

 

   _lwsem_wait((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
   if (kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] != NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, MQX_OK);
      return(MQX_OK);
   } /* Endif */

 

Regards,

MartinK

0 Kudos
805 Views
brentwilliams
Contributor II

Hi Martin,

I was trying to do the same thing.  In the MQX RTOS documentation you see the following:

     The MQX watchdog component provides a software watchdog for each task. If a single

     task starves or runs beyond certain timing constraints, the watchdog provides a way to

     detect the problem. Initially, the task starts its watchdog with a specific time value, and if

     the task fails to stop or restart the watchdog before that time expires, MQX calls a

     processor-unique, application-supplied expiry function that can initiate error recovery.

     Before a task can use the watchdog component, the application must explicitly create it

     by calling _watchdog_create_component() with the interrupt vector of the periodic

    timer device and a pointer to the function that MQX will call, if a watchdog expires.

The way it is written implies that you use the same interrupt vector each time (i.e. BSP_TIMER_INTERRUPT_VECTOR). 

So just for clarification for each task I have will need a separate timer interrupt vector associated with it.

Is that correct?

Thanks,

Brent

0 Kudos