FRDM-K64F + USB + Host + msd (OSA_Start and OS_Task_Create functionality)

cancel
Showing results for 
Search instead for 
Did you mean: 

FRDM-K64F + USB + Host + msd (OSA_Start and OS_Task_Create functionality)

613 Views
Senior Contributor I

Hi everyone,

After battling with trying to configure my custom board with similar settings on the demo (msd_fat_demo), stumbled

trying to make it recognize the USB stick.  I finally discovered that the following two lines of code are needed for my

custom board to be able to work as the demo software.

Here are the two lines of code:

OS_Task_create(Task_Start, NULL, 4L, 4000L, "task_start", NULL);
OSA_Start();

I am not 100% sure about this but it seems that these two lines of code start a thread which locks the demo looking

into Task_Start() function.

1. Can someone confirm if this is true?

2. If the above question is true, if I remove these lines and call the Task_Start function at my own discretion could this 

    work as well? Please explain why?

3. If question #1 is false, then what are these two lines of code affecting the overall function of the demo?

Any help on this would be appreciated.

Thanks,

Neil

0 Kudos
6 Replies

13 Views
NXP TechSupport
NXP TechSupport

From bare metal,  OS_Task_create will execute Task_start , will finally call app_task, waiting for usb mass storage device to be attached.  this function won't lock the demo.

OS_START will execute  _usb_khci_task,  this function is used to handle KHCI controller message. In the bare metal environment, this function should be called periodically . In the RTOS environment, this function should be used
as a function entry to create a task.

0 Kudos

13 Views
Senior Contributor I

Hi Daniel,

Thank you for your explanation, but I am a little confused.  I am in a bare metal environment, no RTOS.  Let me show you what is happening

as I step through my code.

I call my Init() function in my main, it handles all the CPU register configuration and such.  It also calls my USB initialization code which

as in the example project calls the following functions:

OSA_Init();

OS_Task_create(USB_task, NULL, 4L, 4000L, "task_start", NULL);
OSA_Start();

