Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: STM32 новичку в ARM что к чему

Ср июл 14, 2021 12:00:13

А вот чего реально не хватает, так это каналов DMA!!! Их нужно хотя бы 32. Но лучше бы — 64. С семью каналами F072 далеко не уйдешь. Да и у F303 всего-то на 5 каналов больше. Тоже мне…

Есть G0 у который 3 SPI, 3 I2C, 6 USART, 2 LPUART и 13 таймеров, не считая всякие SysTick, а каналов DMA всего 12, хотя DMAMUX позволяет связать любой канал с любой периферией. Возможно это не каналов мало, а концепция их использования не совсем верна :)

Re: STM32 новичку в ARM что к чему

Ср июл 14, 2021 14:02:07

А как вы по UART через DMA работаете? Он же обычно под строки неизвестной длины используется, с терминирующими символами.

Re: STM32 новичку в ARM что к чему

Ср июл 14, 2021 14:17:40

COKPOWEHEU, Tx у меня всегда по DMA, а с Rx, конечно, чаще по прерыванию буфер наполняю, но вот при работе на скоростях под мегабод нужно DMA. Для понимания, что строка закончилась, использовать прерывание по символу '\n'.
С SPI на F072 и Rx, и Tx по DMA очень удобны. Вот с I2C DMA нет смысла использовать, т.к. обычно посылки короткие, а отрабатывать NAK'и на этапе адресации все равно придется.
А вот это:
Есть G0 у который 3 SPI, 3 I2C, 6 USART, 2 LPUART и 13 таймеров, не считая всякие SysTick, а каналов DMA всего 12

считаю вообще издевательством над пользователями! На кой черт такая прорва периферии, если даже половину нельзя одновременно запустить? 3 SPI убьют 6 каналов DMA, если даже в USART'ах только на Tx использовать DMA, то все каналы уже кончились!

А примеров, когда нужно одновременно (еще и порой на разных скоростях) несколько усартов использовать, придумать можно множество. Вот, делал как-то хронометр для соревнований. Там одновременно три усарта (GPS, дальномер и канал служебных сообщений; по USB — основной канал). А в планах было два дальномера втыкать + еще блютус (через USART) и GSM для общения СМСками старта и финиша. Если же захочется экономить на общении, то вместо SMS нужно будет еще один усарт в качестве модема использовать (т.е. дозвонился один раз финиш до старта и держит связь), либо ШИМ'ом делать частотную модуляцию!

Re: STM32 новичку в ARM что к чему

Ср июл 14, 2021 14:42:11

А примеров, когда нужно одновременно (еще и порой на разных скоростях) несколько усартов использовать, придумать можно множество. Вот, делал как-то хронометр для соревнований.

Хронометр - медленное устройство, если он сотые считает, то между ними будет 480 тыс. тактов, там DMA не нужен, а если сильно хочется, то 7 каналов точно хватит.

Re: STM32 новичку в ARM что к чему

Ср июл 14, 2021 23:44:48

Все-таки, что-то я, видимо, неправильно делаю с флешем. Потому что вот такого в нормальных ситуациях точно не может быть! Вот код:
Код:
static inline void gpio_setup(){
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; // for USART and LEDs
    GPIOA->ODR = 0; // don't work without this!
    GPIOB->MODER = GPIO_MODER_MODER0_O | GPIO_MODER_MODER1_O;
    GPIOB->ODR = 1;
}

Если закомментировать строчку с GPIOA->ODR=0, ничего не работает (хотя блымк на PB0/PB1, а тактирование GPIOA включаю для настройки USART)!
А если и мигает светодиодами, то зависает на первом же прерывании USART RXNE.

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 19:53:02

Eddy_Em а зачем столько DMA? Медленные процессы же нормально по IRQ обрабатывать и все это у людей сто лет даже совсем без DMA работало, еще и гибче намного. Представляю себе как скорость радостно поделится на 64. А дебажить это, когда раз в год все 64 одновременно ломанутся, и окажется что вот так оно не успевает обслуживать кого-то - не задолбаетесь потом? А там еще процессор на это претендует. Нехилая гирлянда. Если все это по внешним событиям и проч то средний и наихучший случай могут быть 2 разницы. И даже просто прикинуть его в гирлянде с 64 участниками + проц как-то не очень. И это при том что смысл небольшого микроконтроллера в предсказуемости?

У как минимум некоторых STM32F1xx есть еще DMA2, правда, там только 5 каналов, но 12 каналов на подобный чип ближе к верху разумного предела как мне кажется. С точки зрения адекватного поведения системы без лишней провокации странных вещей. И как минимум F1xx не созданы под огромные потоки данных. F0/G0/L0 еше более не для этого, чисто структурно, по шинам и памяти. Такой аппетит просит кучу шин и независимых банков памяти с кучей матриц коммутаторов и проч, т.е. большой и крутой чип. Может вам FPGA на самом деле хотелось вообще? :)

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 22:03:01

