MQX 3.8 Mutex Example problem using K60

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

MQX 3.8 Mutex Example problem using K60

Jump to solution
1,877 Views
khoanguyen
Contributor I

Hi,

I'm new to MQX so I was running through the MQX 3.8 demos and after after running through the mutex example. My output was didn't show up as was stated with the readme that came with the demo. I am using code warrior 10.2 and MQX 3.8.1. I have not modified the code, which is below.

My procedure was:

File>New Project>MQX 3.8 project>Kinteis TWRK60n512 board>Example application>Basic examples> mutex example

the output on the terminal only displays the first string "Hello from Print task 1" but the second string doesn't display. From my understanding,

two tasks are created and both are put into the "Ready" state and when it runs the first string enters the "Active state" so it prints off and goes back into

the "Ready state." Since the second string was already in the Ready state, shouldn't it be next in line to send out the second string, due to the round robin scheduling?

On a side note, this example is meant to show multiple tasks running at the same time correct?

/**HEADER********************************************************************

*

* Copyright (c) 2008 Freescale Semiconductor;

* All Rights Reserved                      

*

* Copyright (c) 1989-2008 ARC International;

* All Rights Reserved

*

***************************************************************************

*

* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR

* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 

* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,

* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING

* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF

* THE POSSIBILITY OF SUCH DAMAGE.

*

**************************************************************************

*

* $FileName: main.c$

* $Version : 3.8.11.0$

* $Date    : Oct-4-2011$

*

* Comments:

*

*   This file contains the source for the mutex example program.

*

*END************************************************************************/

#include <mqx.h>

#include <bsp.h>

#include <mutex.h>

#if ! BSPCFG_ENABLE_IO_SUBSYSTEM

#error This application requires BSPCFG_ENABLE_IO_SUBSYSTEM defined non-zero in user_config.h. Please recompile BSP with this option.

#endif

#ifndef BSP_DEFAULT_IO_CHANNEL_DEFINED

#error This application requires BSP_DEFAULT_IO_CHANNEL to be not NULL. Please set corresponding BSPCFG_ENABLE_TTYx to non-zero in user_config.h and recompile BSP with this option.

#endif

#if ! MQX_HAS_TIME_SLICE

#error This application requires MQX_HAS_TIME_SLICE defined non-zero in user_config.h. Please recompile kernel with this option.

#endif

/* Task IDs */

#define MAIN_TASK     5

#define PRINT_TASK    6

extern void main_task(uint_32 initial_data);

extern void print_task(uint_32 initial_data);

const TASK_TEMPLATE_STRUCT  MQX_template_list[] =

{

   /* Task Index,   Function,   Stack,  Priority,   Name,       Attributes,          Param, Time Slice */

    { MAIN_TASK,    main_task,  1000,   8,          "main",     MQX_AUTO_START_TASK, 0,     0 },

    { PRINT_TASK,   print_task, 1000,   9,          "print",    MQX_TIME_SLICE_TASK, 0,     3 },

    { 0 }

};

MUTEX_STRUCT   print_mutex;

/*TASK*--------------------------------------------------------

*

* Task Name : main_task

* Comments  : This task creates a mutex and then two

*             instances of the print task.

*END*--------------------------------------------------------*/

void main_task

   (

      uint_32 initial_data

   )

{

   MUTEX_ATTR_STRUCT mutexattr;

   char*             string1 = "Hello from Print task 1\n";

   char*             string2 = "Print task 2 is alive\n";

   /* Initialize mutex attributes */

   if (_mutatr_init(&mutexattr) != MQX_OK) {

      printf("Initialize mutex attributes failed.\n");

      _task_block();

   }

  

   /* Initialize the mutex */

   if (_mutex_init(&print_mutex, &mutexattr) != MQX_OK) {

      printf("Initialize print mutex failed.\n");

      _task_block();

   }

   /* Create the print tasks */

   _task_create(0, PRINT_TASK, (uint_32)string1);

   _task_create(0, PRINT_TASK, (uint_32)string2);

   _task_block();

}  

/*TASK*--------------------------------------------------------

*

* Task Name : print_task

* Comments  : This task prints a message. It uses a mutex to

*             ensure I/O is not interleaved.

*END*--------------------------------------------------------*/

void print_task

   (

      uint_32 initial_data

   )

{

   while(TRUE) {

      if (_mutex_lock(&print_mutex) != MQX_OK) {

         printf("Mutex lock failed.\n");

         _task_block();

      }

      _io_puts((char *)initial_data);

      _mutex_unlock(&print_mutex);

   }

}

/* EOF */

0 Kudos
1 Solution
453 Views
DavidS
NXP Employee
NXP Employee

Hi Khoa,

I'm seeing a slight issue too with the mutex example.

My terminal shows the following:

 

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Print task 2 is alive

Hello from Print task 1

Print task 2 is alive

Looking at the code the print_task() should block to allow the other tasks at the same priority level to be able to run in round robin.

Here is what I added at the end of the infinite while(TRUE) loop in the print_task:

_time_delay(400); //DES test

 

Then the terminal output is:

Hello from Print task 1

Print task 2 is alive

Hello from Print task 1

Print task 2 is alive

I'll pass this along to our MQX Development team.

Regards,

David 

View solution in original post

0 Kudos
3 Replies
454 Views
DavidS
NXP Employee
NXP Employee

Hi Khoa,

I'm seeing a slight issue too with the mutex example.

My terminal shows the following:

 

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Hello from Print task 1

Print task 2 is alive

Hello from Print task 1

Print task 2 is alive

Looking at the code the print_task() should block to allow the other tasks at the same priority level to be able to run in round robin.

Here is what I added at the end of the infinite while(TRUE) loop in the print_task:

_time_delay(400); //DES test

 

Then the terminal output is:

Hello from Print task 1

Print task 2 is alive

Hello from Print task 1

Print task 2 is alive

I'll pass this along to our MQX Development team.

Regards,

David 

0 Kudos
453 Views
khoanguyen
Contributor I

Thank you so much, I've been trying to figure out why it went wrong. This fixed it!

I was wondering why the problem occurred since they have the same priority. Does this mean that I'll have to use the time delay for every tasks that creates multiple tasks with the same priority?

0 Kudos
453 Views
DavidS
NXP Employee
NXP Employee

Hi Khoa,

Please keep in mind the mqx/examples folder is really for learning concepts and not always showing full code.

In this case it should have a blocking RTOS call that will let the scheduler run the next task at the same priority.  So for round robin tasks to execute you have to either have a blocking call, or set the tasks to be time sliced.  It just depends on what the task is doing as to which to implemented.  Since we want to take turns outputting string text the blocking call (_time_delay(400)) was the way to go.

Regards,

David

0 Kudos