This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/AWR1642:任务和邮箱

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/sensors-group/sensors/f/sensors-forum/655508/rtos-awr1642-task-and-mailbox

器件型号:AWR1642
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

您好,

代码如下:

#include
#include
#include
#include
#include
#include
#include
#include


#define NUMMSGS 3 /*消息数*/


#define TIMEOUT 10.


typedef 结构 MsgObj{
int id;/* writer task id */
char val;/*消息值*/
} MsgObj,*Msg;


空读卡器(空);
空写入器(int id_arg);


mailbox_handle mbox;


/*
*==== main ====
*
void main()

Task_Params taskParams;
Task_handle myTsk0、myTski;
Mailbox_Params mboxParams;


UINT I;
ERROR_Block EB;


ERROR_INIT (&EB);


/*create 1 reader_task with priority 2*/
Task_Params_init (&taskParams);
// taskParams.STACKSIZE = 4*1024;
taskParams.priority = 2;


myTsk0=Task_create ((Task_Functr)读取器、&taskParams、&EB);
if (myTsk0=NULL)
system_abort ("读取器创建失败");


Mailbox_Params_init (&mboxParams);
mbox = Mailbox_create (sizeof (MsgObj)、2、和 mboxParams、&EB);


if (mbox=NULL)
system_abort ("创建邮箱失败");


/*创建优先级为2*/的3个任务
/*重复使用 taskParams */
taskParams.priority=2;
for (i=0;i<3;i++)

taskParams.arg0=i;
myTski=Task_create ((Task_FuncPtr) writer、taskParams、&EB);
if (myTski=NULL)
system_abort ("写入器创建失败");


/*启动 SYS/BIOS*/
system_flush();
BIOS_start();



/*
*==== 读取器====
*
空读取器(空)

MsgObj msg;


while (1)

/*等待 writer()发布邮箱*/
if (Mailbox_pend (mbox、&msg、BIOS_wait_forever)=0)//BIOS_wait_forever

System_printf ("MBX_PEND 超时()\n"MB 超时);
system_flush();
中断;


/*打印值*/
system_printf ("从(%d)读取'%c'。\n"、msg.val、msg.id);
system_flush();

System_printf ("读取器完成。\n"\});
system_flush();


/*
*==== Writer ====
*


空写入器(int id_arg)

MsgObj msg;
int i;
int id = id_arg;// 0;//ArgToInt (id_arg);


对于(i=0;i < NUMMSGS;i++)

/*填入值*/
MSG.id = id;
MSG.val = I % NUMMSGS +(Int)('a');


/*排队消息*/
Mailbox_post (mbox、&msg、BIOS_wait_forever);


system_printf ("(%d)写入'%c'...\n"、id、(int) msg.val);
system_flush();



System_printf ("写入器(%d)完成。\n"、id);
system_flush();
Task_yield ();

 控制台中的调试结果如下:

[C674x_0](0)正在写入'A'...
(0)写入'b'...
从(0)读取"A"。
从(0)中读取"b"。
(0)写入'c'...
写入器(0)完成。
(1)写入'A'。
从(0)中读取'c'。
从(1)中读取"A"。
(2)写入'A'。
(1)写入'b'。
从(2)中读取"A"。
从(1)中读取"b"。
(2)写入'b'。
(1)写入'c'。
写入器(1)完成。
从(2)中读取"b"。
从(1)中读取"c"。
(2)写入'c'。
写入器(2)完成。
从(2)中读取"c"。

但我认为结果应如下:

[C674x_0](0)正在写入'A'...
(0)写入'b'...
从(0)读取"A"。
从(0)中读取"b"。
(0)写入'c'...
写入器(0)完成。
(1)写入'A'。
从(0)中读取'c'。
从(1)中读取"A"。
(1)写入'b'。
(1)写入'c'。
写入器(1)完成。
从(1)中读取"b"。
从(1)中读取"c"。
(2)写入'A'。
(2)写入'b'。
从(2)中读取"A"。
从(2)中读取"b"。
(2)写入'c'。
写入器(2)完成。
从(2)中读取"c"。

