MailQueue 기본 Function 구현 (CMSIS-RTOS-V1)
MailQueue는 Task끼리 데이터를 주고받기 위해 사용하는 자료구조이다.
동작:
STM32F407Discvery로 구현 하였다.
Task의 우선순위는 똑같이 Normal
1. sendMailTask는 val1, val2, val3에 0x01, 0x02, 0x03을 쓴다.
2. Mailput을 호출하여 전송 후 osDelay를 호출하여 Context Switching을 한다.
3. recvMailTask은 Block 상태에서 해제되어 val1, val2, val3 이 0x01,0x02,0x03이 맞는지 확인한다.
4. 맞으면 RED LED를 Blink 하고 틀리면 Blue LED를 Set 한다.
(DEBUG 모드에서 PRINTF(SWV) 사용 시 TASK Switching이 깨져 BLUE LED를 띄운다.)
(RELEASE에서 정상동작 확인)
MailQueue API
osMailQId
= osMailQId를 가지고 Mail을 Get 했을 때 일치하는 ID를 가지고 있는 Task 만이 Wakeup을 할 수 있다.
(osMailGet을 호출하고 있다고 무조건 Wakeup을 하지 않는다. 일치할 경우만 Wakeup)
ex) osMailQId ToErrorTask;
osMailQDef(이름, 크기, 타입)
= 메일 이름과 크기 그리고 데이터 타입을 정해준다.
ex) osMailQDef(mail, 1 ,vMail_TypeDef); //메일의 이름은 메일, 크기는 1, 데이터 타입은 메일 구조체
osThreadCreate(Define 된 메일 이름, 스레드ID or NULL)
= 메일을 만든다
ex) mailId = osMailCreate(osMailQ(mail), NULL);
osMailAlloc(메일 아이디, TimeOUT)
= 메모리를 할당한다 위 그림의 alloc에 해당한다.
ex) pTMail = osMailAlloc(mailId, osWaitForever);
osMailFree(메일 아이디, 메일 데이터타입 포인터)
= 할당된 메모리를 Free한다 위 그림의 Free에 해당한다.
ex) osMailFree(mailId, recvTMail);
osMailGet(메일 아이디, 타임아웃)
= 메일를 받는다.(이 함수에 진입되면 Blocked 상태에 있다가 ID와 일치하는 Mail이 들어오면 Wakeup 한다.)
Return 값이 에러인지 메시지인디 타입아웃인지 등 확인할 수 있다.
ososMailPut(메일아이디, 메일 데이터타입 포인터)
= 메일를 보낸다.
메일에 사용하는 데이터 타입 및 ID
typedef struct
{
int val1;
int val2;
int val3;
int *ptr;
}vMail_TypeDef;
osMailQId mailId;
메일을 보내는 Task
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
void sendMailTask(void const * argument)
{
/* init code for USB_HOST */
MX_USB_HOST_Init();
printf("HELLOW WORLD\n");
/* USER CODE BEGIN startOranageTask */
vMail_TypeDef *pTMail;
/* Infinite loop */
for(;;)
{
pTMail = osMailAlloc(mailId, osWaitForever);
/* ORange LED */
pTMail->val1 = 0x1;
pTMail->val2 = 0x2;
pTMail->val3 = 0x3;
pTMail->ptr = &(pTMail->val1);
osMailPut(mailId, pTMail);
HAL_GPIO_WritePin(GPIOD, LD3_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOD, LD3_Pin, GPIO_PIN_RESET);
osDelay(100);
}
/* USER CODE END startOranageTask */
}
|
cs |
메일을 수신하는 Task
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
void recvMailTask(void const * argument)
{
/* USER CODE BEGIN startRedTask */
osEvent event;
osStatus retStatus;
vMail_TypeDef *recvTMail;
/* Infinite loop */
for(;;)
{
/* RED LED */
event = osMailGet(mailId, osWaitForever);
if(event.status ==osEventMail)
{
recvTMail = event.value.p;
// printf("mail value1: 0x%x \r", recvTMail->val1);
// printf("mail value2: 0x%x \r", recvTMail->val2);
// printf("mail value3: 0x%x \r", recvTMail->val3);
// printf("mail ptr4: 0x%x \r", (int)recvTMail->ptr);
if(recvTMail->val1 == 0x01 && recvTMail->val2 == 0x02 && recvTMail->val3 ==0x03)
{
retStatus = osMailFree(mailId, recvTMail);
if(retStatus == osOK)
{
HAL_GPIO_WritePin(GPIOD, LD5_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOD, LD5_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
}
else
{
HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);
}
}
else
{
HAL_GPIO_WritePin(GPIOD, LD6_Pin, GPIO_PIN_SET);
}
}
}
/* USER CODE END startRedTask */
}
|
cs |
'Firmware > stm32' 카테고리의 다른 글
STM32 Lepton 2.5 Project -1 (0) | 2021.06.13 |
---|---|
NanoPB - Stm32 (0) | 2021.04.04 |
STM32 SPI ErrorCallback 처리 (0) | 2020.10.14 |
STM32 SPI Slave 동작 시 데이터 송수신 이상 현상 (0) | 2020.10.14 |
STM32 SPI Slave로 Interrupt DMA Transmit/Receive 구현하기 (1) | 2020.07.24 |