Is file I/O as USB host MQX friendly?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Is file I/O as USB host MQX friendly?

ソリューションへジャンプ
1,680件の閲覧回数
davepfaltzgraff
Senior Contributor I

I took the example found in C:\Freescale\KSDK_1.2.0\examples\frdmk22f\demo_apps\usb\host\msd\msd_fatfs\mqx\kds and have expanded it to include other tasks under MQX. The idea is to have small background tasks that use interrupts to collect data and then log these to a USB drive. However, it seems to me that when the USB drive is active it blocks all the other tasks from running.

 

The first clue was that even before plugging in a USB drive, I needed to add an OS_Time_delay() statement at the top of the primary loop of fat_demo() before the other tasks were able to run. That was OK. But, when I plug in a USB drive, it appears that the other tasks don't get a time slice.

 

Am I reading this right?

 

If so, what can I do to get the USB file I/O to be MQX friendly and share the idle time?

 

Thanks

ラベル(1)
0 件の賞賛
返信
1 解決策
1,501件の閲覧回数
Kan_Li
NXP TechSupport
NXP TechSupport

Hi David,

If this task is a lengthy and non-critical process, the most simple way is give it the lowest priority, so that it have the MCU when no other tasks is ready, but if you give it a higher priority, semaphore should be the right solution, when this task waits for a semaphore which is posted by the lowest task, it leave MCU for other tasks, and get ready immediately when it has the semaphore.

Hope that helps,


Have a nice weekend:smileyhappy:
Kan

Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

元の投稿で解決策を見る

0 件の賞賛
返信
5 返答(返信)
1,501件の閲覧回数
Kan_Li
NXP TechSupport
NXP TechSupport

Hi David,

How did you define other MQX tasks, would you please share your MQX_template_list[]? Thanks for your patience!


Have a great day,
Kan

Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 件の賞賛
返信
1,501件の閲覧回数
davepfaltzgraff
Senior Contributor I

Since I'm new to Kinetis and MQX and still low on the learning curve, I don't mind sharing. (That is if you don't mind that I might answer the wrong question!)

I took what was provided at the bottom of the main.c modules ad expanded it. Now my code is:

======

void Main_Task(uint32_t param);

TASK_TEMPLATE_STRUCT MQX_template_list[] =

{

    {  1L, Main_Task, 1024L, MQX_MAIN_TASK_PRIORITY, "Main", MQX_AUTO_START_TASK},

    {  0L, 0L, 0L, 0L, 0L, 0L}

};

static void Task_Start(void *arg) {

    APP_init();

    for (;; )    {

        APP_task();

    } /* Endfor */

}

void Main_Task(uint32_t param)

{

    Prime_Init();

    OSA_Init();

    NVIC_SetPriority(I2C0_IRQn, 6U);

    OSA_InstallIntHandler(I2C0_IRQn, MQX_I2C0_IRQHandler);

    dbg_uart_init();

    OS_Task_create(Task_Start, NULL, 9L, 4000L, "task_start", NULL);

    OS_Task_create(FrntPnl_App, NULL, 12L, 2048L, "FrntPanel", NULL);

    OS_Task_create(Prime_App, NULL, 10L, 4096L, "Prime", NULL);

    OSA_Start();

}

======

The Task_Start() was left alone with APP_Task() only being modified by the addition of the call to _time_delay_ticks(1) to get it to relinquish the processor.

PrimeInit() initializes the hardware I/O for this platform. The I2C bus is used to interface to an EEPROM and a digital potentiometer. The FrntPanel task uses the MQX timer to get a small chunk of time every 5mS to scan for a switch closure. Finally the Prime_App() task takes input from the FrntPanel() task (through a FIFO queue) and makes changes to the internal sate machine.

At this point all I/O to the USB disk is via the original code - either demo or throughput test. I have not started modifying that task for this application. Before starting that, I noticed that when running the throughput test my FrntPanel() task essentially stopped working. Maybe this is not a fair test.(?) In the final application, the bandwidth required to the USB disk is expected to be about 50KBytes per second. The throughput test reports around 550KBytes per second for the USB disk I have on hand.

0 件の賞賛
返信
1,501件の閲覧回数
Kan_Li
NXP TechSupport
NXP TechSupport

Hi David,

The tasks are defined correctly, I think the cause might be OS_Time_delay() didn't give enough time for other lower priority tasks or you put OS_Time_delay() in a wrong place. You know, the Main_task has the highest priority, and it is a while(1) style task, so OS_Time_delay() is needed to release the MCU for other tasks, but across this task, only fat_demo() or fat_throughput_test calls OS_Time_delay(1000), but they just run once controlled by fat_task_flag[i], so I am not sure how you added an OS_Time_delay() statement at the top of the primary loop of fat_demo(), but in my understanding, it should be added like below:

void APP_task(void)

{

.....

case USB_DEVICE_INTERFACE_OPENED:

            if (1 == fat_task_flag[i])

            {

                g_mass_device_new_index = i;

#if ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_BM) || ((OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)))// && !(defined (FSL_RTOS_MQX))))

#if THROUGHPUT_TEST_ENABLE

                fat_throughput_test();

#else

                fat_demo();

#endif

#else

                mfs_mount(i);

#endif

            }

            /* Disable flag to run FAT task */

            fat_task_flag[i] = 0;

            OS_Time_delay(1000);

........

}

So that Main_task still wait for 1000ms even when fat_task_flag[i] is zero, that allows enough time for other tasks to run when USB device is in the state of USB_DEVICE_INTERFACE_OPENED.

BTW, MQX in KSDK disables time slice at default, and FIFO schedule is used for all mqx tasks, that's why you found other tasks don't get a time slice, you may enable it by setting MQX_HAS_TIME_SLICE to 1, but I don't think it is the root cause for your issue, because even FIFO schedule can also allow lower priority tasks running by calling OS_Time_delay() or wait for some semaphore .

Hope that helps,


Have a great day,
Kan

Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,501件の閲覧回数
davepfaltzgraff
Senior Contributor I

Hi Kan,

As you noted, I am using the OS_Time_delay() to relinquish the processor. This always causes a minimum delay. What is the correct way to relinquish the processor but continue immediately if there are no other ready tasks? I would prefer this approach when I have a lengthy but non-critical process.

Thanks,

Dave

0 件の賞賛
返信
1,502件の閲覧回数
Kan_Li
NXP TechSupport
NXP TechSupport

Hi David,

If this task is a lengthy and non-critical process, the most simple way is give it the lowest priority, so that it have the MCU when no other tasks is ready, but if you give it a higher priority, semaphore should be the right solution, when this task waits for a semaphore which is posted by the lowest task, it leave MCU for other tasks, and get ready immediately when it has the semaphore.

Hope that helps,


Have a nice weekend:smileyhappy:
Kan

Freescale Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 件の賞賛
返信