watchdog for roundrobin tasks

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

watchdog for roundrobin tasks

跳至解决方案
2,749 次查看
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 项奖励
回复
1 解答
1,989 次查看
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 项奖励
回复
6 回复数
1,989 次查看
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 项奖励
回复
1,989 次查看
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 项奖励
回复
1,989 次查看
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 项奖励
回复
1,989 次查看
VinGanZ
Contributor III

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

0 项奖励
回复
1,990 次查看
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 项奖励
回复
1,989 次查看
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 项奖励
回复