매우 메모리 제한된 임베디드 시스템에서 큰 데이터 전송을 어떻게 처리합니까?

StackOverflow https://stackoverflow.com/questions/359745

문제

PC 직렬 포트 (115200 Baud)에서 큰 파일을 다운로드하고 SPI (~ 2 MHz)를 통해 직렬 플래시 메모리에 작성 해야하는 마이크로 컨트롤러가 있습니다. 플래시 쓰기는 쓰기 명령과 페이지 주소가 앞서 256 바이트 블록에 있어야합니다. 시스템에서 사용할 수있는 총 RAM은 80 바이트 스택 크기로 1KB입니다.

이것은 현재 UART에서 256 바이트 버퍼를 채우고 Ping-Ponging을 RX 버퍼 준비 신호의 인터럽트로 채우는 또 다른 256 바이트 버퍼로 핑을함으로써 작동하고 있습니다. 조작이 완료 될 때까지 버퍼 스왑이 반복됩니다.

별도의 원형 버퍼에서 작동하는 SPI 및 UART 포트 모두에 대한 TX/RX 인터럽트 핸들러를 설정하는 것이 좋습니다. 따라서 새로운 바이트를 폴링하고 작동이 완료되기를 기다리는 대신 TX 버퍼를 채우고 인터럽트를 사용하거나 버퍼를 들어오는 데이터를 확인할 수 있습니다. 이것은 주변 장치를 기다리는 대신 실제 작업을 위해 훨씬 더 많은 시계 사이클을 제공합니다.

128 바이트 원형 버퍼로 IRQ를 구현 한 후 데이터 용 UART RX 버퍼를 설문 조사하고 즉시 SPI TX 버퍼에 배치하여 파일 전송을 수행합니다. 이 접근 방식으로 제가 겪고있는 문제는 버퍼에 대한 RAM이 충분하지 않으며 PC 수신 버퍼가 데이터를 플래시 전송 버퍼로 가져 오는 것보다 빠르게 채우고 있다는 것입니다. 분명히, 전송 속도는 문제가되지 않지만 (115.2 kHz in 및 2 MHz 아웃), 256 바이트 페이지가 전송 된 후에 쓰기주기 대기가 있습니다.


빈번한 SPI 인터럽트가 일부 UART 인터럽트를 차단하고 바이트를 놓치는 것으로 보입니다. 내가 선택한 솔루션은 UART 수신 인터럽트에 링 버퍼를 사용하고 바이트 전송에 대한 폴링 및 작성 완료를 통해 직렬 플래시로 전송되는 256 바이트 페이지 버퍼에 데이터를 공급하는 것이 었습니다. 128 링 버퍼는 SPI 쓰기 동안 오버플로를 방지 할 수있을 정도로 큽니다.

도움이 되었습니까?

해결책

나는 PC에서 산란 모자처럼 할 일을 할 것입니다. 이와 같은 구조물의 링크 된 목록을 만듭니다.

typedef struct data_buffer {
    char flags;
    char[128] data;
}

플래그에 비트 중 하나가 "ReadyToflash"를 의미하고 "플래싱"을위한 것입니다. 링크 된 목록의 버퍼 수를 조정하여 플래시가 UART를 작성하거나 그 반대의 경우도 마찬가지입니다.

플래시가 "ReadyToflash"가 아닌 버퍼 블록에 도달하면 멈추고 UART IRQ를 다시 시작해야합니다. UART가 "ReadyToflash"또는 "Flashing"인 블록에 도달하면 너무 빠르게 채워지고 다른 버퍼가 필요할 것입니다. 동적 메모리가 있으면 런타임 에이 튜닝을 수행하고 즉시 목록에 버퍼를 추가 할 수 있습니다. 그렇지 않으면 경험적 테스트를 수행하면됩니다.

다른 팁

애플리케이션의 UART와 PC 측은 RS-232 핸드 쉐이킹 (흐름 제어)을 지원합니까? 그렇다면 수신 버퍼가 가득 차면 ISR에 CTS 라인을 떨어 뜨리십시오. PC 쪽이 하드웨어 흐름 제어를 존중하도록 구성되면이 조건을 볼 때 전송을 중단해야합니다. 수신 버퍼가 배수되거나 거의 배수되면 CTS를 다시 주장하면 PC가 다시 전송을 시작해야합니다.

이로 인해 임베디드 장치의 소프트웨어가 상당히 복잡해집니다. 기꺼이 트레이드 오프를할지 여부에 관계없이 귀하와 귀하의 관리자 및 팀이 분석해야합니다.

이것이 바로 흐름 제어가 만들어진 것입니다. 나는 그것의 큰 고통이 설정되어 있다는 것을 알고 있지만 직렬 라인에서 흐름 제어를 가능하게하면 문제가 역사 일 것입니다.

바이너리 파일을 전송한다고 가정하므로 Xon-Xoff가 최상의 솔루션이 아니기 때문에 하드웨어 흐름 제어를 남깁니다.

또 다른 옵션은 Xmodem과 같은 내장 플로우 제어 기능이있는 프로토콜을 사용하는 것입니다. 플래시가 128 바이트 페이지로 작성되는 비슷한 임베디드 프로젝트가 있습니다. Xmodem이 128bete 덩어리로 데이터를 보내는 일치는 다음을 보내기 전에 ACK를 기다립니다.

내가 여기서 누락 된 내용은 확실하지 않지만 PC에서 오는 평균 데이터 비율이 평균 속도보다 높다는 사실이 사실이라면 플래시에 쓸 수있는 평균 속도보다 높으면 많은 RAM이 필요할 것입니다. 또는 흐름 제어가 필요합니다.

그러나 블록 버퍼가있을 때 효과가 있었지만 지금은 바이트 버퍼가 있으므로 그렇지 않습니까?

UART RX 인터럽트로 채워진 블록 버퍼를 고수 할 수 있으며 각 버퍼가 가득 찼을 때 SPI/플래시 코드로 전달하여 SPI 인터럽트를 사용하여 해당 버퍼를 비우십시오. 그러면 각 바이트를 복사 할 수 있으며 각 바이트에 대해 원형 버퍼 로직을 두 번 수행하는 대신 각 블록에 대해서만 수행하면됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top