您能解释一下原因吗? 非常感谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    实际输出是正确的(和预期的)、但由于所有任务都是相同的优先级、因此这相当棘手。 注意:邮箱实例具有数据和空闲队列。 空闲队列中填充了创建中指定的 msgs 数。 这些队列受数据和空闲信标保护。

    BIOS_start 函数之前,这里是优先级为2的就绪队列中的任务(在 ROV->Task->ReadyQ 中查看非常有用!)

    readyQ:R、W0、W1、W2被阻止:无
    邮箱中的数字消息:0
    操作:调用 BIOS_start、因此 R 首先运行、然后立即阻断、因为邮箱为空。

    readyQ:W0、W1、W2阻塞:R
    邮箱中的数字消息:0
    操作:W0运行并发布第一条消息。 这使 R 准备好运行、然后在邮箱中为1条消息
    输出:(0)写入'A'……

    readyQ:W0、W1、W2、R (其中 W0正在运行)被阻止:无
    邮箱中的数字消息:1.
    操作:W0继续运行并发布第二条消息。 现在邮箱中有2条消息。
    输出:(0)写入'b'...

    readyQ:W0、W1、W2、R (其中 W0正在运行)被阻止:无
    邮箱中的数字消息:2.
    操作:W0继续运行并尝试发布第3条消息、但邮箱已满、因此它会阻止。

    readyQ:W1、W2、R blocked:W0
    邮箱中的数字消息:2.
    操作:W1运行、但由于邮箱已满、在 Mailbox_post 上被阻止

    readyQ:W2、R 阻塞:W0、W1
    邮箱中的数字消息:2.
    操作:W2运行、但由于邮箱已满、在 Mailbox_post 上被阻止

    readyQ:R blocked:W0、W1、W2
    邮箱中的数字消息:2.
    操作:读取器运行并获得一条消息。 这会使 W0就绪。
    从(0)读取"A"。

    readyQ:R、W0阻塞:W1、W2
    邮箱中的数字消息:1.
    操作:读取器继续运行并获得第二条消息。 这使 W1就绪。
    输出:从(0)读取"b"。

    readyQ:R、W0、W1阻塞:W2
    邮箱中的数字消息:0
    操作:由于 Mailbox_pend 为空、读取器在它上被阻断。

    readyQ:W0、W1阻塞:W2、R
    邮箱中的数字消息:0
    操作:W0运行并将第三条消息放置在邮箱上并结束。 这会使 R 就绪。 邮箱中的1个消息。
    输出:(0)写入'c'……
    写入器(0)完成。

    readyQ:W1、R blocked:W2
    邮箱中的数字消息:1.
    操作:W1运行第一条消息并将其放置在邮箱中。 现在邮箱中有2个 MSG
    输出:(1)写入'A'...

    readyQ:W1、R blocked:W2
    邮箱中的数字消息:2.
    操作:由于邮箱已满、W1继续运行、但在尝试放置第二条消息时被阻止。

    readyQ:R blocked:W2、W1
    邮箱中的数字消息:2.
    操作:读取器运行并获取消息(最后来自 W0)。 这使 W2就绪(因此它将获取邮箱中的第一个空闲消息)
    输出:从(0)读取"c"。

    readyQ:R、W2阻塞:W1
    邮箱中的数字消息:1.
    操作:读取器运行并获取消息(首先来自 W1)。 这使 W1就绪。 这是微妙的…它还基本上给 W1提供邮箱中的第二个空闲消息。
    输出:从(1)读取"A"。

    readyQ:R、W2、W1阻塞:
    邮箱中的数字消息:0
    操作:由于邮箱为空、读取器运行并被阻止

    readyQ:W2、W1阻塞:R
    邮箱中的数字消息:1.
    操作:W2运行并放置其第一条消息。 这是 R READY。
    输出:(2)写入'A'...

    readyQ:W2、W1、R blocked:
    邮箱中的数字消息:1.
    操作:W2运行,但无法获取免费的 msg (由 W1在几行前拥有)…所以它会阻止

    readyQ:W1、R blocked:W2
    邮箱中的数字消息:1.
    操作:W1运行并放置其第二条消息。
    输出:(1)写入'b'...

    readyQ:W1、R blocked:W2
    邮箱中的数字消息:2.
    操作:W1运行并阻止,因为没有可用的 msgs

    readyQ:R blocked:W2、W1
    邮箱中的数字消息:2.
    操作:R 会收到一条消息、这会使 W2就绪
    输出:从(2)中读取"A"。

    readyQ:R、W2阻塞:W1
    邮箱中的数字消息:1.
    操作:R 获得一条消息、这使 W1就绪(基本上为它提供邮箱中的第二个空闲消息)
    输出:从(1)中读取"b"

    readyQ:R、W2、W1阻塞:
    邮箱中的数字消息:0
    操作:R 块、因为没有 msgs

    readyQ:W2、W1阻塞:R
    邮箱中的数字消息:0
    操作:W2运行… 读取器左侧以完成…

    这有道理吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    抱歉,我不理解下图中的下划线位置,为什么?我认为 W2运行、它不会被阻止。 非常感谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于邮箱是用2个 msgs 创建的、当它为空时、2个 msgs 位于空闲队列中。 用于管理空闲队列的信标(称为空闲信标)的计数为2 (零表示不可用)。 下面是上述两个关键步骤(我希望我已经编号!)。 我添加了更多说明

    readyQ:R blocked:W2、W1
    邮箱中的数字消息:2.
    可用信标计数:0
    操作:读取器运行并获取消息(最后来自 W0)。 这会使 W2就绪(因此它将获取邮箱中的第一个空闲消息)。
    更多详细信息:当读取器通过 Mailbox_pend 获取 msg 时、它会将 msg 放置在空闲队列上。 它还会看到 W2在自由信标上挂起。 因此、它使 W2就绪、并且不会增加自由信标计数。 请记住、W1也在自由信标挂起队列中。 由于 W2已准备就绪、W1现在位于自由信标挂起队列的前面。
    输出:从(0)读取"c"。

    readyQ:R、W2阻塞:W1
    邮箱中的数字消息:1.
    可用信标计数:0
    操作:读取器运行并获取消息(首先来自 W1)。 这使 W1就绪。 这是微妙的…它还基本上给 W1提供邮箱中的第二个空闲消息。
    更多详细信息:同样、当 R 获取 msg 时、包含数据的内部 msg 现在会置于空闲队列中。 由于在自由信标挂起队列上有一个任务(W1)、因此它已准备就绪。 自由信标计数仍然为零(因为 W2和 W1都获得了它、并且没有更多的可用 msgs)。
    输出:从(1)读取"A"。

    后来,当 W2尝试获取另一个 msgs 时,由于没有更多空闲消息(一个在数据队列中,另一个由 W1拥有),所以它将被阻止。

    Todd
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    非常感谢!