[mbed RTOS] 3. Queue, MemoryPool, MailQueue

2014. 4. 13. 19:152018년 이전 관심사/mbed

반응형


Queue

Queue는 생산자 Thread(Producers Threads)에서 소비자 Thread(Consumers Threads)에게 Data Pointer를 전달 할 수 있게 한다.




  • Queue()
    • Message Queue 생성 및 초기화
  • osStatus put(T* data, uint32_t millisec=0)
    • Message를 Queue에게 전달
  • osEvent get(uint32_t millisec=osWaitForever)
    • Queue로 부터 Message를 받거나 기다림


Queue<message_t, 16> queue;

 

message_t *message;

 

queue.put(message);

 

osEvent evt = queue.get();

if (evt.status == osEventMessage) {

    message_t *message = (message_t*)evt.value.p;


MemoryPool

MemoryPool 클래스는 고정된 사이즈의 memory pool들을 정의 하거나 관리 한다.


  • MemoryPool()
    • memory pool을 생성 및 초기화
  • T* alloc(void)
    • Memory pool에서 템플릿 타입의 memory block을 할당
  • T* calloc(void)
    • Memory pool에서 템플릿 타입의 memory block을 할당하고 0값으로 초기화
  • osStatus free(T* block)
    • 명시된 memory pool에게 할당되었던 memory block을 반환 함

MemoryPool<message_t, 16> mpool;

 

message_t *message = mpool.alloc();

 

mpool.free(message);


#include "mbed.h"

#include "rtos.h"


Serial pc(USBTX, USBRX);


typedef struct{

    float       voltage;

    float       current;

    uint32_t    counter;

} message_t;


MemoryPool<message_t, 16> mpool;

Queue<message_t, 16> queue;


void send_thread(void const *args)

{

    uint32_t i = 0;

    while(true)

    {

        i++;

        message_t *message = mpool.alloc();

        message->voltage = (i * 0.1) * 33;

        message->current = (i * 0.1) * 11;

        message->counter = i;

        queue.put(message);

        Thread::wait(1000);

    }

}


int main(void)

{

    pc.baud(115200);

    Thread thread(send_thread);

    

    while(true)

    {

        osEvent evt = queue.get();

        if ( evt.status == osEventMessage)

        {

            message_t *message = (message_t*)evt.value.p;

            pc.printf("\nVoltage: %.2f V\r\n",      message->voltage);

            pc.printf("Current: %.2f A\r\n",        message->current);

            pc.printf("Number of cycles: %u\r\n",   message->counter);

            

            mpool.free(message);

        }   

    }   

}


▼ 위 코드를 실행 하면, main 함수에서 queue를 주기적으로 확인하여 queue 안에 message가 있을 때마다, queue에서 message를 꺼내 출력한다.



Mail

Mail은 Queue와 유사하게 동작하며, Queue에 없는 추가된 기능이 있다. ( 할당된 memory block을 Mail Queue에 직접 전달 할 수 있음 )



  • Mail()
    • Mail Queue를 생성 및 초기화
  • T* alloc(uint32_t millisec=0)
    • 템플릿 타입의 memory block을 할당
  • T* calloc(uint32_t millisec=0)
    • 템플릿 타입의 memory block을 할당하고 0으로 초기화 함
  • osStatus put(T* mptr)
    • Queue에 mail을 전달
  • osEvent get(uint32_t millisec=osWaitForever)
    • Queue로 부터 mail을 수신
  • osStatus free(T* mptr)
    • mail로 부터 memory block을 해제 함.

#include "mbed.h"

#include "rtos.h"


Serial pc(USBTX, USBRX);


/* mail */

typedef struct{

    float       voltage;

    float       current;

    uint32_t    counter;

}mail_t;


Mail<mail_t, 16> mail_box;


void send_thread(void const *args)

{

    uint32_t i = 0;

    while (true)

    {

        i++;

        mail_t *mail = mail_box.alloc();

        mail->voltage = ( i * 0.1 ) * 33;

        mail->current = ( i * 0.1 ) * 11;

        mail->counter = i;

        mail_box.put(mail);

        Thread::wait(1000);

    }

}


int main(void)

{

    pc.baud(115200);

    

    Thread thread(send_thread);

    

    while(true)

    {

        osEvent evt = mail_box.get();

        if ( evt.status == osEventMail)

        {

            mail_t *mail = (mail_t*)evt.value.p;

            pc.printf("\nVoltage: %2.f V\r\n",      mail->voltage);

            pc.printf("Current: %.2f A\r\n",        mail->current);

            pc.printf("Number of cycles: %u\r\n",   mail->counter);

            

            mail_box.free(mail);

        }

    }

}



▼ 위 코드를 수행하면, Queue의 예제와 동일한 결과가 나온다. 단, Queue와 다른 점은 Mail Queue의 경우 Memory Pool을 이용할 필요 없이 mail 객체에서 직접 memory block을 할당 할 수 있다.




[참고자료]

[mbed], http://mbed.org/handbook/RTOS



반응형