Прошерстил уже и линкер-скрипт: ничего страшного не нашел. Попробовал решить глюк с "мыргаю-не мыргаю" добавлением паузы после включения тактирования RCC_AHBENR_GPIOBEN. В общем, почему-то вот так работает:
Код:
static inline void gpio_setup(){
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; // for USART and LEDs
    for(int i = 0; i < 10000; ++i) nop();
    GPIOB->MODER = GPIO_MODER_MODER0_O | GPIO_MODER_MODER1_O;
    GPIOB->ODR = 1;
}

А без паузы - нет!
Ни у F0x2, ни у F103 такого глюка не встречал!
USART1 проверил - работает.

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 22:17:28

По виду этого костыля все выглядит как будто RCC_AHBENR_GPIOBEN почему-то возымел эффект не сразу и до этого включаемый блок либо не был активен, либо глючил. А код на ассемблере там адекватный получается в этом месте? Компилер ничего не переупорядочил/оптимизнул там?

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 22:18:23

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

Кстати, хорошо бы ещё проверить, а что будет, если эту паузу в самое начало программы поставить.

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 22:20:23

А без паузы - нет!

Видимо порты не успевают включиться, а ты их сразу инитишь. Убери паузу и проверь что в MODER записалось. HAL-ие макросы после включения периферии читают из регистра, чтобы удостовериться, что запись завершена.

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 23:01:31

HSE включаю в самом начале вот так:
Код:
TRUE_INLINE int StartHSE(){ // system bus 72MHz from PLL
    __IO uint32_t StartUpCounter = 0;
#define WAITWHILE(x)  do{StartUpCounter = 0; while((x) && (++StartUpCounter < 0xffffff)){nop();}; if(x) return 0;}while(0)
    RCC->CR = (RCC->CR & ~RCC_CR_PLLON) | RCC_CR_HSEON; // disable PLL to reconfigure, enable HSE
    WAITWHILE(!(RCC->CR & RCC_CR_HSERDY));
    // Enable Prefetch Buffer. Flash 4 wait states for 48..72MHz
    FLASH->ACR = (FLASH->ACR & ~(FLASH_ACR_LATENCY)) |
            FLASH_ACR_LATENCY_2 | FLASH_ACR_PRFTBE;
    // HCLK = SYSCLK (AHB prescaler = 1), PCLK1 = HCLK (APB1 prescaler = 1), PCLK2 = HCLK (APB2 prescaler = 1)
    // PLLCLK = HSE * 9 = 72MHz
    RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2 |
                               RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL | RCC_CFGR_USBPRE)
                 ) | RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLMUL9 | RCC_CFGR_USBPRE_DIV1_5;
    RCC->CR |= RCC_CR_PLLON; // Enable PLL
    // Wait till PLL is ready
    WAITWHILE(!(RCC->CR & RCC_CR_PLLRDY));
    // Select PLL as system clock source
    RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
    // Wait till PLL is used as system clock source
    WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1);
#undef WAITWHILE
    return 1;
}

Т.е. каждый раз ожидаю, а если проблема - возвращаю 0 (в этом случае включаю HSI и там по периоду видно, т.к. в этом случае системная шина на 48МГц, а не 72). В асме все нормально.

А еще у меня не получается FPU активировать. Добавил простую float переменную и выражение сложения. FPU активирую:
Код:
TRUE_INLINE void enable_FPU(){
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
}

Однако, фигвам! Несмотря на асмовские инструкции для FPU, МК "уходит в себя".

Re: STM32 новичку в ARM что к чему

Чт июл 15, 2021 23:48:20

на скоростях под мегабод нужно DMA

У меня юарт на 2Мбит лупашит. Кроме DMA пришлось прикрутить аппаратную детекцию таймаута по Rx, чтобы максимально быстро ловить пакеты. еще крутится спай, эзернет стек, CAN, отладочный юарт. даже работает.

Re: STM32 новичку в ARM что к чему

Пт июл 16, 2021 01:11:27

А уходит в себя - случайно не hardfault какой-нибудь, который не получился и активировался deadlock? Вроде это единственный эффективный способ совсем повесить ARM. И да, может с wait states что-то не так? Так наверное и настоящий deadlock можно поймать, если "что-то не так" будет и с обработчиком исключения.

И кстати конструкция вида #define WAITWHILE(x) do{StartUpCounter = 0; while((x) && (++StartUpCounter < 0xffffff)){nop();}; if(x) return 0;}while(0) мне не очень нравится. Вы для принятия решения проверяете хардварный регистр, дважды, при том что никто не обещал что хардварный регистр не поменяется сам по себе. Что-то типа if (StartUpCounter >= 0xffffff) -> таймаут было бы логичнее чем уповать на то что там в хардварном регистре. Просто потому что StartUpCounter не может меняться сам по себе, в отличие от. В данном случае проблема конечно не в этом, но может лучше так не делать лишний раз?

