我正在尝试在带有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一直打印它的名字。我该怎么做才能解决这个问题?
答案 0 :(得分: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发送缓冲区可能会在你的情况下对其进行排序,但你真的不想依赖它,因为它只是如此之大而且没有什么可以阻止一个线程完全填满。
答案 1 :(得分:1)
日Thnx!
我按如下方式实现了这个:
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等。