티스토리 뷰
[stm32] rtos uart semaphore
rtos로 uart통신 interrupt하는데 semaphore를 이용하기
이건 칩에 맞게 설정합니다. -- rtos 설정, led설정, uart 설정(interrupt설정 포함)
https://www.freertos.org/a00124.html
위 사이트 예시 사용
전체적인 흐름
main에서 interrupt 호출되면 -> stm32h7xx_it.c 의 UART4_IRQHandler(void) 실행 -> 세마포어를 주면 ->main.c의 startUartTask() 실행 (세마포어를 받으면 실행) -> 원하는 동작
어제도 이해가 안갔는데 사실 지금도 안가긴한다;;
대충 인터럽트가 걸리면 IRQNandler에서 세마포어 변수를 준다. 그러면 main의 task가 받아서 동작을 하는 방식이다.
main.c에서
1. include 및 변수
TICKS_TO_WAIT 는 안쓸거라서 빼도 됨
✔╰(*°▽°*)╯✔
전역변수 SemaphoreHandle_t xSemaphore; 를 main.c에 선언 후 -> stm32h7xx_it.c 에도 extern으로 한번 더 선언해야 한다.!
2. rtos task설정
main문에서 uart_receive_it 함수로 interrupt 대기상태로 만들기
3. stm32h7xx_it.c 에서 세마포어 주기
저번 interrupt로 uart( rtos안쓰고) 할 때는
밑에 코드로 callback을 사용해서 interrupt를 했는데 인터럽트를 많이 쓰면 안좋아서 semaphore로 오류를 방지하기로 했다. semaphore는 공유자원을 컨트롤하는 변수이다.
stm32h7xx_it.c 파일 안에
void UART4_IRQHandler(void) 를 이용해서 interrupt 진행!
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
를 사용할 것이다.
주석처리된 if문은 10tick마다 받는거라 필요없다. 우린 키보드 입력이 들어오면 interrupt를 해야하는 걸!
10timer 가 필요 없다,, 주의
타이머 세마포어를 하고 싶다면 맨위에 사이트를 참고
void UART4_IRQHandler(void)
{
/* USER CODE BEGIN UART4_IRQn 0 */
static unsigned char ucLocalTickCount = 0;
static signed xHigherPriorityTaskWoken;
// SemaphoreHandle_t xSemaphore = NULL; no local value
// HAL_UART_IRQHandler(&huart4);
xHigherPriorityTaskWoken = pdFALSE;
// ucLocalTickCount++;
// if( ucLocalTickCount >= TICKS_TO_WAIT ) //per 10 ticks
// {
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
// ucLocalTickCount = 0;
// }
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
/* USER CODE END UART4_IRQn 0 */
HAL_UART_IRQHandler(&huart4);
/* USER CODE BEGIN UART4_IRQn 1 */
/* USER CODE END UART4_IRQn 1 */
}
void UART4_IRQHandler(void)
{
/* USER CODE BEGIN UART4_IRQn 0 */
static unsigned char ucLocalTickCount = 0;
static signed xHigherPriorityTaskWoken;
// SemaphoreHandle_t xSemaphore = NULL; no local value
xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
/* USER CODE END UART4_IRQn 0 */
HAL_UART_IRQHandler(&huart4);
/* USER CODE BEGIN UART4_IRQn 1 */
/* USER CODE END UART4_IRQn 1 */
}
4. main.c에서 StartUartTask() 만들기
void StartUartTask(void *argument)
{
/* USER CODE BEGIN 5 */
xSemaphore = xSemaphoreCreateBinary();
/* Infinite loop */
for(;;)
{
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
{
// Do something
HAL_UART_Transmit(&huart4, &data, sizeof(data), 10);
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_UART_Receive_IT(&huart4, &data, 1);
}
osDelay(10);
}
}
'stm32 & rtos' 카테고리의 다른 글
[stm32] rtos+lwip (0) | 2022.07.28 |
---|---|
[ stm32] uart 통신 (0) | 2022.07.18 |
[stm32] rtos + lwip (0) | 2022.07.15 |
관련 url (0) | 2022.07.14 |
[stm32] uart 입출력 (polling) (0) | 2022.07.08 |
- Total
- Today
- Yesterday
- 표처럼 코드가 나와요
- 2163번
- gmapping
- 내 몸에서
- 백준
- 빈 txt
- lwip
- 으에엑
- WPF
- add button
- 4831
- 텐서플로우 #tensorflow # tensor #텐서 #flow #플로우
- 버튼 클릭 시 메뉴
- #전기버스
- 어이구 두야
- 꺼저
- 파일 올리기
- 10869
- cartographer
- diagrams.net
- SWEA
- 버튼에 메뉴만들기
- 재생목록
- 6204
- c#
- 티스토리 코드블럭
- 네트워크 구성도
- rosbag
- 2588
- wpf 재생목록
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |