ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
24 апреля
1005208 Топик полностью
RxTx (17.05.2020 10:11 - 20:16, просмотров: 857) ответил NAUT на Что было-то?
Я пока что в командировке, так что "решено" это условно, временно. Я к тому так написал чтобы не ломали голову из-за меня, как бы не тратили энергию. Но если есть какие-то мысли, конечно пишите. Приеду домой, буду разбираться, трассировать времянки итд. "Решено" так: сделал код прерывания как можно более коротким, просто запись в ring buffer. Об этом писал здесь: и один из UART'ов у меня уже был так построен. Этот (отладочную консоль) я перевел, остался еще один, 

сейчас

переписываю.

http://caxapa.ru/1000878?todo=full

Лично-субьективно считаю fk0 был прав вскричав насчет ITM_SendChar(). Это что-то я не подумал, понадеявшись что она хоть и блокирующая (я видел её код до этого), достаточно скоростная. Камень STM32F407 @ 168Mhz, SWOCLK = 2Mhz (супротив ~115khz), да и привык к JLINK'у, где это < 1 usec.

Поэтому я был достаточно беспечен :)


Работаю в Debug'е.


Да, UART-линк на STM32 жручая CPU вещь, так как 115200/(8+2) = получаем прерывание с частотой 11.520 Hz = 11.5 KHz на один UART.


Но тут не всё так просто.

Во-первых, у меня весь проект работал абсолютно без малейших проблем на AT91SAM7S.. @ 48Mhz (это ARM7TDMI) (проект велся на IAR)

проблемы посыпались как из рога изобилия стоило перейти на STM32F407 @ 168Mhz , учитывая что он быстрее в несколько раз.

(проект на Atollic STM32 True Studio, компилер GCC)


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

Это примитивный парсер вида waitdata-charsdata-crlf, всего лишь switch по состоянию, и затем cmdline[idx++] = c; в момент конца строки memcpy 5 байтов.


Внутри есть еще прерывания:

1. Молотит 1 KHz таймер, крутящий одну переменную.

2. 500-700 Hz таймер на степпер шагового двигателя (достаточно тяжелый)

3. И еще пара линков на UART'ах на 115200.



Скорее всего у меня что-то с приоритетами прерываний.

Плюс, я уверен, за счет STM "HAL" все прерывания утяжелились в несколько раз.


Буферизован или нет UART AT91SAM7S я не помню, имхо нет. Сейчас поискал по datasheet'у, з..лся искать, ничего не нашел.



Исправленный код стал такой:

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
    //HAL_UART_IRQHandler(&huart1);
    volatile unsigned int status;
    volatile unsigned char b;

status = USART1->SR; if ((status & USART_SR_RXNE) == USART_SR_RXNE) { b = USART1->DR; console.buf[console.writepos] = b; console.writepos = (console.writepos + 1) & (CONSOLE_CIRCULAR_BUFFER_SIZE-1); } }

В mainloop выгребаю из ringbuffer:

void CONSOLE_ProcessRingBuffer(void)
{
    while (console.readpos != console.writepos)
    {
        unsigned char b = console.buf[console.readpos];
        console.readpos = (console.readpos + 1) & (CONSOLE_CIRCULAR_BUFFER_SIZE-1);
        parser_addchar(b);
    }
}