LoginSignup
1
2

More than 5 years have passed since last update.

Mbed OSで複数のスレッドからのmailを待つ方法

Last updated at Posted at 2018-11-23

開発環境

IDE:e2studio
マイコンボード:GR-LYCHEE
使用OS:Mbed OS

結論

複数のスレッドから異なる型のmailを送る方法が分からなかったので、
試行錯誤してみた結果、できた。

共用体は使っても使わなくてもどっちでもいいけど、
メモリ節約のためには使ったほうがいい。

本当にこの実装でいいのかは、検証が必要。

仕様

mailを送信するスレッドは、下記3スレッド。
それぞれ、異なる型のmailを送信している。

  • send_thread
  • send_thread2
  • send_thread3

mailを受信待ちするスレッドは、下記スレッド。

  • receive_thread

send_thread・send_thread2・send_thread3
のうち、どのスレッドがmailを送信してきたかは、
mail_typeで識別している。

コード

main.cpp
#include "mbed.h"

Serial pc(USBTX, USBRX);

typedef struct {
    uint32_t count1;
    uint32_t count2;
    uint32_t count3;
    uint32_t count4;
} a_mail_t;

typedef struct {
    uint8_t count13;
    uint8_t count14;
    uint8_t count15;
} b_mail_t;

typedef struct {
    char *msg;
} c_mail_t;

/* Mail */
typedef struct {
    uint32_t mail_type;
    union {
        a_mail_t a_mail;
        b_mail_t b_mail;
        c_mail_t c_mail;
    };
} mail_t;

Mail<mail_t, 32> mail_box;
Thread thread;
Thread thread2;
Thread thread3;
Thread thread4;

void send_thread3(void) {
    int i = 0;
    while (true) {
        i++;
        mail_t *mail = mail_box.alloc();
        mail->mail_type = 3;
        if (i % 2) {
            mail->c_mail.msg = "aaaaaaa";
        } else {
            mail->c_mail.msg = "bbbbbbb";
        }
        mail_box.put(mail);
        Thread::wait(3000);
    }
}

void send_thread(void) {
    uint32_t i = 3000000;
    while (true) {
        i++; // fake data update
        mail_t *mail = mail_box.alloc();
        mail->mail_type = 1;
        mail->a_mail.count1 = i;
        mail->a_mail.count2 = i * 2;
        mail->a_mail.count3 = i + 2;
        mail->a_mail.count4 = i % 6;
        mail_box.put(mail);
        Thread::wait(500);
    }
}

void send_thread2(void) {
    uint32_t i = 0;
    while (true) {
        i++; // fake data update
        mail_t *mail = mail_box.alloc();
        mail->mail_type = 2;
        mail->b_mail.count13 = i;
        mail->b_mail.count14 = i % 3;
        mail->b_mail.count15 = i * 5;
        mail_box.put(mail);
        Thread::wait(1000);
    }
}

void receive_thread(void) {
    while (true) {
        osEvent evt = mail_box.get();
        if (evt.status == osEventMail) {
            mail_t *mail = (mail_t *) evt.value.p;

            if (mail->mail_type == 1) {
                pc.printf("mail_type%d:%d,%d,%d,%d\n", mail->mail_type,
                        mail->a_mail.count1, mail->a_mail.count2,
                        mail->a_mail.count3, mail->a_mail.count4);
            } else if (mail->mail_type == 2) {
                pc.printf("mail_type%d:%d,%d,%d\n", mail->mail_type,
                        mail->b_mail.count13, mail->b_mail.count14,
                        mail->b_mail.count15);
            } else if (mail->mail_type == 3) {
                pc.printf("mail_type%d:%s\n", mail->mail_type,
                        mail->c_mail.msg);
            }
            mail_box.free(mail);
        }
    }
}

int main(void) {
    thread.start(send_thread);
    thread2.start(send_thread2);
    thread3.start(send_thread3);
    thread4.start(receive_thread);

    while (true) {

    }
}

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2