2012-04-26 63 views
0

我一直有一些问题,我正在运行几个任务。我有三个任务,其中一个是LCD更新任务,另外两个是电机驱动任务。我还有两个ISR将消息发布到两个电机驱动程序任务中。至于传递指针安全,我在想创建一个结构:实时操作系统 - 通过分配一个结构并传递它通过一个队列

typedef struct message{ 
    enum BUTTON_1 = 0, BUTTON_2 = 1, NO_BUTTON = 3; //button ISR to increase motor drive 
    int timestamp; //A timestamp for the RPM of the motors 
    } 

现在,共享内存的问题进来,所以我想:

struct message* update_msg = (struct message*)malloc(sizeof(struct message)); //from here I dont know how to creat an object that fills the space allocated. 

我会再发指针通过队列的结构:

OSTASKQPOST((void *)(st_size) 
    .... 
) 

在最后一次任务后最终得到的消息,并做它需要与成员变量是什么,我将不得不解除分配内存。

free(st_size) 

会是这样的似是而非?

回答

2

这是在线程之间传递数据的'线程间通信101'方法。它会正常工作。假设32位宽的队列,发布结构地址或对象实例开始赢得相当快,(随着消息大小的增加,直接通过值发布数据)。

还有其他的机制。在我的ARM嵌入式项目中,RAM是有限的,内存空间比速度更重要,我倾向于使用一个由255个全局消息实例组成的数组作为池(对于'无效索引',保留一个值是有用的,255)。 。这意味着每个消息只能被一个字节引用,而每个消息中的两个字节允许它们被链接到列表中和从列表中移出。链表头字节,互斥量和信号量为线程间通信创建了阻塞队列 - 不需要额外的存储空间。所有消息在启动时都链接到一个“池”队列中,并被弹出,在线程之间排队并通过应用程序线程释放回池中。

从硬件接收数据的ISR无法调用malloc,获取互斥锁或等待消息索引的信号量。我使用另一个没有锁的队列类,只是一个字节索引的循环队列。我在启动时推送了几条消息。中断处理程序可以从这个ISRpool出列消息,从硬件中填充它们,设置int(位域!),识别ISR,将消息索引推送到'ISRout'循环队列,发出信号并通过信号退出OS。等待信号量的线程唤醒并知道ISRout上有数据,将其弹出并排队等待任何线程处理来自该ISR的消息。 'ISRhandler'线程还负责用信息'补足'ISRpool,以便ISR在数据到达时总是有消息准备好。这个简单的共享'ISRpool'系统只有在中断不能重新启用更高优先级的中断时才能工作!

以类似的方式,将tx ISR的消息推送到循环队列中供ISR使用(中断暂时禁用以查看硬件是否空闲并且硬件FIFO需要“启动”以启动tx再次中断)。 'used'tx消息被转储到rx ISRpool上 - 它们也可能被重新用于输入。

汇集计划有一些优势,并不是很明显。一个是“没有malloc,没有空闲”。消息当然可以泄漏,但是我注意到 - 我的'monitor/debugger'运行的UART的终端提示符是'223>'这个数字是池级别。如果这个数字下降并且不再回来,我知道我已经泄露了。当你不能在Valgrind下运行应用时,这是非常重要的:)