Обновить
8
14
Данил@danil_12345

Пользователь

Отправить сообщение

Мотором я решил управлять через «Январь» 5.1 6ц на прошивке TRS251.

Что такое «Январь» 5.1? Название прошивки? Название PCB?
И главный вопрос: почему название это слово обозначающее вообще время года?

Оk. Заменил на CAN MAC.

Если п.1<>п.3

Что значит оператор "<>" ?

После 72ой минуты 32 таймер переполнится и начнет считать заново. Можно генерировать прерывания и по slave таймеру, умножать счетчик прерываний на 0xFFFFFFFF и прибавлять cnt32. В результате получится уже тайм штамп типа uint64_t.

А что будет, если при чтении попадëм на обновление слейв-таймера?

Я видел такое решение

uint32_t time_stamp_get_us( void ) {
    uint32_t tim_word_lo = 0x0000; 
    uint32_t tim_word_hi = 0x0000;
    do {
        tim_word_lo = TIM3->CNT;
        tim_word_hi = TIM9->CNT;
    } while( tim_word_hi != TIM9->CNT );
    uint32_t timestamp_dword=(tim_word_hi<<16)|tim_word_lo;
    return timestamp_dword;
}

Однако почему так сделано - затрудняюсь пояснить.

Да. Это классическая "ошибка 71ой минуты".

>>> ((10**(-6))*(2**32))/60
71.58278826666667

Что делать - не знаю.
Переходить на RISC-V.
Там 64битный systick встроен прямо в ядро!

Обновление tim_word_hi происходит раз в 65 ms.
Я бы предпочел ничего не делать.
На следующей итерации прочитается уже корректное значение.

А я предлагаю каскадный 32бит таймер, который вообще прерывания не производит.

в обработчике прерываний по переполнению тех же 16 битных таймеров? А зависимый функционал будет плясать от значения такого счетчика.

Прерывания каждую микросекунду?
Приложение будет тормозить.

A RTT будет работать при пере сбросе питания?
Вот UART сохраняет Link, если Target ресутнуть.

Никогда не ждите событий в бесконечных циклах - в них и поляжете.

У меня как раз есть условие выхода

            uint32_t up_time = TIME_GetMs();
            uint32_t diff = up_time - up_time_start;
            if(200 < diff) {
                res = false;
                break;
            }

Спасибо за описание решения. Но чем кольцевой буфер отличается от FIFO?

Надо ждать в for(;;) пока UART трансивер под освободит TxFIFO и вложить туда новые данные.
Или просто увеличивать счетчик об ошибках.

Хороший вопрос. Пока у нас разрешена только SafeRTOS

Можно ждать отправки не всегда, а только в случае, если в программном буфере TxFIFO не достаточно места, чтобы добавить туда ещё одно сообщение, если позволяет логика программы, и с таймаутом. 

Да. У меня это выглядит так

/*Wait until a free space appears in the Tx Queue*/
bool UART_WaitFifoSpace_LL(UartHandle_t* node, uint32_t size) {
    bool res = false;
    if(node->init_done) {
        uint32_t cnt = 0;
        uint32_t up_time_start = TIME_GetMs();
        while(1) {
            cnt++;
            uint32_t spare = FIFO_GetSpare(&node->TxFifo);
            if(size <= spare) {
                res = true;
                break;
            }
            uint32_t up_time = TIME_GetMs();
            uint32_t diff = up_time - up_time_start;
            if(200 < diff) {
                res = false;
                break;
            }
        }
    } else {
        res = false;
    }
    return res;
}

Первая (очевидная, да, кэп!) - не использовать один и тот же UART для логов и для связи с чем-то другим.

Как же тогда один кабель Ethernet используется для сотен протоколов внутри трафика?

сама расставит мьютексы при инициализации драйвера и две задачи не попытаются писать в один UART каждая свое. 

У меня NoRTOS прошивка.

Спасибо. Надеюсь заметка поможет Вам в программировании микроконтроллеров.

Информация

В рейтинге
497-й
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Зарегистрирован
Активность