STM32 – USART ring buffer

  • Post author:
  • Post category:STM32

https://istarik.ru/blog/stm32/151.html

ring buffer:
물론 링은 없으며 수신 버퍼에 대한 일부 배열을 할당하기만 합니다. 이 경우에 6바이트 배열을 할당했다고 가정합니다.나 자신이 그림을 그리기에는 너무 게을러서 인터넷에서 적합한 것을 찾았습니다 …

back 은 레코드 포인터 (쓰려는 셀의 인덱스. head-head라고도 함) 입니다 .

앞 – 읽기 포인터 (바이트를 선택하려는 셀의 인덱스. 테일 – 테일이라고도 함) .

프로그램이 시작될 때 두 포인터는 버퍼의 맨 처음에 있고 동일하며 수신 버퍼가 비어 있음을 의미합니다.

그런 다음 3바이트 (a, b, c) 가 도착 하고 각 후속 바이트 후에 레코드 포인터가 다음 셀로 이동합니다. 쓰기 포인터와 읽기 포인터의 차이 때문에 버퍼에 3개의 새 바이트가 있음을 알 수 있습니다. 다음으로 프로그램에 이 세 바이트 중 처음 두 개 (a, b) 를 읽고 싶다고 말하고 버퍼에 “c”를 남겨둡니다.(우리는 세 가지를 모두 취할 수 있지만 이것이 애니메이션이 그려지는 방식입니다 .), 읽기 포인터도 이동하고 읽지 않은 셀 번호 2에서 멈춥니다.

그런 다음 4바이트가 더 도착합니다 (d, e, f, g) . 레코드 포인터가 있는 셀, 즉 3번 셀부터 녹음을 시작합니다. 이 경우 마지막 바이트(g)가 0 셀에 기록됩니다. 즉, 버퍼가 최대값을 통과하고 처음으로 돌아가서 반복됩니다. 자, 그러면 읽기 포인터가 있는 곳, 즉 셀 2번부터 데이터를 읽어옵니다. 또한 애니메이션이 중단되지만 데이터를 계속 읽으면 읽기 포인터도 최대 값을 통해 0 셀에서 읽기를 계속할 것임이 분명하다고 생각합니다.

데이터를 읽지 않으면 레코드 포인터가 처음으로 이동하여 셀이 사용 중인지 확인하고 읽을 때까지, 즉 버퍼가 “중지”될 때까지 덮어 쓰지 않습니다.

결과적으로 쓰기 포인터와 읽기 포인터가 어디에 있는지 전혀 알 필요가 없으며 프로그램이 모든 것을 처리하고 동일한 포인터를 원으로 쫓습니다.

링 버퍼의 작동을 얼마나 잘 설명했는지 모르겠으므로 애니메이션을 하나 더 추가하겠습니다.

여기서는 모든 것이 동일합니다. “HELLOWIKPEDIA”라는 문구가 조각으로 쓰여지고 읽혀집니다.

그건 그렇고, 이것은 키보드 링 버퍼 입니다.기존 컴퓨터. 버퍼가 꽉 찼고 프로세서가 아직 비우지 않은 상태에서 사용자가 미친 듯이 버튼을 계속 누르면 일부 컴퓨터에서 경고음이 울립니다. 이것은 호기심에 대한 인파입니다. Wikipedia의 영어 버전에 설명되어 있습니다.
라이브러리는 위에서 설명한 원칙에 따라 작동합니다. 들어오는 데이터가 기록되는 수신 버퍼 (배열) 가 생성되고 (이는 인터럽트 처리기에서 직접 발생) 무한 루프에서 새 데이터가 도착했는지 지속적으로 확인합니다. 수신 버퍼, 그렇다면 다른 배열로 읽습니다.

무한 루프에서 적어도 새로운 것이 나타 났는지 확인할 수 있습니다 …

그리고 적어도 특정 바이트 수를 기다리고 있음을 지정할 수 있습니다 …

이 경우 수신 버퍼에 최소 5개의 새 바이트가 나타날 때까지 기다렸다가 그 후에야 선택합니다. 수신 버퍼에서 데이터를 가져 오지 않았지만 계속 도착하면 채울 때 수신이 “중지”됩니다. 즉, 이전 데이터를 읽기 시작할 때까지

새 데이터 기록이 중지됩니다 (손실됩니다) . 공간을 확보하는 것.

즉, 수신 버퍼에서 들어오는 데이터를 적시에 가져와야 합니다.

“정지”하지 않는 버퍼를 만들 수 있지만 이 경우 시간 내에 다시 빼지 않으면 이전 데이터를 단순히 덮어씁니다. 이것은 모든 링 버퍼의 문제/기능입니다. 데이터를 가져올 시간이 필요합니다.

프로그램

Cube에서는 일부 USART를 활성화하고 인터럽트를 켭니다.

라이브러리 에서 프로젝트로 파일 추가 -usart_ring.h , usart_ring.c.

파일에서 usart_ring.h USART 번호를 지정하고 수신 버퍼의 크기를 설정해야 합니다.

크기는 그대로 둘 수 있습니다. 더 큰 길이의 패킷을 수신하는 경우 읽을 시간이 없는 경우를 대비하여 버퍼를 패킷보다 크게 만드는 것이 좋습니다.

파일로 갑시다 stm32f1xx_it.c, 거기에 헤더를 포함하십시오 …

변수 선언 중…

그리고 인터럽트 처리기에 코드를 추가하십시오 …

여기에서 수신된 바이트가 수신 버퍼에 기록되고 레코드 포인터가 이동됩니다. HAL은 이 문제에 관여하지 않습니다. 모든 것이 가능한 한 빨라야 하므로 돌아가십시오.

F3 시리즈 스톤은 레지스터 이름이 약간 다릅니다…

SR ⇨ ISR

USART_SR_RXNE ⇨ USART_ISR_RXNE

DR ⇨ RDR

컴파일러가 무엇을 변경해야 하는지 알려줍니다.

이제 파일로 이동하겠습니다. main.c헤더도 포함하고…

무한 루프 전에 USART 인터럽트를 활성화 하십시오 …

글쎄, 주기 자체에서 우리는 데이터를 받습니다 …

조건 내에서 읽기 구성은 작업에 따라 다릅니다.

모든 주요 작업 (새 데이터 확인, 포인터 읽기 및 쓰기 조작)은 파일에서 수행됩니다.usart_ring.c.

수신 버퍼를 지우거나 제로화하는 기능이 있습니다…

이 함수를 실행한 후 레코드 포인터는 수신 버퍼의 시작 부분으로 설정됩니다.

여러 USART를 사용해야 하는 경우 다른 함수 및 변수 이름으로 라이브러리를 복제합니다.