int main(void)
{
Init();//Initialize

for (;;) {

Function call 1
Function call 2

etc...

}

Once OSA_Start(); line is executed, the software is tied here (inside fsl_os_abstraction.bm):

osa_status_t OSA_Start(void)
{
#if (TASK_MAX_NUM > 0)
g_curTask = &g_taskListHead;

for(;;)
{
if (g_curTask->p_func)
{
g_curTask->p_func(g_curTask->param);
}
g_curTask = g_curTask->next;
}

This executes the USB code which determines if a USB stick is introduced or not and then executes the fat_demo().

But if a USB stick is not introduced, if I place a breakpoint in my code say on Function call 1, it will never go there.  The 

program is stuck in the OSA_Start(void) function endlessly looping.  I need for it to check if a USB has been introduced and

if not, then continue to Function call 1, 2, etc.., then I will call the USB call again at a later time.

Let me know if you understand?

Thank you,

Neil

0 Kudos

13 Views
Senior Contributor I

Hi Daniel,

Here is a quick update and it seems to work, but I don't think this is the correct way of doing things.

int main(void)        <------------ my main
{
Init();//Initialize      <------------ my initialization code

 

for (;;) {

void Start_app(void *arg)
{

 Function call 1

 Function call 2

etc...

}

OS_Task_create(Start_app, NULL, 4L, 4000L, "Start_app", NULL);
OSA_Start();

}

Is there documentation on how OS_Task_create work and OSA_Start() work and how to use it?

Thanks,

Neil

0 Kudos

13 Views
NXP TechSupport
NXP TechSupport

Please check the following help page in your KSDK installation folder.

C:\Freescale\KSDK_1.3.0\doc\Kinetis SDK v.1.3.0 API Reference Manual\group__os__abstraction.html

and check  OS Abstraction Layer (OSA)

Kinetis SDK v.1.3 API Reference Manual: OS Abstraction Layer (OSA)

OSA initialize

osa_status_t OSA_Init (void)
 Initializes the RTOS services. More...
 
osa_status_t OSA_Start (void)
 Starts the RTOS. More...
 

OS Abstraction Layer

Overview

Operating System Abstraction layer (OSA) provides a common set of services for drivers and applications so that they can work with or without the operating system. OSA provides services that abstract most of the OS kernel functionality. These services can either be mapped to the target OS functions directly, or implemented by OSA when no OS is used (bare metal) or when the service does not exist in the target OS. Freescale Kinetis SDK implements the OS abstraction layer for MQX™ RTOS, Free RTOS, µC/OS, and for OS-less usage (bare metal). The bare metal OS abstraction implementation is selected as the default option.
OSA provides these services: task management, semaphore, mutex, event, message queue, memory allocator, critical section, and time functions.

Task Management

With OSA, applications can create and destroy tasks dynamically. These services are mapped to the task functions of RTOSes. For bare metal, a function poll mechanism simulates a task scheduler.
OSA supports task priorities 0~15, where priority 0 is the highest priority and priority 15 is the lowest priority.
To create a task, applications must prepare different resources on different RTOSes. For example, µC/OS-II and µC/OS-III need pre-allocated task stack while other RTOSes do not need this. The µC/OS-III needs pre-allocated task control block OS_TCB while other RTOSes do not. To mask the differences, OSA uses a macro OSA_TASK_DEFINE to prepare resources for task creation. Then the function OSA_TaskCreate() creates a task based on the resources. This method makes it easy to use a copy of code on different RTOSes. However, it is not mandatory to use the OSA_TASK_DEFINE. Applications can also prepare the resources manually. There are two methods to create a task:

  1. Use the OSA_TASK_DEFINE macro and the function OSA_TaskCreate(). The macro OSA_TASK_DEFINE declares a task handler and task stack statically. The function OSA_TaskCreate() creates task base-on the resources declared by OSA_TASK_DEFINE.
    This is an example code to create a task using method 1:
    // Define the task with entry function task_func.
    OSA_TASK_DEFINE(task_func, TASK_STACK_SIZE);
    void main(void)
    {
    task_param_t parameter;
    // Create the task.
    OSA_TaskCreate(task_func, // Task function.
    "my_task", // Task name.
    TASK_STACK_SIZE, // Stack size.
    task_func_stack, // Stack address.
    TASK_PRIO, // Task priority.
    parameter, // Parameter.
    false, // Use float register or not.
    &task_func_task_handler); // Task handler.
    // ...
    }
  2. Prepare resources manually, then use the function OSA_TaskCreate() to create a task.
    For example:
    task_param_t parameter;
    task_handler_t task_handler;
    #if defined(FSL_RTOS_UCOSII)
    task_stack_t task_stack[TASK_STACK_SIZE/sizeof(task_stack_t)];
    OSA_TaskCreate(task_func, // Task function.
    "my_task", // Task name.
    TASK_STACK_SIZE, // Stack size.
    task_stack, // Stack address.
    TASK_PRIO, // Task priority.
    parameter, // Parameter.
    false, // Use float register or not.
    &task_handler); // Task handler.
    #elif defined(FSL_RTOS_UCOSIII)
    task_stack_t task_stack[TASK_STACK_SIZE/sizeof(task_stack_t)];
    OS_TCB TCB_task;
    task_handler = &TCB_task;
    OSA_TaskCreate(task_func, // Task function.
    "my_task", // Task name.
    TASK_STACK_SIZE, // Stack size.
    task_stack, // Stack address.
    TASK_PRIO, // Task priority.
    parameter, // Parameter.
    false, // Use float register or not.
    &task_handler); // Task handler.
    #else // For MQX RTOS, FreeRTOS OS and bare metal.
    OSA_TaskCreate(task_func, // Task function.
    "my_task", // Task name.
    TASK_STACK_SIZE, // Stack size.
    NULL, // Stack address.
    TASK_PRIO, // Task priority.
    parameter, // Parameter.
    false, // Use float register or not.
    &task_handler); // Task handler.
    #endif
Method one is easy to use. The disadvantage is that one task function can only create one task instance. Method two can create multiple task instances using one task function, but the code must be divided by macros for different RTOSes. Applications can choose either method according to requirements.
After a task is created successfully, task handler can be used to manage the task, for example, get or set task priority, destroy task and so on.If task is not used any more, use the OSA_TaskDestroy() function to destroy the task. If the task function does not contain an infinite loop, or, in other words, the task function returns, call the OSA_TaskDestroy() function at the end of the task function.

13 Views
NXP TechSupport
NXP TechSupport

Hi Neil:

KSDK1.3 drivers are designed to work with or without an RTOS. The Operating System Abstraction layer (OSA) is designed and implemented for supported RTOS to provide a common set of service routines for drivers, integrated software solution, and upper-level applications. The usb host demo in KSDK1.3 supports FreeRTOS, MQX, ucOS, and bare metal.

The two lines ( OS_Task_create and OSA_Start ) are for all the three RTOSes and bare mental .  (For your case, you selected bare metal,  actually  you can choose FreeRTOS, maybe better ).

Regards

Daniel

0 Kudos

13 Views
Senior Contributor I

Hi everyone,

Here is an update on the issue I am trying to resolve.  I found similar code to a USB+Host+msd, which doesn't use the

two lines of code:

OS_Task_create(Task_Start, NULL, 4L, 4000L, "task_start", NULL);
OSA_Start();

instead in the main, it uses:

 

#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
#endif

which ties to the os_tasks.c->APP_USB_task and inside this function, it has the following:

#ifdef PEX_USE_RTOS
while (1) {
#endif

I noticed once again that APP_USB_task is locked in a while loop.

My question is, does this function need to be locked in a while loop?

Thank you,

Neil

0 Kudos