У меня есть микроконтроллер, который должен загрузить большой файл с последовательного порта ПК (115200 бод) и записать его в последовательную флэш-память через SPI (~ 2 МГц). Флэш-запись должна быть в 256-байтовых блоках, перед которыми стоят команда записи и адрес страницы. Общий объем доступной оперативной памяти в системе составляет 1 кБ при размере стека 80 байт.
В настоящее время это работает путем заполнения 256-байтового буфера из UART и последующего пинг-понга к другому 256-байтовому буферу, заполняемому прерыванием по сигналу готовности RX-буфера, в то время как флэш-память записывается с занятыми записями. Замена буфера повторяется до завершения операции.
Я бы предпочел настроить обработчики прерываний TX / RX для портов SPI и UART, которые работают на отдельных кольцевых буферах. Таким образом, вместо опроса новых байтов и ожидания завершения операций я могу просто заполнить буферы TX и включить прерывание или проверить буферы на наличие входящих данных. Это дало бы намного больше тактов для реальной работы вместо ожидания на периферии.
После реализации IRQ с 128-байтовыми кольцевыми буферами я опрашиваю данные в буфере UART RX и немедленно помещаю его в буфер SPI TX, чтобы выполнить передачу файла. Проблема, с которой я сталкиваюсь при таком подходе, заключается в том, что у меня недостаточно оперативной памяти для буферов, а приемный буфер ПК заполняется быстрее, чем я передаю данные в буфер флэш-передачи. Очевидно, что проблема не в скорости передачи (115,2 кГц на входе и 2 МГц на выходе), но после каждой 256-байтовой страницы происходит ожидание цикла записи.
Похоже, что частые прерывания SPI блокировали некоторые прерывания UART и приводили к пропуску байтов. Решение, которое я выбрал, состояло в том, чтобы использовать кольцевой буфер для прерывания приема UART и подавать данные в 256-байтовый буфер страницы, который отправляется на последовательную флэш-память путем опроса передачи байтов и завершения записи. Кольцевой буфер 128 достаточно большой, чтобы предотвратить переполнение во время записи SPI.