Re: STM32 новичку в ARM что к чему

Пт июл 16, 2021 08:45:14

Откуда ж я знаю: хардфолт там или нет? Даже если б я и хотел gdb запустить, ни один из этих 10МК не работает с SWD. Про это я уже писал: прошиваю через бутлоадер.
Что до проверки регистра, то без разницы: счётчик или содержимое регистра проверять.
А если регистр настроек меняется "сам по себе", то такой МК нужно выкинуть!

Re: STM32 новичку в ARM что к чему

Пт июл 16, 2021 09:42:51

Код:
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; // for USART and LEDs
GPIOA->ODR = 0; // don&#39;t work without this!
GPIOB->MODER = GPIO_MODER_MODER0_O | GPIO_MODER_MODER1_O;

Проверил, запись в MODER проходит только если перед ней хотя бы один NOP добавить, не важно от HSI тактироваться или от HSE+PLL. В общем-то ничего удивительного...

Добавлено after 3 minutes 58 seconds:
Однако, фигвам! Несмотря на асмовские инструкции для FPU, МК "уходит в себя".

-mfpu=fpv4-sp-d16?

Re: STM32 новичку в ARM что к чему

Пт июл 16, 2021 12:14:37

Откуда ж я знаю: хардфолт там или нет? Даже если б я и хотел gdb запустить, ни один из этих 10МК не работает с SWD. Про это я уже писал: прошиваю через бутлоадер.
Ну тогда завести в RAM флаг (магическое значение по известному адресу), в регионе RAM который бутлоадер не трогает (это важно). В обработчике hardfault и чего там - прописать желаемое значение как индикатор что это было. После этого запустить фирмвару, ресет, через бутлоадер слить RAM и посмотреть что в этом месте. Более продвинутый вариант: exec trace, несколько флагов для прохождения ключевых точек, заодно и readback всех интересных регистров рядом сложить заодно можно, и похрен что UART не работает! Когда нихрена не понятно на ранней инициализации, а дебагера под рукой нет, можно за 5 минут накодить это и через 10 получить ответ на интересовавшие вопросы ранней инициализации. Единственное условие - чтобы RAM можно было считать без ее порчи потом. Бутлоадер в ROM для этого удобен :). Дело в том что RESET# сам по себе RAM не сбрасывает, и содержимое кто-то должен явно вынести. Бутлоадер протирает только лимитированный регион которым он пользуется. Нормальная фирмвара обычно делает это в startup для получения стандартного окружения и реинициализации, но не обязана. С теми или иными вариациями, например можно делать флаги переживающие ребут, типа запроса активации своего бутлоадера после ребута и т.п.. Главное чтобы стартап их не грохал. Единственное что если hardfault сам падает, тогда будет уже именно deadlock. Проверить полный deadlock можно... ну, например, каким-нибудь IRQ типа systick'а и хранением счетчика накручиваемого им в известном месте. Если deadlock, счетчик как я понимаю застрянет. Если же умер только main thread, systick продолжит тикать и крутить счетчик. И ему довольно пофиг на живость всего остального, кроме разве что может быть стэка. И то можно обработчикам отдельный резерв стэка дать через MSP, ARM так умеет.

Что до проверки регистра, то без разницы: счётчик или содержимое регистра проверять.

Не согласен. Счетчик "однопортовый". Его читает и пишет только софт. Поэтому он целиком под контролем софта. Регистр "двухпортовый" - железо с 1 стороны, софт с другой. И если идея в том что таймаут ловит заскоки железа, ожидать конкретное поведение железки само по себе странная идея, а конкретно так можно при случае сделать очень странный TOCTOU срабатывающий не так как вы думали раз в 10 лет. Тут его вроде нет, но я бы 100% не дал, откуда я знаю как чип на самом деле может. Регистры, биты которых которых вы ждете - совершенно точно могут меняться железом.

А если регистр настроек меняется "сам по себе", то такой МК нужно выкинуть!

Довольно забавная идея сказать это, попутно ожидая пока железо ... само поменяет бит в регистре?! И оно совершенно точно меняет регистр, вы как раз именно этого и ждете.

Re: STM32 новичку в ARM что к чему

Пт июл 23, 2021 20:27:31

На 303 пока забил, есть более важные дела. Пытаюсь программно ввести STM32F042C6T6 в режим DFU. С 072 это на ура проходило, а вот с этим что-то затык вышел. Код такой:
Код:
#define SYSMEM03x 0x1FFFEC00
#define SYSMEM04x 0x1FFFC400
#define SYSMEM05x 0x1FFFEC00
#define SYSMEM07x 0x1FFFC800
#define SYSMEM09x 0x1FFFD800
// define SystemMem to other in MAKEFILE
#ifndef SystemMem
#define SystemMem SYSMEM04x
#endif

