Обновить

STM32: Виртуальный COM порт на USB (Serial Over USB)

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели9.9K
Всего голосов 12: ↑12 и ↓0+13
Комментарии11

Комментарии 11

Прерывание (Interrupt Trap) — событие в микропроцессоре, которое провоцирует замену значений регистров процессора и вызов отдельной функции ISR.

как то это не очень правильно сформулировано. Например что значит замена значений регистров? Это какое-то совершенно не традиционное слово "замена" в данном контексте.

Но дело даже не в этом. Гораздо чаще именно обновление значений в регистрах ведет к генерации прерываний (событий) в микропроцессоре (так же как и в больших процессорах). Например Timer может генерировать прерывания на основании изменившегося значения регистра счета Timer-а.

По моему гораздо важнее понимать, что именно изменения в регистрах вызывают прерывания, как раз для того чтобы софт (программа) смогла отреагировать на эти изменения.

Ну и дальше:

прерывания используются для работы с внешними периферийными устройствами SoCa: Timer, UART, DMA и пр

зачем скакать-то с микропроцессоров на какие-то непонятные SoC - это же точно не помогает читателю понять о чем идет речь, особенно если речь идет о STM32. Наверно без пафосных SoC-ов будет гораздо понятнее:

прерывания используются для работы со встроенными (как они могут быть внешними совершенно не понятно!) периферийными устройствами микропроцессора: Timer, UART, DMA и пр

Сформирулировано действительно так, что ещё больше запутывает, но, полагаю, что это имеются в виду регистры ядра ARM (pc, sp и т.п.) и описан механизм переключения контекста - значения регистров сохраняются, исполнение передается обработчику прерывания, после значения возвращаются обратно.

хорошее замечание! я думаю вы действительно угадали о чем думал автор статьи. Но это тем более не правильная формулировка со стороны автора - получается главное в прерываниях что они меняют значения регистров - абсолютно вывернутый на изнанку смысл назначения прерываний и того откуда они берутся и зачем нужны.

Во первых, в этом случае (с теневым набором регистров) меняются не значения регистров, а переключаются наборы регистров, но это детали СПЕЦИАЛЬНОЙ аппаратной реализации прерываний на определенной аппаратной платформе, которые не характеризуют само назначений прерываний - поэтому вспоминать про это в обобщенной формулировке термина, наверно, не стоит. А формулировка явно претендует на обобщенность поскольку туда и SoC приплели, например.

Ну а в самых первых (важнее чем во первых), это совсем не про назначение прерываний и того откуда они берутся и зачем нужны.

Но за статью в целом плюс, кто-то еще занимается реальной работой, а то все в основном фантазируют как они будут командовать умной программой которая за них все напишет.

А если очередь отправки TxFIFO была некоторое время пуста, как вы поймёте, что в ней появились новые данные?

Очень хороший вопрос.
Для этого есть периодическая проверка в суперцикле

/*can be called form ISR TODO rename to usb_serial_tx_next */
bool usb_serial_tx_next(const uint8_t num) {
    bool res = false;
    UsbHandle_t *Node = UsbGetNode(num);
    if (Node) {
        if (Node->init) {
            uint32_t outLen = 0;
            res = fifo_pull_array(&Node->TxFifo,
                                  Node->TxBuff, 
                                  sizeof(Node->TxBuff),
                                  &outLen);
            if (res) {
                res = usb_serial_send(num, Node->TxBuff, outLen);
            }
        }
    }
    return res;
}
bool usb_serial_proc_one(const uint8_t num) {
    bool res = false;
    LOG_PARN(USB_SERIAL, "Proc:%u", num);
    UsbHandle_t *Node = UsbGetNode(num);
    if (Node) {
        if(false==Node->tx_in_progress) {
            uint32_t cnt = fifo_get_count(&Node->TxFifo);
            if(cnt) {
                res = usb_serial_tx_next(num);
            }
        }
    }
    return res;
}

А почему не по прерыванию?

для справки, SoC (система на кристалле) - это обычно (изначально) это объединение на одном кристалле (в чипе, в одной микросхеме) содержимого нескольких микросхем, это обычно два процессорных ядра плюс шаренная между ними память и переферия которая таким образом тоже становится шареной между этими двумя ядрами. Система в таком случае подразумевает что было как минимум три микросхемы два процессора и память и набор шин между ними, возможно со спец контроллерами шин, а тут все это упаковали в один кристал-чип-микросхему, то есть в микросхему упаковали целую плату с разводкой.

это обычно два процессорных ядра плюс шаренная между ними память и переферия которая таким образом тоже становится шареной между этими двумя ядрами

Ну правильно. Внутри SoC STM32 как раз несколько автономных подсистем.
--Ядро ARM Cortex-M
--Сопроцессор FPU
--Два сопроцессора DMA
+ общая для их всех физическая память

я думаю USB контроллер встроенный будет даже посложнее чем Сопроцессор FPU или чем сопроцессор DMA (хотя контроллер ДМА я не помню чтобы инструкции выполнял, насколько я знаю он управляется регистрами), что же вы про него забыли. А во многих современных "микро-"процессорах еще и Ethernet (MAC) контроллер присутствует. И тот и другой (USB и MAC) обычно в своем составе имеют свой, узко специализированный, ДМА-контроллер...

Вообще говоря, да! Это, в любом случае, огромная система в одной микросхеме (то есть на кристалле) с шинами и разными типами памяти, но все таки, изначально, под SoC имелась ввиду определенная специфика о которой я написал выше.

Привет. Не подскажете, ваш метод подойдет для STM32F407 DISCOVERY? Было бы здорово чисто программно реализовать COM соединение через разъем ST-Link, а не OTG разъем. И без подпайки проводами к USART2 MCU ST-Link. В общем сделать Virtual COM, как на платах Nucleo.

Привет. Не подскажете, ваш метод подойдет для STM32F407 DISCOVERY?

Да, но тогда надо его сконфигурировать на OTG разъеме.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации