Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

임베디드 소프트웨어/Zephyr

[nRF52840 + Zephyr] #11. Inter-task communication A

방피터 2023. 6. 3. 12:34

제퍼의 경우에는 Inter-thread communication이 되겠구만!

지원되는 기능을 살펴보니....

너무 많아;;;😢

👇👇

지원되는 inter-thread communication 기능이 너무 많다.

우린 너무 많은 거 안좋아 하니까 줄여보자구.

난 보통 다른 RTOS에서는 Flag와 Queue를 많이 사용했어.

그런데 제퍼에는 Flag가 없네? 진짜 없는 건가? ;;; 간편하게 사용하기 좋았는데 ㅠㅠ

Queue는 당연히 있는데... FIFO가 Queue 아닌가?;;

LIFO가 Stack이고?

Pipe는 freertos에서 stream같고 ㅎㅎ

주절 주절 말이 많았는데

Stack은 잘 안쓰니까 우선 Queue부터 해보자구

👇👇

#include <zephyr/kernel.h>
#include <stdio.h>

K_QUEUE_DEFINE(my_queue);

typedef struct queueItem{
	uint8_t itemName[10];
	uint8_t data;		
}queueItem_t;

//declaration
void queue_thread_entry(void *p1, void *p2, void *p3);

K_THREAD_DEFINE(queue_thread, 512, queue_thread_entry, NULL, NULL, NULL,
		5, 0, 0);

void queue_thread_entry(void *p1, void *p2, void *p3){
	static uint8_t itemNumber = 0;
	for(;;){
		queueItem_t *queueItem = k_malloc(sizeof(queueItem_t));
		sprintf(queueItem->itemName, "item_%d\0", itemNumber++);
		queueItem->data = itemNumber;
		k_queue_append(&my_queue, queueItem);
		k_msleep(1000);
	}
}

void main(void)
{
	queueItem_t *queueItem;
	printk("Hello World! %s\n", CONFIG_BOARD);
	for(;;){
		queueItem = k_queue_get(&my_queue,	K_FOREVER);
		printk("%s, %d\n", queueItem->itemName, queueItem->data);
		k_free(queueItem);
	}
}

예제가 아~~주 약간 긴데 ㅎ

별거 아니니까 얼른 보자 😆

queue_thread에서 main thread로 데이터를 전송하는 예제야.

 

1. 우선 K_QUEUE_DEFINE으로 Queue 선언하고

2. queue_thread에서 전송할 데이터 malloc한 후 전송

3. main thread에서 k_queue_get으로 데이터 수신

4. printk!

끝!

 

엄청 간단하지?

queue example 결과

그럼 멈추지 말고 바로 FIFO 갑니다.

코드를 보면 알겠지만 FIFO 사용법이 민망할 정도로 QUEUE와 똑같아.

👇👇

#include <zephyr/kernel.h>
#include <stdio.h>

K_FIFO_DEFINE(my_fifo);

typedef struct fifoItem{
	uint8_t itemName[20];
	uint8_t data;		
}fifoItem_t;

//declaration
void queue_thread_entry(void *p1, void *p2, void *p3);

K_THREAD_DEFINE(fifo_thread, 512, queue_thread_entry, NULL, NULL, NULL,
		5, 0, 0);

void queue_thread_entry(void *p1, void *p2, void *p3){
	static uint8_t itemNumber = 0;
	for(;;){
		fifoItem_t *fifoItem = $k_malloc(sizeof(fifoItem_t));
		sprintf(fifoItem->itemName, "fifo item_%d\0", itemNumber++);
		fifoItem->data = itemNumber;
		printk("FIFO put\n");
		k_fifo_put(&my_fifo, fifoItem);
		k_msleep(1000);
	}
}

void main(void)
{
	fifoItem_t *fifoItem;
	printk("Hello World! %s\n", CONFIG_BOARD);
	for(;;){
		fifoItem = k_fifo_get(&my_fifo,K_FOREVER);
		printk("Fifo received: %s, %d\n", fifoItem->itemName, fifoItem->data);
		k_free(fifoItem);
	}
}

함수 이름이 조금 다를 뿐이야.

당연히 결과도 잘 나오고

👇👇

FIFO와 Queue는 거의 같다.

음.. 그런데 공식 문서를 보니 이런 내용이 있네?

struct data_item_t {
    void *fifo_reserved;   /* 1st word reserved for use by FIFO */
    ...
};

전송할 데이터의 첫번째 워드는 FIFO가 사용하게 되어 있네?

-_- 왜 잘 동작했지?

그래도 따를 건 따라야지 ㅋ

👇👇

typedef struct fifoItem{
	void *reserved;
	uint8_t itemName[20];
	uint8_t data;		
}fifoItem_t;

이렇게 해도 동작에는 별 차이가 없는 듯.

 

LIFO나 STACK도 사용법은 거의 비슷하니까

관심 있는 사람들은 따로 해보면 될 것 같고 ㅋ

(사실 난 거의 쓸일이 없었어.)

 

글이 너무 길어지니까 다음글에서

Message Queue랑 Mail box 그리고 Pipe를 다뤄보도록 하지.

 

2023.06.04 - [임베디드 소프트웨어/Zephyr] - [nRF52840 + Zephyr] #13. Inter-task communication B

 

[nRF52840 + Zephyr] #13. Inter-task communication B

2023.06.03 - [임베디드 소프트웨어/Zephyr] - [nRF52840 + Zephyr] #11. Inter-task communication A [nRF52840 + Zephyr] #11. Inter-task communication A 제퍼의 경우에는 Inter-thread communication이 되겠구만! 지원되는 기능을 살펴보

engschool.tistory.com

 

다시 말하지만 inter-thread comminication은

rtos에서 매우 핵심적인 기능이라 할 수 있어.

꼭 숙지! 공부! 하자고!

안녕!

👋👋👋

2023.06.03 - [임베디드 소프트웨어/Zephyr] - [nRF52840 + Zephyr] #12. Synchronization

 

[nRF52840 + Zephyr] #12. Synchronization

Synchronization에 대해서는 Semaphore와 Mutex, 이 두 개만 알면 끝! 😆😆😆😆 Semaphore부터 보자구. //런타임에서는 이렇게 struct k_sem my_sem; k_sem_init(&my_sem, 0, 1); //컴파일타임에서는 이렇게 K_SEM_DEFINE(my_s

engschool.tistory.com

 

반응형