void Jump2Boot(){
    __disable_irq();
    void (*SysMemBootJump)(void);
    volatile uint32_t addr = SystemMem;
    // reset systick
    SysTick->CTRL = 0;
    // reset clocks
    RCC->APB1RSTR = RCC_APB1RSTR_CECRST    | RCC_APB1RSTR_DACRST    | RCC_APB1RSTR_PWRRST    | RCC_APB1RSTR_CRSRST  |
                    RCC_APB1RSTR_CANRST    | RCC_APB1RSTR_USBRST    | RCC_APB1RSTR_I2C2RST   | RCC_APB1RSTR_I2C1RST |
                    RCC_APB1RSTR_USART4RST | RCC_APB1RSTR_USART3RST | RCC_APB1RSTR_USART2RST | RCC_APB1RSTR_SPI2RST |
                    RCC_APB1RSTR_WWDGRST   | RCC_APB1RSTR_TIM14RST  |
#ifdef STM32F072xB
            RCC_APB1RSTR_TIM7RST   | RCC_APB1RSTR_TIM6RST |
#endif
                    RCC_APB1RSTR_TIM3RST   | RCC_APB1RSTR_TIM2RST;
    RCC->APB2RSTR = RCC_APB2RSTR_DBGMCURST | RCC_APB2RSTR_TIM17RST | RCC_APB2RSTR_TIM16RST |
#ifdef STM32F072xB
            RCC_APB2RSTR_TIM15RST |
#endif
                    RCC_APB2RSTR_USART1RST | RCC_APB2RSTR_SPI1RST  | RCC_APB2RSTR_TIM1RST  | RCC_APB2RSTR_ADCRST   | RCC_APB2RSTR_SYSCFGRST;
    RCC->AHBRSTR = 0;
    RCC->APB1RSTR = 0;
    RCC->APB2RSTR = 0;
    __DSB();
    // remap system flash memory to 0 (only for STM32F0)
    SYSCFG->CFGR1 = 0x01; __DSB(); __ISB();
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
    // set main stack pointer
    __set_MSP(*((uint32_t *)addr));
    // jump to bootloader
    SysMemBootJump();
}

По идее, по адресу 0x1FFFC400 должен переходить. А фигвам!!! МК настоящие, не паленые, купленные у доверенного поставщика года четыре назад. МК нулевый, т.е. в options bytes не может быть мешающего мусора. Если boot0 перед включением питания кидаю на +3.3В, в DFU выходит.
В интернетах аналогичный код у людей. Вот как так может быть?

Re: STM32 новичку в ARM что к чему

Сб июл 24, 2021 23:46:48

В общем, оказалось, что программно перевести F042 в DFU невозможно: там есть эдакий механизм контроля, который запрещает программный запуск DFU, если в первых 4 байтах флеша что-то есть. А стереть первую страничку и потом активировать DFU невозможно.

Буду знать. Ну их нафиг, эти 042, когда 072 намного лучше, а по цене даже дешевле иной раз выходят!

Re: STM32 новичку в ARM что к чему

Вс июл 25, 2021 00:39:40

А я сейчас бьюсь над сходной задачей: прошивка gd32vf103 (risc-v), который прошиваться по JTAG не хочет (а по SWD и вовсе не умеет). Зато умеет через stm32flash по UART. Но поскольку прошивку писать буду я, никакой гарантии, что попадет в загрузчик, нет. Значит, надо его ресетить, отключать от USB и выставлять boot снаружи.
Получилось устройство на stm32f103 (то VF, это F, не путать!), которое прикидывается двумя UART'ами (не лишаться же отладки из-за кривого программирования!) плюс логикой для обычных GPIO на соответственно RESET, BOOT0 и релюшку D+/D-. Ну и раз все равно пилю самодельный прогамматор, можно добавить свистелок - независимое управление 16-ю выходами и аналоговый вход, которые работают через Custom-HID, а аналоговый вход еще и как микрофон 44 кГц.
Такое вот составное устройство: CDC + CDC + HID + Audio
Основная часть уже готова, осталось только правильно настроить переключение двух UART'ов, потому что иногда заклинивает в неправильном режиме.

Re: STM32 новичку в ARM что к чему

Вс июл 25, 2021 10:00:55

В общем, оказалось, что программно перевести F042 в DFU невозможно: там есть эдакий механизм контроля, который запрещает программный запуск DFU, если в первых 4 байтах флеша что-то есть. А стереть первую страничку и потом активировать DFU невозможно.
И что? "запрещает программный запуск DFU из ROM", но никто не запрещает в своём ПО (которое уже во флешь) реализовать этот самый DFU. Тем более, что протокол простой.
Ответить