티스토리 뷰

[stm32] rtos uart semaphore

rtos로 uart통신 interrupt하는데 semaphore를 이용하기

이건 칩에 맞게 설정합니다. -- rtos 설정, led설정, uart 설정(interrupt설정 포함)


https://www.freertos.org/a00124.html

 

This page describes the xSemaphoreGiveFromISR() FreeRTOS API function which is part of the RTOS interrupt safe semaphore API sou

FreeRTOS is a truely free and small footprint RTOS for microcontrollers. This page describes the xSemaphoreGiveFromISR() FreeRTOS API function which is part of the interrupt (ISR) safe FreeRTOS semaphore API source code function set.

www.freertos.org

위 사이트 예시 사용


전체적인 흐름

main에서 interrupt 호출되면 -> stm32h7xx_it.c 의  UART4_IRQHandler(void) 실행 -> 세마포어를 주면 ->main.c의 startUartTask() 실행 (세마포어를 받으면 실행) -> 원하는 동작

어제도 이해가 안갔는데 사실 지금도 안가긴한다;;

대충 인터럽트가 걸리면 IRQNandler에서 세마포어 변수를 준다. 그러면 main의 task가 받아서 동작을 하는 방식이다.

 

 


main.c에서

1. include 및 변수

semaphore를 위한 변수선언

TICKS_TO_WAIT 는 안쓸거라서 빼도 됨

✔╰(*°▽°*)╯✔

전역변수 SemaphoreHandle_t xSemaphore; 를 main.c에 선언 후 -> stm32h7xx_it.c 에도 extern으로 한번 더 선언해야 한다.! 

extern 해주기

 

2. rtos task설정

task설정

 

interrupt uart 함수

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() 만들기

main.c

더보기
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);
  }
}

freertos_uart_interrupt.zip
19.50MB

 

'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
댓글