2

我正在尝试在具有 freeRTOS 的 CC3200 wifi (TI) lauchpad 板上构建具有多项任务的系统。我在我的主要任务中创建了三个任务:

    // Create task1
    osi_TaskCreate( task1, ( signed portCHAR * ) "task1",
            OSI_STACK_SIZE, NULL, 1, NULL );

    //Two more tasks

所有三个任务都具有相同的优先级 (1),因此我希望所有三个任务都将获得相同数量的处理器时间。

每个任务只负责在 uart 端口上打印其名称:

void task1( void *pvParameters )
{
    while(1)
    {
        Report("task1");
    }
}

不幸的是,我只看到任务 1 一直在打印它的名称。我应该怎么做才能解决这个问题?

4

2 回答 2

4

就我对 FreeRTOS 的记忆而言,如果您确实创建了具有相同优先级的所有线程,那么如果您不定义 USE_TIME_SLICING 或定义它并将其设置为“1”,那么您只会获得您想要的平等共享。

当涉及到多个线程竞争对硬件资源(或共享内存资源)的访问时,您总是希望以某种方式控制对它的访问。在这种情况下,最简单(虽然不是最快)的选项是使用互斥锁,FreeRTOS 也有二进制信号量,可以完成同样的事情,而且速度可能会稍微快一些。通常,尽管互斥锁和二进制信号量是可以互换的。对于两者的详细信息,我会去阅读关于它们的 FreeRTOS 文档,它应该可以解决问题。

如果你原谅伪代码,你希望每个线程都按照以下方式做一些事情

createMutex(UART_Lock)

void task1
{
    while(1)
    {
       if(GetLockOnMutex(UART_Lock))
       {
          PrintToUART();
          ReleaseMutex();
       }
    }
}

void task2
{
    while(1)
    {
       if(GetLockOnMutex(UART_Lock))
       {
          PrintToUART();
          ReleaseMutex();
       }
    }
}

void task3
{
    while(1)
    {
       if(GetLockOnMutex(UART_Lock))
       {
          PrintToUART();
          ReleaseMutex();
       }
    }
}

因此,当每个线程进入上下文时,它会尝试锁定互斥锁,该互斥锁用于限制对 UART 的访问。如果成功,那么它将发送一些东西,并且只有当打印函数返回时(可能超过多个时间片),它才会释放 UART 上的锁,以便另一个线程尝试获取。如果一个线程无法获得锁,那么它会再次尝试,直到它的时间片结束。您可能有一个无法获得锁的线程让自己重新进入睡眠状态,直到它下一次进入上下文,但这只有在您的 CPU 非常繁忙并且您必须考虑您的任务是否真的可以调度时才真正重要。

基本上,如果您不控制对 UART 的访问,并且无法保证在给定时间片内线程完成对 UART 的访问,那么调度程序可以抢占未完成的线程,其他人可以尝试使用UART。

假设 UART 发送缓冲区可能会在您的情况下对其进行排序是合乎逻辑的,但您真的不想依赖它,因为它只有这么大,没有什么可以阻止一个线程完全填满它。

于 2014-11-27T14:47:31.723 回答
1

谢谢!

我实现了如下:

void vTestTask1( void *pvParameters )
{
    while(1) {
        if(xSemaphoreTake(uart_lock, 1000)) {
            // Use Guarded Resource
            Report("1");
            // Give Semaphore back:
            xSemaphoreGive(uart_lock);
        }
        vTaskDelay(1000);
    }
}
void vTestTask2( void *pvParameters )
{
    while(1) {
        if(xSemaphoreTake(uart_lock, 1000)) {
            // Use Guarded Resource
            Report("2");
            // Give Semaphore back:
            xSemaphoreGive(uart_lock);
        }
        vTaskDelay(1000);
    }
}

它工作完美,因为它通过 uart 打印 121212 等。

于 2014-11-28T12:54:52.863 回答