mbed-rtos提供的同步机制和通讯机制同样也可以应用在中断服务程序中,但考虑到中断服务程序必须尽快返回,所以互斥锁机制不能用,而且所以涉及到需要等待的场合必须立刻返回,我们来看下面的示例代码,其效果和采用多线程方式实现是一样的:
#include "rtos.h"
typedef struct {
    uint32_t length;
    char str[255];
} message_t;
 
Mail<message_t, 16> queue;
Serial pc(USBTX,USBRX);
int32_t bufindex =-1;
char serialdata[255];
void serialhandler () {
    serialdata[++bufindex]=pc.getc();
    if (serialdata[bufindex]=='\n' || bufindex==255)
    {
                        message_t *message = queue.alloc();
                        message->length = bufindex;
                        memcpy(message->str,serialdata,bufindex);
                        queue.put(message);
                        bufindex=-1;
    }
}
int main (void) {
    pc.attach(&serialhandler);
    while (true) {
                        osEvent evt = queue.get();
                        if (evt.status == osEventMail) {
                                            message_t *message = (message_t*)evt.value.p;
                                            pc.printf("User input length is %d.\n",message->length);
                                            for (uint8_t i=0;i<message->length;i++)
                                                                 pc.putc(message->str);
                                            pc.printf("\n");
                                            queue.free(message);
                        }
                        Thread::yield();
    }
}
         当然,不同的中断服务程序之间也可以用Queue或Mail实现通讯,但需要注意的是,在使用这两者的get函数时一定要立即返回,示例代码如下:
#include "rtos.h"
typedef struct {
    uint32_t length;
    char str[255];
} message_t;
 
Mail<message_t, 16> queue;
Serial pc(USBTX,USBRX);
int32_t bufindex =-1;
Ticker tick;
char serialdata[255];
void serialhandler () {
    serialdata[++bufindex]=pc.getc();
    if (serialdata[bufindex]=='\n' || bufindex==255)
    {
                        message_t *message = queue.alloc();
                        message->length = bufindex;
                        memcpy(message->str,serialdata,bufindex);
                        queue.put(message);
                        bufindex=-1;
    }
}
void serialout()
{
    osEvent evt = queue.get(0);
    if (evt.status == osEventMail) {
                        message_t *message = (message_t*)evt.value.p;
                        pc.printf("User input length is %d.\n",message->length);
                        for (uint8_t i=0;i<message->length;i++)
                                            pc.putc(message->str);
                        pc.printf("\n");
                        queue.free(message);
    }
}
int main (void) {
    pc.attach(&serialhandler);
    tick.attach(&serialout,1);
    Thread::wait(osWaitForever);
 
}