|
libopencm3, Неплохая либа для кортексов... |
|
|
|
Mar 15 2013, 07:04
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(demiurg_spb @ Mar 15 2013, 12:35)  https://github.com/libopencm3/libopencm3ИМХО хорошая альтернатива стандартной библиотеки от ST и не только. TNX! Посмотрю потом, но все равно спасибо!
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Apr 3 2015, 13:24
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(esaulenka @ Apr 3 2015, 11:06)  Тут есть пользователи этой библиотеки? Нет пользоваться не стал, т.к. у них тогда сильно менялись интерфейсы библиотеки. Цитата Первое впечатление - написано заметно приятнее, чем Cube/SPL. Можно читать и не плеваться каждые 15 секунд. Склонность, правда, авторов к созданию своих велосипедов (почему бы не использовать родные определения регистров?..) несколько удивляет. Ну да ладно... Абсолютно такое же впечатление и у меня осталось. Цитата(AlexandrY @ Apr 3 2015, 13:38)  Детская поделка. А остальная половина файлов просто пустые. Аккуратней надо быть с такими ссылками. Не понял вашего юмора. Да эта либа пока не претендует на полноту. Да есть что пилить. Но уже сейчас глазу гораздо приятнее смотреть на неё нежели на творения ST (SPL).
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 6 2015, 14:49
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(esaulenka @ Apr 3 2015, 11:06)  Собственно, у меня задача - сделать USB-Device. Что-то как-то работает, однако мне сильно не нравится реализация USB без прерываний, опросом. Попытка запихать usbd_poll() в прерывание с разрешением такового пока к результатам не привела... у меня та же задача, msc. но поллинг пока устраивает. уже моск выкипел, определяется стабильно с 3 раза, это секунд 40, затыкается на отдаче scsi готов/неготов... хз как его отловить. Цитата(demiurg_spb @ Apr 3 2015, 16:24)  Не понял вашего юмора. Да эта либа пока не претендует на полноту. Да есть что пилить. Но уже сейчас глазу гораздо приятнее смотреть на неё нежели на творения ST (SPL). че там за полнота дожна быть? f3 f4 и хватит. в мелких вообще неясно нахрена эти обертки. Цитата(klen @ Apr 4 2015, 10:36)  голосую за libcm3
да libcm3 не полная, но... лучше я в этот проект комитить буду то чо недоделано вобщем каждому по вкусу.. +100500 там тоже иногда аццки хочется показать, шо так не делают, но в целом нормально. Только мне непонятно, чего они автогенерированные части, которые инклюдятся, с расширением *.c оставили - это ж бардак..надо каждый файлик перебирать и смотреть что включать в проект а что нет. Цитата куда не плюнеш -ПЕРЕКОСТЫЛИВАТЬ меняю клок инит через куб на регистры - минимум 2 кб кода уходит. Мама миа!
Сообщение отредактировал _Pasha - Apr 6 2015, 14:51
|
|
|
|
|
Apr 7 2015, 10:45
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(_Pasha @ Apr 6 2015, 17:49)  у меня та же задача, msc. но поллинг пока устраивает. уже моск выкипел, определяется стабильно с 3 раза Определяется стабильно. Прерывание тоже нормально работает вот с таким нехитрым кодом: Код extern "C" void OTG_FS_IRQHandler (void) { usbd_poll(usbd_dev); } Почему не взлетело сразу, я так и не понял... Сейчас борюсь с граблей - некорректно работает прием по control endpoint.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 12 2015, 15:50
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Цитата(klen @ Apr 4 2015, 10:36)  голосую за libcm3 Spl еще както было похоже на чтото , со скидкой что первый раз в первый класс.... но куб извините это говнокод. перевожу все проекты на куб а в результате поцесса получается что перевожу на регистры... при попытке воткнуть FreeRTOS обнаружил что куб использует системный таймер - пришлось перекостыливать куб, куда не плюнеш -ПЕРЕКОСТЫЛИВАТЬ.... а че они творят в яко бы дефолтных обработчиках прерываний... за каждый if else не по делу растреливать нада. куб это либа для школоты. единственное что понравилост - включение выключение переферии, макрос через регисты rcc
да libcm3 не полная, но... лучше я в этот проект комитить буду то чо недоделано вобщем каждому по вкусу.. Запускаю свой первый проект на HAL через CubeMX, не соглашусь, что это говнокод. Косяков, конечно, еще довольно много, но в целом все это собирается более менее небольшими усилиями и с FreeRTOS состыкуется хорошо, прерывания с обработкой всех флагов - if else меня не сильно напугали, понятно, что за универсальность приходится платить. На SPL код был оптимальнее, на какую то долю % быстрее и на какие то единицы % копактнее, но делал я его на порядок дольше, а памяти и мегагерцев и так некуда девать.
|
|
|
|
|
Apr 12 2015, 17:17
|
Профессионал
    
Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863

|
Цитата(kan35 @ Apr 12 2015, 18:50)  Запускаю свой первый проект на HAL через CubeMX, не соглашусь, что это говнокод. Косяков, конечно, еще довольно много, но в целом все это собирается более менее небольшими усилиями и с FreeRTOS состыкуется хорошо, прерывания с обработкой всех флагов - if else меня не сильно напугали, понятно, что за универсальность приходится платить. На SPL код был оптимальнее, на какую то долю % быстрее и на какие то единицы % копактнее, но делал я его на порядок дольше, а памяти и мегагерцев и так некуда девать. В этом HALе куда ни плюнь while (какой-то бит); то есть затачивать реально подо РТОС они это будут ещё как минимум очень долго.
|
|
|
|
|
Apr 13 2015, 09:52
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Golikov A. @ Apr 13 2015, 12:28)  строго говоря я не под что не пишу while(условие). У меня все ожидания с таймаутами.
Но пока я все равно не понял. Хотите сказать что при while(bit) не будет переключаться задачи? Да, не будут. Но к вашему случаю с двумя задачами это не относится. Реальная проблема возникнет когда будет несколько десятков задач и вы перестанете всех их помнить. Хотя думаю и семи хватит. Тогда while приведут к полному краху всей системы приоритезации. Скажем во всех задачах есть диагностика. Она пишет лог. А тот лог в свою очередь пишет в файл. А в драйвере файловой системы стоит while да хоть и с таймаутом. И все, кранты вашей риалтаймности.
|
|
|
|
|
Apr 13 2015, 10:00
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Вы знаете, но честно говоря меня напрягают оценки результатов труда одного программиста, другим. Прога это такая субъективная вещь ... Я правда тоже тут с одним образчиком творчества работаю .... Тоже разговариваю одними междометиями и нецензурными словами, но всё же ... Можно понять и тех кто делал тот же stdlib или куб. Когда я последний проект начинал был только stdlib - посмотрел, что он для меня обладает избыточной функциональностью. И отказался от него. Особенно меня напрягла работа с портами. Для инициализации порта требуется ввести три енума потом три массива и работать через процедуры. Короче на первый взгляд значительный и неоправданный оверхед. Особенно в сравнении с тем как я привык писать. Но когда потом смотрел некоторые части понимаешь смысл написанного. Так как у меня написано - не стандартизуешь. Мы разные цели ставим перед собой. Они изначально закладывают избыточность и пишут библиотеки, чтобы максимально перекрыть все возможные применения. А я строю реальное приложение, устраняю избыточность, нацелен на локальное использование. В общем объёме приложения - объём драйверов у меня составляет единицы процентов. Учитывая что я их пишу в 2 - 3 уровня, то получается драйвера камнезависимые вообще копейки. Поэтому я могу себе позволить их написать. Хоть каждый раз. А стандартными воспользоваться как примером в каких то случаях. Это общие моменты, а конкретно ... Я вижу что куб был рассчитан на применение в составе ОСи. Причём обкатывался с разными. Приведу пример. Я использовал драйвер Ethernet из куба. Поскольку у меня не было заведено прерывания на обрыв линии, как это реализовано в кубе, то мне пришлось это сделать опросом в другой задаче... Я посмотрел их код и вижу например heth->State ... Это для чего написано? Для разруливания работы с устройством из под разных задач. И некоторые другие вещи. И как результат подключение не вызвало никаких проблем. У меня всё заработало устойчиво. Наверняка там тоже есть что оптимизировать. Так этим никто не запрещает заниматься. Даже механизм блокировки вы можете привести в соответствие с применяемой осью.
|
|
|
|
|
Apr 14 2015, 14:21
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Тут всё просто. Если ждать долго, то надо на окончение ожидания настраивать прерывание, и ждать флага. Если недолго, то ждать, опрашивая в цикле. В частности, FRAM работает быстро, поэтому есть вероятность, что от попыток переноса ожидания в прерывания будут только дополнительные тормоза. Естественно, ожидание в цикле опроса желательно производить в менее приоритетной задаче, чтобы более важные задачи могли этот цикл прервать.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 14 2015, 14:35
|
Профессионал
    
Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863

|
Цитата(AHTOXA @ Apr 14 2015, 17:21)  Если ждать долго, то надо на окончение ожидания настраивать прерывание, и ждать флага. Кто вам создаст это прерывание? А "флаг" как ждать? Чем его ожидание отличается от ожидания бита? Цитата(AHTOXA @ Apr 14 2015, 17:21)  Если недолго, то ждать, опрашивая в цикле. Это ничего в принципе не меняет. Просто вечный while переходит из HALа в вашу программу. Можно сделать while (нет бита) шедьюлинг();правда тогда период опроса будет много миллисекунд, что может быть долго.
|
|
|
|
|
Apr 14 2015, 14:51
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(Golikov A. @ Apr 14 2015, 14:16)  А вот теперь я задумался, а как с учетом заточености под RTOS правильно делать передачу данных, допустим по SPI в режиме мастера, допустим с какой-нибудь FRAM? Ведь там есть послать данные, подождать бита готовности памяти и принять их. Как бита ждать? Вообще-то для этого под оси и пишутся драйвера, они висят на прерываниях железа, более высокого уровня, чем переключатель контента у оси, и работают через стандартные потоки, как драйвер ком-порта под виндой, например... Ну или ждите в вечном цикле, если это устройство монопольно используется.
Сообщение отредактировал mantech - Apr 14 2015, 14:52
|
|
|
|
|
Apr 14 2015, 17:01
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Dr.Alex @ Apr 14 2015, 19:35)  Кто вам создаст это прерывание? А "флаг" как ждать? Чем его ожидание отличается от ожидания бита? Прерывание мне никто не создаст, придётся самому :-) Под флагом я имел в виду какой-нибудь объект синхронизации операционной системы (event, mutex). Соответственно, ожидание такого флага -- усыпляет ожидающий процесс. Цитата(Dr.Alex @ Apr 14 2015, 19:35)  Это ничего в принципе не меняет. Просто вечный while переходит из HALа в вашу программу. Можно сделать while (нет бита) шедьюлинг(); Ну зачем же вечный? Можно с тайм-аутом. Мысль моя была о том, что если период ожидания бита ожидается короткий (например, гарантирован в даташите на FRAM), то такое ожидание ничем не отличается от просто небольшого цикла по ходу выполнения. Поэтому принимать специальные меры для перевода процесса в сон на время этого ожидания вряд ли целесообразно. Например, я не усыпляю процессор на время передачи пары байт по SPI. А вот на время передачи блока из 512 байт в SD-карту - уже усыпляю, ибо уже успею за это время сделать что-нибудь ещё полезное. ЗЫ. В вытесняющей оси "while (нет бита) шедьюлинг();" ничего не даст, потому что вернёт управление тому же самому процессу. Лучше тогда while (нет бита) sleep(1);
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 14 2015, 17:04
|
Профессионал
    
Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863

|
Цитата(AHTOXA @ Apr 14 2015, 20:01)  Ну зачем же вечный? Можно с тайм-аутом. С тайм-аутом или без не важно, всё равно это "вечный цикл" с точки зрения операционки. Цитата(AHTOXA @ Apr 14 2015, 20:01)  ЗЫ. В вытесняющей оси "while (нет бита) шедьюлинг();" ничего не даст, потому что вернёт управление тому же самому процессу. Лучше тогда while (нет бита) sleep(1); Осёвый "sleep" это и есть функция, вызывающая шедьюлинг..
|
|
|
|
|
Apr 14 2015, 17:59
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Dr.Alex @ Apr 14 2015, 22:04)  С тайм-аутом или без не важно, всё равно это "вечный цикл" с точки зрения операционки. Нет. С тайм-аутом цикл не вечный. Это просто несколько шагов выполнения алгоритма. То, что они оформлены в цикл - ничего не меняет. Так можно договориться до того, что и вычисление математических функций тоже придётся признать "вечным циклом", неприменимым в программировании с ОС. А что, какой-нибудь atan2() - вон как долго вычисляется! Значительно дольше, чем я буду ожидать флага опустошения передатчика SPI перед отправкой туда символа. Цитата(Dr.Alex @ Apr 14 2015, 22:04)  Осёвый "sleep" это и есть функция, вызывающая шедьюлинг.. Нет. Осёвый "sleep" не просто вызывает шедулинг, он ещё перед этим переводит текущий процесс в состояние ожидания.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 14 2015, 18:16
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Вообще-то для этого под оси и пишутся драйвера, они висят на прерываниях железа, более высокого уровня, чем переключатель контента у оси, и работают через стандартные потоки, как драйвер ком-порта под виндой, например... Ну или ждите в вечном цикле, если это устройство монопольно используется. это плохой ответ, не о чем... Цитата А вот на время передачи блока из 512 байт в SD-карту - уже усыпляю, Имеется ввиду, запускаем ДМА, а задачу в sleep, то есть ОС будет к ней возвращаться с каким то своим достаточно большим интервалом, так? Подытожим, у нас есть варианты: 1. усыпление процесса и возврат к нему с долгими интервалами для проверки дождались или нет (ожидание чего-то очень долгого) 2. это прерывание на окончание ожидания и в нем какой-то симафор, что позволяет ожидающую задачу усыпить до появления симафора. (если надо подождать среднюю длительность) 3. это долбим проверку интервала прямо в задаче циклом. В некоторых ОС будут переключать задачи по временным интервалам, если ожидание затянется, а в некоторых все задачи будут ждать эту. (ожидаем чего-то очень короткого) правильные варианты? Мне как-то внутренне кажется устраивать заопарк прерываний в ОС не верно. Ну то есть отправку UART сделать буфер, и прерывание символ ушел - пихать следующий символ, и так поступить со всеми интерфейсами. Боюсь что так система станет слабо предсказуемой и постоянно что-то ковыряющейся в прерываниях... Ведь их то между собой поделить будет нельзя, посылки по UART забьют передачи по другим интерфейсам, например... Не понятно как это решить в универсальной библиотеке
|
|
|
|
|
Apr 14 2015, 18:40
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Golikov A. @ Apr 14 2015, 21:16)  Мне как-то внутренне кажется устраивать заопарк прерываний в ОС не верно. Именно, о чем я вам и говорил. В драйверах доступа к всяческой памяти никаких вытеснений и семафоров RTOS. Кто так делает убивает RTOS и получает просто примитивную многозадачность. Нельзя надеятся, что RTOS облегчит написание низкоуровневых драйверов. Наоборот она их усложняет. Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний. Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA. Сами прерывания это прерывания уровня ядра. Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных.
|
|
|
|
|
Apr 15 2015, 03:04
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AlexandrY @ Apr 15 2015, 00:40)  Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний. Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA. Иногда (при необходимости быстрой работы со сложной периферией) получаются очень сложные автоматы состояний со множеством состояний (десятками) и сложными переходами между ними. Код становится трудночитаем, ведь программирование в стиле автоматов состояний гораздо хуже читается чем линейный код. В таких случаях я иногда применяю подход "а-ля ISR-псевдозадача": создаю отдельный контекст (стек), при завершении очередной транзакции с периферией (получении прерывания от неё, от DMA или от таймера), внутри ISR переключаюсь на этот контекст, выполняю участок кода до след. запроса к периферии (после которого следует обратное переключение контекста на исходный стек ISR с выходом из ISR). И по завершении этого запроса - опять вход в ISR-псевдозадачу. Получается простой хорошо читаемый линейный код вместо леса автомата состояний. Надо только не забывать про уровни приоритетов ISR, участвующих в этом (на NVIC). Можно просто сделать все одного уровня. Цитата(AlexandrY @ Apr 15 2015, 00:40)  Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных. О готовности данных, или освобождении какого-то ресурса (занятого буфера или флага в API доступа к драйверу, работающему на уровне прерываний) и т.п..
|
|
|
|
|
Apr 15 2015, 03:59
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Golikov A. @ Apr 14 2015, 23:16)  Имеется ввиду, запускаем ДМА, а задачу в sleep, то есть ОС будет к ней возвращаться с каким то своим достаточно большим интервалом, так? Не в sleep, а в wait(). В ожидание объекта синхронизации (event, mutex, ...). А объект синхронизации взводится в прерывании по окончании передачи. В этом случае ОС не будет возвращаться к ожидающей задаче с каким-бы то ни было интервалом - задача будет спать чётко до момента окончания передачи. И затем практически сразу проснётся.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 15 2015, 04:46
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(jcxz @ Apr 15 2015, 06:04)  Иногда (при необходимости быстрой работы со сложной периферией) получаются очень сложные автоматы состояний со множеством состояний (десятками) и сложными переходами между ними. Код становится трудночитаем, ведь программирование в стиле автоматов состояний гораздо хуже читается чем линейный код. В таких случаях я иногда применяю подход "а-ля ISR-псевдозадача": создаю отдельный контекст (стек), при завершении очередной транзакции с периферией (получении прерывания от неё, от DMA или от таймера), внутри ISR переключаюсь на этот контекст, выполняю участок кода до след. запроса к периферии (после которого следует обратное переключение контекста на исходный стек ISR с выходом из ISR). И по завершении этого запроса - опять вход в ISR-псевдозадачу. Получается простой хорошо читаемый линейный код вместо леса автомата состояний. Надо только не забывать про уровни приоритетов ISR, участвующих в этом (на NVIC). Можно просто сделать все одного уровня.
О готовности данных, или освобождении какого-то ресурса (занятого буфера или флага в API доступа к драйверу, работающему на уровне прерываний) и т.п.. В принципе не возражаю, только вот это - "хорошо читаемый" напрягает. Субъективизм же. Во первых в скоростной периферии важнее хорошая отлаживаемость Во вторых хорошо читаемый только короткий код. Расположите все ISR связанные с одним автоматом в одном месте и получите короткий код, понятно откоментируйте и отформатируйте и получите отличную читаемость.
|
|
|
|
|
Apr 15 2015, 05:02
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(AlexandrY @ Apr 14 2015, 21:40)  Работа с быстрой периферией по прежнему пишется в стиле автоматов состояний. Задержки делаются аппаратными таймерами. Переключение состояний автоматов производится в процедурах обслуживания прерываний по цепочке от разных источников включая DMA. Сами прерывания это прерывания уровня ядра. Прерывание RTOS вызывается только когда уже готов блок данных для обработки. И вот там-то взводится объект синхронизации о готовности данных. В принципе, да, это и есть "драйвер", о котором я выше "ни о чем" написал... И вообще, считаю "дурным тоном" писать обработчик какого-либо устройства в виде цикла с опросом битов, останавливая всю программу, может а аврках это еще считалось нормальным, но в чем-то посложнее, только прерывания без остановки основного цикла или задач.
Сообщение отредактировал mantech - Apr 15 2015, 05:05
|
|
|
|
|
Apr 15 2015, 05:47
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Golikov A. @ Apr 15 2015, 08:12)  ДМА настраивать на обмен 6 байтами - глупо, а 2 ДМА для приема 4 еще глупее. Да, если недальновидно выбран микроконтроллер. Я например сразу планирую сколько скоростных последовательных каналов будет в системе и прикидываю сколько каналов DMA понадобится. Чем больше каналов DMA тем лучше чип заточен под RTOS. Лучше всего здесь дела обстоять у Kinetis (32 канала), похуже у STM32F4 (16 каналов), еще хуже у LPC17xx (8 каналов)
|
|
|
|
|
Apr 15 2015, 06:55
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AlexandrY @ Apr 15 2015, 10:46)  В принципе не возражаю, только вот это - "хорошо читаемый" напрягает. Субъективизм же. Во первых в скоростной периферии важнее хорошая отлаживаемость Во вторых хорошо читаемый только короткий код. Расположите все ISR связанные с одним автоматом в одном месте и получите короткий код, понятно откоментируйте и отформатируйте и получите отличную читаемость. Вот такая работа с SPI (вполне хорошо читаемая и короткая при построении драйвера на уровне OS-задачи или как я описывал - псевдозадачей (выглядит так же как с OS)): Код FlashRead(); n = N_PAGES; do FlashWrite(); while (--n); при описывании state-машиной превращается в дикий лес, из нескольких десятков шагов с вермишельной логикой ветвлений: (учтите что здесь ещё надо расписать шаги внутри FlashRead()/FlashWrite(), с реализацией стека вызовов (стека state-переменных)) Код while (1) { switch (state) { case STATE_0: StartActionRead(...); state = STATE_1; break; case STATE_1: n = N_PAGES; case STATE_2: StartActionWrite(...); state = STATE_3; break; case STATE_3: state = STATE_ERROR; if (!result) continue; state = STATE_2; if (--n) continue; ... case STATE_ERROR: ... ... } break; } Особенно если учесть, что надо реализовать цикл(циклы), что внутри FlashWrite(), FlashRead() может быть несколько транзакций по SPI-шине с несколькими входами в ISR, могут быть циклы с проверкой условий и т.п.). Вообще если нужно сделать простейшую функцию (набор часто повторяемых действий) на базе state-машины. Если взять любой код драйвера, работающий на базе задачи ОС с использованием её объектов синхронизации (для уведомления о завершениях транзакций от ISR), и попытаться его развернуть в state-машину, то сразу видно какой получается малочитаемый код. State-машиной ещё вполне нормально реализуются простые линейные последовательности шагов алгоритма, без ветвлений и вызовов функций. Не более того.
|
|
|
|
|
Apr 15 2015, 07:37
|
Профессионал
    
Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863

|
Цитата(AlexandrY @ Apr 15 2015, 08:47)  Лучше всего здесь дела обстоять у Kinetis (32 канала), похуже у STM32F4 (16 каналов), еще хуже у LPC17xx (8 каналов) Тут дело даже не в "канальности". У STM32F4 например к каждому каналу (точнее, стриму) привязано до 8 определённых источников/приёмников данных. Поэтому если вы хотите использовать ДМА для 2-3-4 источников, привязанных к одному стриму, то вас может ждать облом. Точнее, облом был бы неминуем, но один и тот же источних часто (но не всегда) привязан к двум стримам (а в целом они распределены хаотично), но всё же облом вероятен (я — уже). Нет и речи о том чтобы использовать хотя бы половину стримов. А к примеру в "тупике эволюции" блэкфине каналы ДМА не привязаны к конкретной периферии. При этом забавно, что там каналов чуть ли не больше чем источников данных :-)))
|
|
|
|
|
Apr 15 2015, 08:42
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(Golikov A. @ Apr 15 2015, 08:12)  Вот и получается что "надо драйвер написать чтобы все в прерывании делал и не тормозил" - не о чем... Ну вот зачем такие голословные утверждения? Пример уарта делал, нужно передавать и принимать пакеты разной длины, делаю первое - в процедуре "инит" анализируется размер пакета на передачу, если пакет большой - запускаю ДМА, маленький, просто задаю глобальный счетчик, запускаю передачу - если ДМА, ждем флаг окончания, если счетчик, по прерыванию уарта уменьшаем и так до нуля, если событие передачи состоялось - генерю софт инт. Прием - запускаю дма и счетчик таймаута, жду событий и генерю софтинт, что сложного? И не надо ждать в циклах и ступорить ось. Все работает по прерываниям в режиме полного автомата.
|
|
|
|
|
Apr 15 2015, 09:07
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Dr.Alex @ Apr 15 2015, 13:37)  Поэтому если вы хотите использовать ДМА для 2-3-4 источников, привязанных к одному стриму, то вас может ждать облом. Точнее, облом был бы неминуем, но один и тот же источних часто (но не всегда) привязан к двум стримам (а в целом они распределены хаотично), но всё же облом вероятен (я — уже). Нет и речи о том чтобы использовать хотя бы половину стримов. Это одна из главных причин из-за которой недавно, при выборе МК для новой железки, мы отказались от STM32F4. Очень убого реализована периферия в нём - ни буферизации (FIFO) ни достаточного числа DMA-каналов для решения проблемы без FIFO.  Цитата(Golikov A. @ Apr 15 2015, 13:44)  Опять же иногда ДМА настроить дольше чем перепихать данные... LPC кстати имеет фифо - что здорово облегчает иногда дело, но все равно проблемы имеются... LPC, Tiva имеют нормальные FIFO (UARTы, SPI, etc). STM32 экономит на пуговицах непонятно зачем, значительно ухудшая характеристики МК.
|
|
|
|
|
Apr 15 2015, 09:59
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Когда у человека появляется красивый инструмент, возникает непреодолимое желание его использовать. Иногда вопреки здравому смыслу. И старый тут же объявляется вне закона. Смотрю различные драйвера обработки SPI - просто убивает. Порой визуально видно, что будет менее эффективно чем простой while. При частоте проца 168МГц и работе SPI 22, байт вылетает за 61 такт. Обработчик прерывания на SPI это не 2 строки. Плюс вход/ выход. В чём прелесть? Применение DMA порой ещё более натянуто. Я попробовал реализовать работу с флэшкой at45db. Правда у меня там разные режимы включая потоковую запись через разные буфера. Применение DMA существенно усложняет драйвер. Оценить выигрыш в производительности не представляется возможным. Оценить надёжность такой работы ... Да это надо целое исследование производить. При этом не надо забывать, что Ваше приложение не винда!!! Вам не нужно обеспечивать максимальную производительность. Вам надо обеспечить достаточную производительность. Как правило. Ну если не рассматривать вопросы потребления. Применение автомата в некоторых случаях конечно оправдано и наиболее удобно. А в целом нет универсального способа написания драйвера. Чего бы то ни было. Надо исходить из поставленной задачи. Кидайте в меня палками, на SPI я применяю while. Не блокирующий. Кроме того у меня есть один поток на диагностику, где я пытаюсь контролировать в том числе зависание потока, а также анализирую зависание периферии. Там кстати автомат, так как я там всякие мелкие задачи в один поток собираю чтобы не плодить.
|
|
|
|
|
Apr 15 2015, 10:29
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(SasaVitebsk @ Apr 15 2015, 15:59)  Смотрю различные драйвера обработки SPI - просто убивает. Порой визуально видно, что будет менее эффективно чем простой while. При частоте проца 168МГц и работе SPI 22, байт вылетает за 61 такт. Обработчик прерывания на SPI это не 2 строки. Плюс вход/ выход. В чём прелесть? Прелесть в том, что по SPI обычно не по одному байту пересылают, а десятки и сотни за транзакцию. Цитата(SasaVitebsk @ Apr 15 2015, 15:59)  Применение DMA существенно усложняет драйвер. Оценить выигрыш в производительности не представляется возможным. Оценить надёжность такой работы ... Да это надо целое исследование производить. Ошибаетесь. Всего ПЛЮС несколько дополнительных строк на инициализацию, и МИНУС некоторое кол-во строк на цикл опроса состояний/программной пересылки и т.п. В простых случаях по коду одинаково, но несравнимо быстрее с DMA. Цитата(SasaVitebsk @ Apr 15 2015, 15:59)  Кидайте в меня палками, на SPI я применяю while. Не блокирующий. Кроме того у меня есть один поток на диагностику, где я пытаюсь контролировать в том числе зависание потока, а также анализирую зависание периферии. Там кстати автомат, так как я там всякие мелкие задачи в один поток собираю чтобы не плодить. Ваш while убъёт все нижележащие по приоритету задачи. Особенно если там надо не один-два байта переслать. Для многозадачной среды - это зло.
|
|
|
|
|
Apr 15 2015, 17:41
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(jcxz @ Apr 15 2015, 12:07)  Это одна из главных причин из-за которой недавно, при выборе МК для новой железки, мы отказались от STM32F4. Очень убого реализована периферия в нём - ни буферизации (FIFO) ни достаточного числа DMA-каналов для решения проблемы без FIFO. Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще... Вот никогда эти фифо не использовал, муторно с ними, работал с 5 уартами и 2 спи одновременно, по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис. Никаких проблем не испытывал, либо, принимал по прерываниям, либо дма, для больших пакетов. Тут, по моему, искусственно создают бурю в стакане воды...
|
|
|
|
|
Apr 15 2015, 19:06
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(mantech @ Apr 15 2015, 22:41)  Вот никогда эти фифо не использовал, муторно с ними Да нет же, практически то же самое, что и без фифо, только в обработчиках прерываний не по одному байту бросается, а сколько влезло
|
|
|
|
|
Apr 15 2015, 19:08
|
Профессионал
    
Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863

|
Цитата(mantech @ Apr 15 2015, 20:41)  Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще... Достаточно неудачно выбрать 3-4 периферийных блока чтобы стримы ДМА пересеклись. А для ЦОС - да, уже пытаюсь использовать. Цитата(mantech @ Apr 15 2015, 20:41)  по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис. Для ПЛИС 100 МБпс это ничто. Отличный способ сделать совершенно неоптимальное устройство. Можно мне показать такой "коммуникационный процессор"? Чтобы 1-2МБ флеши, 256КБ срамы, корпус 10х10х0.6? Задача ещё и в том чтобы обрабатывать эти потоки на минимальной частоте ядра. Для моей текущей задачи разница в потреблении на частоте 168 и 84 очень существенна. Надеюсь вообще уложиться в 42.
|
|
|
|
|
Apr 16 2015, 02:16
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(mantech @ Apr 15 2015, 23:41)  Че-то не пойму, или все пытаются использовать стм для ЦОС, с несколькими стримами по 100 мегабайт\сек или используют сразу всю периферию, что каналов дма нехватает или что еще... Вот никогда эти фифо не использовал, муторно с ними, работал с 5 уартами и 2 спи одновременно, по 100мег не передавал, конечно, ибо для таких задач существуют коммуникационные процы или плис. Не для ЦОС (хотя и она там возможно в каком-то количестве будет чуть позже), но в устройстве нужно 5-6 UART (одновременно работающих и при этом желательно - не перегружающих систему прерываниями в десятки кГц) + 2 одновременно работающих SPI (20-40МГц). Это как минимум то, что в STM32 придётся делать с DMA. В старых устройствах на LPC17x примерно то же самое работает занимая всего 4 DMA-канала (2 SPI), а UART-ы без DMA нормально работают, так как имеют FIFO. Да и SPI-каналы имеют FIFO, так что, как я понимаю, меньше занимают шину блочными пересылками. А в новом устройстве планируется более интенсивный поток по SPI-каналам (к тому-же - реалтаймовый). По этой причине в основном и отказались от STM32. Как тут уже написали - работать с FIFO - то же самое что и без, практически никакой разницы, только частота обслуживания может быть в 16 раз меньше.
|
|
|
|
|
Apr 16 2015, 04:59
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(jcxz @ Apr 16 2015, 05:16)  Как тут уже написали - работать с FIFO - то же самое что и без, практически никакой разницы, только частота обслуживания может быть в 16 раз меньше. Это только в "тепличных" условиях. В моем случае была поддержка протоколов с пакетами разной длины от 6 до 1000 байт, причем длина указывается в первых байтах, без таймаутов, там же и ИД-пакета, которые нужно парсить "на лету", тут все фифы только вредят, и работа уартов на 115200 не сильно замедляет систему, если конечно, не нагружать прерывания чем-то еще, кроме приема...
|
|
|
|
|
Apr 16 2015, 05:05
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(jcxz @ Apr 15 2015, 13:29)  Прелесть в том, что по SPI обычно не по одному байту пересылают, а десятки и сотни за транзакцию. У меня по SPI 2 устройства: at45db и АЦП. 1. Во втором случае надо передавать 2 байта и получать 4. 2. В случае работы с флэшкой то же не всё шикарно. Если не выравнивать флэшку на границу страницы, то надо выполнять кучу работы. Грузить страницу, заполнять, записывать. Для всего этого требуется разные команды. У меня идёт в основном запись архивов и ошибок. Как правило требуется забота с малыми объёмами данных. Я прикидывал, вариант драйвера с DMA. Для меня это очень значительное усложнение. Плюс поясните мне пожалуйста. Вот я записываю информацию во флэшку. Потом мне надо ждать готовности флэшки. Как это обойти с помощью DMA?
|
|
|
|
|
Apr 16 2015, 07:02
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(mantech @ Apr 16 2015, 10:59)  Это только в "тепличных" условиях. В моем случае была поддержка протоколов с пакетами разной длины от 6 до 1000 байт, причем длина указывается в первых байтах, без таймаутов, там же и ИД-пакета, которые нужно парсить "на лету", тут все фифы только вредят, и работа уартов на 115200 не сильно замедляет систему, если конечно, не нагружать прерывания чем-то еще, кроме приема... Ну да... 11520*6UART*2(TX/RX) итого частота прерываний ==138240Гц, т.е. - прерывания с периодом 7.2мкс конечно не нагружают никак систему  Про случай когда надо работать всего с одним UART-ом - тут нет вопросов. А ведь бывают ещё и бОльшие скорости по UART. У нас тоже по всем UART-каналам идёт обмен по протоколам с размером кадров переменной длины. FIFO не мешает этому никак. Цитата(SasaVitebsk @ Apr 16 2015, 11:05)  Плюс поясните мне пожалуйста. Вот я записываю информацию во флэшку. Потом мне надо ждать готовности флэшки. Как это обойти с помощью DMA? Когда нужно всего пару байт - никто не мешает использовать обмен по прерываниям: записать в FIFO сразу все 1...8 слов, а потом получить 1..N прерываний и вычитать. Можно комбинировать (я так делаю при малых размерах транзакции по SPI, полностью влезающей в размер FIFO): настраиваю DMA только на приёмный канал, записываю в TX.FIFO сразу все байты (программно), а потом по окончании приёма всего пакета получаю ОДНО прерывание завершения DMA (без ожидания таймаута по завершению). Готовность AT45DB никак не надо обходить. Считывать регистр состояния согласно документации. Хоть программно, хоть с DMA. Никто не мешает смешивать работу через DMA с программным обменом, хоть одновременно, хоть поочередно. В зависимости от SCLK и её соотношения с частотой CPU, можно хоть программно записать в SPI необходимую команду чтения статуса и ждать поллингом завершения приёма (допустимо при большой SCLK, когда такое ожидание приёма занимает мало тактов и выигрыш от освобождения процессора на время передачи невелик или нету его), хоть записать программно, настроив DMA на приём ответа и генерацию прерывания по завершению (если SCLK много меньше частоты CPU и если ждать поллингом, то надолго займёшь CPU впустую). На МК без FIFO всё гораздо хуже, так как нельзя записать целиком посылку в FIFO, настроив только RX.DMA. Мы много используем AT45DB. Передача данных в драйверах идёт через DMA, опрос состояния - как я описал (у нас SCLK=25...30МГц). Под рукой сейчас нет исходника с AT45DB, но вот подобная операция с nRF24L01+ (чтение регистра nRF24L01+ - короткая SPI-транзакция): CODE static void ActSSP(int cmd, int len, int stepNew) { Pclr(PIN_NRF_CS); //CS=low isrStep = stepNew; volatile HwRegsSSP *ssp = &concatAB(SSP, nSSP_nrf); HwRegsDMA::T_CH volatile *ch = &DMA.CH[DMA_CH_nrf_RX]; //DMA-канал DMA_CH_nrf_RX статически привязан к данному SPI (nSSP_nrf), так что адрес источника (ch->SRC) и ch->LLI устанавливаются в инит-коде и каждый раз их писать не надо. //Всё программирование DMA для запуска транзакции занимает 3 строчки кода ниже, настройка регистров: ch->DST, ch->CTL и старт RX.DMA: ch->CFG. ch->DST = &sh.regIO.status; ch->CTL = len + sizeof(sh.regIO.status) | 1 << 12 | B27 | B31; ch->CFG = B0 | (DMA_REQ_nrf_RX >> 4) << 1 | 2 << 11 | B14 | B15; ssp->CR[1] = B1; //включаем SPI-канал __DMB(); ssp->DR = cmd; //старт передачи (и приёма) } static uint RegRead(REG reg) { ActSSP((int)reg + CMD_R_REGISTER, 1, IS_GAP); concatAB(SSP, nSSP_nrf).DR = 0; //запись хвоста (для приёма значения регистра) NrfCtxSw(); //переключение контекста в фоновую задачу с ожиданием завершающего DMA-IRQ, который делает CS=high return sh.regIO.val[0]; } Код #define concatAB_(a, b) a##b #define concatAB(a, b) concatAB_(a, b) Это код для LPC17xx.
|
|
|
|
|
Apr 16 2015, 07:26
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата которые нужно парсить "на лету", тут все фифы только вредят, Это не верно! Они вредят только в одном случае, при неожиданном разрыве обмена их надо очищать от старых пакетов... И в LPC для уарта они сделали очистку, а для SSP нет, приходиться 8 слов читать чтобы точно передатчик был пусть, в случае слейва это ложиться на внешнее устройство... В остальном они только помогают, UART с FIFO неотличим от UART без фифо, кроме одного момента, на приеме если из UART без фифо не успеть забрать символ, он потеряется, а тут он сохраниться, на передаче без фифо вам приходиться ждать когда уйдет прошлый символ прежде чем сунуть следующий, а с фифо можно сразу запихать несколько. FIFO - благо
|
|
|
|
|
Apr 16 2015, 09:23
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(jcxz @ Apr 16 2015, 10:02)  Готовность AT45DB никак не надо обходить. Считывать регистр состояния согласно документации. Хоть программно, хоть с DMA. Подскажите а в чём преимущество, если я готовность буду через DMA получать? Просто мозг закипает. Кто-нибудь приведёт расчёт доказывающий эффективность такой работы? Для меня совершенно очевидна потеря производительности процессора в данном случае. Плюс явное усложнение читаемости программы. Плюс существенное замедление процесса записи флэшки. По-моему необходимо рассчитывать производительность системы в целом. Не всегда имеет смысл передавать управление другой задаче. Учитывая, что время переключения с задачи на задачу фиксированное и зависит от выбранной ОС и особенностей процессора, чем меньше будет тик ОСи тем больше потери будут на обслуживание работы ОСи. Но тем быстрее будет реакция системы. Поэтому необходим какой-то компромисс. Но в любом случае что вызов прерывания, что передача управления другой задаче это многие десятки тактов. Если анализ занимает меньшее время, или сопоставим, нет смысла этим заниматься.
|
|
|
|
|
Apr 16 2015, 16:42
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(Golikov A. @ Apr 16 2015, 10:26)  Это не верно! Они вредят только в одном случае, при неожиданном разрыве обмена их надо очищать от старых пакетов... И в LPC для уарта они сделали очистку, а для SSP нет, приходиться 8 слов читать чтобы точно передатчик был пусть, в случае слейва это ложиться на внешнее устройство... Тогда объясните алгоритм приема пакета с фифо, где 1й байт ИД, который нужно фильтровать, затем адрес, то-же самое, и длина, по которой определяется буфер, а в конце еще и КС?? Причем длина, как правило, не кратна фифо. Таймауты использовать нельзя! Цитата(SasaVitebsk @ Apr 16 2015, 12:23)  Подскажите а в чём преимущество, если я готовность буду через DMA получать? Просто мозг закипает. По своей памяти, с флешкой работал странично, т.е. запихиваю 264 байта, через дма, затем жду отмены бизи, потом опять... Если флешка побайтная - то дма не нужен, только для чтения и блоками. Цитата(jcxz @ Apr 16 2015, 10:02)  Ну да... 11520*6UART*2(TX/RX) итого частота прерываний ==138240Гц, т.е. - прерывания с периодом 7.2мкс конечно не нагружают никак систему Это крайний случай, когда все урты работают в непрерывном потоке, для таких целей используют потоковые коммуникационные процессоры, со встроенной аппаратной распарсировкой пакетов и дма в "автомате". И 130кгц прерываний, для векторного nvic - это немного. Тут все зависит от "кривости" обработчика
Сообщение отредактировал mantech - Apr 16 2015, 16:43
|
|
|
|
|
Apr 16 2015, 17:06
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Тогда объясните алгоритм приема пакета с фифо, где 1й байт ИД, который нужно фильтровать, затем адрес, то-же самое, и длина, по которой определяется буфер, а в конце еще и КС?? Причем длина, как правило, не кратна фифо. Таймауты использовать нельзя! такой же как и без FIFO. Только разница вот в чем. На 115200 время передачи 1 символа ~87 мкСек, а 16 символов уже 1.3 мСек. То есть если у вас нет фифо, то вы нигде не можете висеть дольше 87 мкСек, потому что иначе уже полученный символ затрется следующим, а если фифо есть, то у вас уже 1.3 миллисекунда есть в запасе до того как начнут гибнуть пришедшие символы. Можно сразу сделать опрос по таймеру с 1 мСек интервалами, и ничего гарантированно не потеряется а нагрузка в 16 раз меньше чем по прерыванием на каждый символ. FIFO ничего не меняет в логике, кроме того что создает запас на всякие непредвиденные случаи.
|
|
|
|
|
Apr 16 2015, 18:31
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(Golikov A. @ Apr 16 2015, 20:06)  FIFO ничего не меняет в логике, кроме того что создает запас на всякие непредвиденные случаи. Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится. Цитата(Golikov A. @ Apr 16 2015, 20:06)  Можно сразу сделать опрос по таймеру с 1 мСек интервалами, Еще плюс таймер задействовать под каждый уарт... Таймера всегда нужны для более важных задач. Плюс те-же доп. прерывания, зачем?? ЗЫ. Лично мое мнение - фифо использовать хоть как-то удобно только под небольшие пакеты кратной длины, остальное либо прерывания, либо дма.
Сообщение отредактировал mantech - Apr 16 2015, 18:33
|
|
|
|
|
Apr 16 2015, 18:48
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(mantech @ Apr 16 2015, 23:31)  Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится. Таймаут в 3-4 символа -- это слишком много? Что это за устройство у вас такое?
|
|
|
|
|
Apr 17 2015, 02:27
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(SasaVitebsk @ Apr 16 2015, 15:23)  Подскажите а в чём преимущество, если я готовность буду через DMA получать? ... Учитывая, что время переключения с задачи на задачу фиксированное и зависит от выбранной ОС и особенностей процессора, чем меньше будет тик ОСи тем больше потери будут на обслуживание работы ОСи. Но тем быстрее будет реакция системы. Поэтому необходим какой-то компромисс. Но в любом случае что вызов прерывания, что передача управления другой задаче это многие десятки тактов. Если анализ занимает меньшее время, или сопоставим, нет смысла этим заниматься. Вы мой пост вообще читали или сразу отвечать начали?  Я вообще-то там и написал, что в зависимости от соотношения частот CPU и SCLK SPI (сколько тактов CPU займёт SPI-транзакция) и от размера транзакции и нужно определять, что эффективнее - через DMA, или по прерываниям или вообще поллингом (если SCLK - велика, а транзакция == 1-2 байта). Кстати, если речь зашла о AT45DB, то насколько помню там есть возможность быстрого чтения статуса: при активном сигнале CS и отсутствии обмена по SPI, она на линии MISO держит статус занятости. И достаточно просто прочитать состояние пина. Хотя - может путаю с другой ИС? Уже не помню, давно работал с ней.... Цитата(mantech @ Apr 17 2015, 00:31)  Хорошо, объясню подругому... Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, а придет оно только, когда приму еще 9 байт, или таймаут, но я должен сразу ответить устройству, что принял от него пакет, а я отвечу только через мсек, а устройство будет "думать", что пакет проглотился и начнет слать новый - не годится. Что за протокол такой кривой, что 3-4 символа задержка для него обрушивает обмен? На помойку его!  Если таймаут ответа такой короткий, то получается и ответ надо формировать в ISR, а перед этим значит надо и распарсить принятый кадр (на который отвечаем), а значит и парсер входящих кадров (и собственно вся обработка протокола) должен быть в ISR. Вот собственно Вы сами и ответили на свой-же вопрос про 130кГц прерываний Так построенная работа (обработка протокола в ISR) да ещё для нескольких каналов параллельно и завалит всю вашу систему  Пока Вы будете формировать ответ с таймаутом 3-4 символа в ISR, в это время по другому каналу (работающему без FIFO) произойдёт потеря байтов. Только не надо выдумывать следующий умозрительный случай, с протоколом работающим на низкой бодовой скорости и короткими таймаутами на ответ в 1-2 символа  Цитата(mantech @ Apr 17 2015, 00:31)  ЗЫ. Лично мое мнение - фифо использовать хоть как-то удобно только под небольшие пакеты кратной длины, остальное либо прерывания, либо дма. Главный плюс FIFO: кратное снижение необходимой частоты обслуживания хоть процессором (снижение частоты прерываний) хоть DMA (пакетные пересылки по шине, меньше её занятость). Цитата(mantech @ Apr 16 2015, 22:42)  И 130кгц прерываний, для векторного nvic - это немного. Тут все зависит от "кривости" обработчика  Немного, когда CPU нечем больше заниматься...
|
|
|
|
|
Apr 17 2015, 05:11
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Принимаю пакет, фифо настроен на 16 байт, а пакет - 7, т.е. прерывания на прием я не дождусь, А... дело в том что фифо всегда 16 символов, оно не настраиваемо. А прерывание можно настроить на 1 символ, половину фифо, все фифо. В приведенном примере настраиваем прерывание на 1 символ, ставим ему не высокий приоритет и все. Дальше все работает так же как и ваш алгоритм, за одним исключением в прерывании читаем на 1 символ, а все что пришли. И мы никогда не имеем ситуации потренных символов обмена, потому что даже если мы не успели за время прерывания попасть в обработчик (например обсулуживали со всеми ответами соседний уарт), то символ сохраниться в фифо. С ответом опять же лучше. Получили, обработали, надо что-то короткое ответить. Не пихаем символ и ждем когда он уйдет чтобы пихнуть следующий, а просто набиваем символы в фифо и уходим.... Для SPI slave без фифо или ДМА вообще нельзя, внешнее устройство делает клоки и вам надо успевать пихать данные, тут выходное фифо вам дает хоть какую-то свободу а без него, только ДМА иначе тупо долбить флаг что ушел очередной байт и мигом пихать новый, и не моги ни на что отвлекаться...
|
|
|
|
|
Apr 17 2015, 05:17
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(jcxz @ Apr 17 2015, 05:27)  Вот собственно Вы сами и ответили на свой-же вопрос про 130кГц прерываний Так построенная работа (обработка протокола в ISR) да ещё для нескольких каналов параллельно и завалит всю вашу систему Не буду впадать в тупой спор, просто скажу, что кроме уартов на интах, работает файловая система, сетевой стек, парсер биткода виртуальной задачи, работа с кучей периферии, включая несколько каналов 1wire(кто в теме, тот знает, как этот протокол чувствителен к задержкам)и еще много чего... И самое главное - все работает и "не жужжит". Зависнуть все может только из-за кривости самого программиста. Цитата(Golikov A. @ Apr 17 2015, 08:11)  Потом настраиваем прерывание на 1 символ, ставим ему не высокий приоритет и все.лекаться... Дак какой тогда выигрыш-то, кроме дополнительных настроек? Я же говорю, что выигрыш есть, если в протоколе байты передаются кратными пакетами, на которые настроен триггер фифо. Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика?? На частоте 160 МГц?? И за это время что можно потерять?? Ничего не терялось никогда.
|
|
|
|
|
Apr 17 2015, 05:37
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(Golikov A. @ Apr 17 2015, 10:11)  А... дело в том что фифо всегда 16 символов, оно не настраиваемо. А прерывание можно настроить на 1 символ, половину фифо, все фифо. Не особо понимаю, к чему это (просто конкретный пример?), но на всякий случай замечу, что на некоторых МК размер фифо настраивается, а ещё фифо умеют генерить прерывание таймаута. Наверное я кривовато выразился про настройку размера, да.
Сообщение отредактировал den_po - Apr 17 2015, 05:41
|
|
|
|
|
Apr 17 2015, 05:57
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Если фифо железное, то глубина фифо определена жестко, вопрос в том на какой наполненности мы узнаем что там что-то есть. Если только можно увеличить глубину одного фифо за счет другого... но это экзотика какая-то ИМХО. Цитата И самое главное - все работает и "не жужжит" Ну можно только вам позавидовать. Я бы переживал за систему у которой практически все на прерываниях висит... Цитата Дак какой тогда выигрыш-то, кроме дополнительных настроек? Доп настроек на самом деле нет, но не важно. Выигрыш в том что повышается надежность и снижается критичность скорости обработки прерываний. Вплоть до того что если общий цикл короткий, то можно вообще без прерываний, полингом из основного цикла проверять наличие данных. На вход и выход в прерывание есть накладные расходы, летать на каждый символ всяко будет хуже чем вообще не летать в случае полинга или летать 1 раз с таймером на длительный интервал, в котором можно разом все уарты обработать. Цитата Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика?? А обработка общего буфера где? А как же про ответ за время 2-3 символов?
|
|
|
|
|
Apr 17 2015, 07:01
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(mantech @ Apr 17 2015, 11:17)  Дак какой тогда выигрыш-то, кроме дополнительных настроек? Я же говорю, что выигрыш есть, если в протоколе байты передаются кратными пакетами, на которые настроен триггер фифо. Ну сколько времени потребуется, если в инте проверить пару байт и записать в память с инкрементом счетчика?? На частоте 160 МГц?? И за это время что можно потерять?? Ничего не терялось никогда. Какие пару байт? Передёргиваете. Вы писали про размер кадра немного меньше размера FIFO. Его проверить надо (валидность всех полей, CRC, etc), прогнать полученный кадр по всем веткам протокола обмена надо (а он может быть многоуровневый) и только после этого можно будет формировать ответ (который тоже нужно сформировать (CRC и т.п.)). А представьте теперь, что как раз в это время когда Вы это всё будете делать, по другому UART пришло ещё пару байт. А если ещё в этот момент и по 3-му и по 4-му UARTам ...? Вероятность всё меньше и меньше, но это только говорит о том, что такие ситуации будут происходить редко, и будет Ваша система работать-работать, но иногда глючить (терять байты, нарушаться связь при идеальной линии и т.п.). И вот не надо рассказывать про 160МГц, здесь вроде не маркетологи сидят, а кое-кто даже даташиты на МК почитывает  У Вас ПО из ОЗУ работает? Или всё-таки из флешь? А скорость флешь с ростом частоты CPU не повышается, как была около 20МГц, так и осталась даже на STM32F4. Так что - работало-работало Ваше ПО в фоне, горя не знало, заполнило кеш строками из фоновой задачи, тут вдруг пришло прерывание от UART и полезло оно вытаскивать команды из флешь, медленно и печально на 20МГц-ах... А ему надо успеть за 2-3 символа кучу работы обмолотить. Опа... Хоть техасцы в Tiva сделали шину к флешь в 2 раза пошире - там быстрее должно вытаскивать команды из флешь....
|
|
|
|
|
Apr 17 2015, 08:50
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(jcxz @ Apr 17 2015, 10:01)  Какие пару байт? Передёргиваете. Вы писали про размер кадра немного меньше размера FIFO. Его проверить надо (валидность всех полей, CRC, etc), прогнать полученный кадр по всем веткам протокола обмена надо (а он может быть многоуровневый) и только после этого можно будет формировать ответ (который тоже нужно сформировать (CRC и т.п.)). CRC считается по таблице - это недолго, определить ИД и длину еще быстрее, и флеш не такой уж медленный, как кажется, во первых 64 или 128 битный доступ, плюс конвеер, скорость почти не ограничивает, если не делать умопомрачительных ветвлений. И протокол не настолько "тупой", много чего делается до начала передачи (ответы подтверждения, запроса идентификации вновь подключенных устройств и т.д.)
|
|
|
|
|
Apr 17 2015, 09:42
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(mantech @ Apr 17 2015, 14:50)  CRC считается по таблице - это недолго, определить ИД и длину еще быстрее, и флеш не такой уж медленный, как кажется, во первых 64 или 128 битный доступ, плюс конвеер, скорость почти не ограничивает, если не делать умопомрачительных ветвлений. CRC - это для примера. Может быть, что угодно для проверки валидности кадра. 64-битный доступ к флешь увеличивает скорость флешь всего в 2 раза (даже на линейном коде без ветвлений в случае последовательности 4-байтовых инструкций) с 20 до 40МГц (эквивалентных). Для 160МГц без тормозов на линейном 4-байтовом коде, нужна шина 256бит к флешь-памяти. Как сделано в Tiva. PS: Впрочем - тред уже совсем ушёл в сторону. Вас не переубедить похоже, да и нафик
|
|
|
|
|
Apr 17 2015, 17:17
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(jcxz @ Apr 17 2015, 12:42)  64-битный доступ к флешь увеличивает скорость флешь всего в 2 раза (даже на линейном коде без ветвлений в случае последовательности 4-байтовых инструкций) с 20 до 40МГц (эквивалентных). PS: Впрочем - тред уже совсем ушёл в сторону. Вас не переубедить похоже, да и нафик  Для справки, в стм флеш шина 128бит и частота 30МГц. Подружитесь с математикой и посчитайте, сколько времени выполняется одна инструкция при этих частотах, и сопоставте со временем между приемом символов... ЗЫ Для обработки моего "неудачного" протокола требуется от 25 до 40 машинных инструкций, вот и прикинте, если интересно, а переубеждать меня не надо, я не зеленый студент, и проектов дофига сделал, причем все работают как надо
Сообщение отредактировал mantech - Apr 17 2015, 17:17
|
|
|
|
|
Apr 23 2015, 09:47
|
Знающий
   
Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250

|
Если кому интересно, можно глянуть на систему управления спектрографом. Я ее с использованием opencm3 делал. Вполне удобная библиотека. Правда, часть вещей все равно лучше напрямую регистрами делать...
|
|
|
|
|
Oct 6 2015, 04:10
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
А позвольте некропостнуть и вступить в полемику по поводу высокоуровневых либ а-ля Cube. Я сейчас много об этом думаю, а тут на тему наткнулся, прочитал 5 страниц. Насколько я понял, большинство не переносит Cube по причине сложности (читай - простоты использования и универсальности). Ее верхний уровень куда выше верхнего уровня той же stdlib и уж подавно opencm3, поэтому напрямую их сравнивать как бы не совсем корректно. Я не претендую на правоту, скорее хочу взвесить все за и против.
Вот, к примеру, надо мне передать 100 байт по UART. Раньше пользовался stdlib, в прерывании вызывал функцию, которая хранит пойнтер на массив, индексирует его и отдает очередной байт. Позже появилось желание не писать это в каждом проекте, а создать либу верхнего уровня для UART. Потом был SPI и так далее. В cube сделано то же самое, только универсально (и я хочу верить, ее проверяли, во всяком случае, версии новые выходят): есть готовый обработчик прерываний, досылающий массив, и вызывающий калбек поле полной отправки. Да, код из-за этого большой. Конечно, если я буду делать максимально маленькое или максимально быстрое приложение, ни о каком cube речи не идет. Возможно, иногда даже поллингом получится передать быстрее, чем через прерывания или DMA. Объясните, чем он так плох? И чем хорошо использовать opencm3, который не намного удобней работы с регистрами для человека, хорошо знакомого с камнем?
|
|
|
|
|
Oct 6 2015, 05:46
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(Эдди @ Oct 6 2015, 11:43)  Вкратце: CUBE — признак идиота. Это как ардуйня. Только даже хуже. А Вы попробуйте не вкратце, если не сложно. Где граница между признаком идиота и библиотекой? Графические библиотеки тоже под запретом? А готовые ОС? Если что, я не о программе Cube, а о библиотеке, что она использует. STM позиционирует ее как замену stdperiph_lib.
Сообщение отредактировал drozel - Oct 6 2015, 05:47
|
|
|
|
|
Oct 6 2015, 06:27
|
Гуру
     
Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143

|
Цитата(drozel @ Oct 6 2015, 07:10)  Объясните, чем он так плох? И чем хорошо использовать opencm3, который не намного удобней работы с регистрами для человека, хорошо знакомого с камнем? Да ни чем не плох, просто всегда удивляюсь, когда кто-нибудь решает, что можно ничего не зная о камне, как правило, не читая доков, просто взять какой-нить визард, типа куба и пр... и "написать" на нем прогу любой сложности, за день или меньше... Так-то фиг с ним, пускай пишет, только потом она, почему-то не работает!!! Вот почему, блин?! По мне, можно писать на чем угодно, сам писал с использованием либ от СТ, но при этом хотя-бы чуток разбираться в камне и уметь читать код этих либ, тогда и понимание, "почему...", придет само собой. Цитата(Эдди @ Oct 6 2015, 08:43)  Вкратце: CUBE — признак идиота. Это как ардуйня. Только даже хуже. Скажем так, если "программист" считает, что на кубе можно все "написать" от и до, то да - признак идиота, а если его использовать, как вспомогательный инструмент к голове - то полезная вещь. ЗЫ. А на счет ардуины - не стоит так категорично, иногда нужно сделать просто и быстро - почему и нет?? Сам себе сделал что-то подобное на МХ6 с графикой, типа виндовой - для есложных приложений с гуем - самое оно
Сообщение отредактировал mantech - Oct 6 2015, 06:31
|
|
|
|
|
Oct 6 2015, 06:28
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Вот вам на пальцах:
Ну берем SPI, настраиваем по кубовски на ДМА слейв прием, все там подключаем, запускаем, вроде как работает.
Идем дальше, хотим сделать так, буфер 1024 байта, заполняется по ДМА, время от времени проверяем его и если в нем уже есть полное сообщение (определяется по размеру сообщения в заголовке и по тому сколько байт приняло ДМА), забираем сообщение и перенастриваем ДМА на прием нового сообщения. Казалось бы все функции есть, и тут на тебе!
В процедуре завершения ДМА обмена вставлен таймаут аж на кучу миллисекунд. Ну е мое! И более того он еще забит одной единой коснтантой, и от него едут все остальные таймауты, И таймер нужен кубовский, который не просто считает а вызывает еще доп функции тормозя весь процесс... И начинаешь это все преписывать, допиливая библиотечные файлы, и в итоге для того чтобы сделать что-то с нормальной производительностью надо все руками переписать, сломав всю предложенную логику куба. И что от него остается?
Ну дальше мы добавляем кучу ошибок ввиде переменных у которых забили valotile и следовательно при оптимизации отличной от none половина задержек виснет насмерть. Дальше добавляем задержки через while которые убивают RTOS если вдруг до нее дойдет.
К этому так же надо добавить наличие просто ошибок, коих немало в кубе, то есть не оглядываясь его использовать во взрослом проекте нельзя. А если мне надо его весь прочитать и перелопатить, то почему бы мне не сделать свою нормальную библиотеку? Которая за пару тройку боевых проектов будет иметь все необходимое под проц, но написанное по моей архитектуре и в моем стиле, и с моим контролем ошибок?
Вот и получается что если какая-то игрушка то куб очень ничего для домохозяек пойдет. А если что-то взрослое да за деньги, то труда с кубом в разы больше, он не дает никакого бонуса, и потому вреден... И в целом аналогия верная, это как ардуйня...
Все естественно ИМХО.
|
|
|
|
|
Oct 6 2015, 07:11
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Мне кажется пример для UART вы неудачный выбрали. )) Дело в том, что написать универсальный обработчик UART, на мой взгляд, нецелесообразно. С одной стороны сам USART позволяет слишком многое, а с другой стороны законченный драйвер должен обеспечивать хотя бы канальный уровень (ведущий/ведомый, контрольная сумма, контроль приёма сообщений) и сетевой (определение маршрута и логическая адресация). А это для разных протоколов существенно отличается. То есть универсальный или не получится или будет слишком громоздкий, избыточный. Кроме того значительно чаще интересен не "универсальный драйвер для одного типа МК (например STM32F4)", а драйвер для целого семейства. И здесь начинают проявляться особенности периферии. Посмотрите мануалы для F0/F1/F3/F4 контроллеров STM. Вроде похожи, но ... Кое где предусмотрена обработка полудуплекса, а где-то нет. Где то есть аппаратная обработка логичесской адресации. Разная обработка LIN протоколов. Ещё всякие особенности ... Причём сама работа с железом у вас составит максимум 1% от библиотеки. Думаю меньше на самом деле. И она проста до безобразия. Вам просто надо почитать описание самих регистров. Вот и получается ... С одной стороны - прочитать описание регистров контроллера и написать универсальную (по возможности) библиотеку своего протокола. С другой стороны - прочитать описание библиотеки КУБ или другой, со всеми взаимоувязками (так как там одна написана через другую) и, опять же, написать библиотеку своего протокола. ... Так ответьте мне. В чём выигрыш? Я вот просто не пойму. У меня создаётся впечатление, что библиотеками пользуются те, кто сами вообще ничего не пишут. А берут готовый пример с просторов инета, и прикручивают что-то своё с косяками. ... Некоторыми библиотеками я пользуюсь сам. Например Ethernet. Но думаю, там то же самое. Просто недостаток моих знаний и времени. Я уверен, что если переписать это всё под себя то работать будет комфортней намного.
|
|
|
|
|
Oct 6 2015, 07:17
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(mantech @ Oct 6 2015, 09:34)  Но ИМХО, писать с нуля, например усб стеки - ну это для отпетых "гурманов"  Вот-вот. Мне нравится, когда отдельные куски можно выдрать без особых усилий и вставить в свою программу. Конечно, если при выдирании выясняется, что там всё со всем связано тысячью нитей, то становится грустно... Цитата(SasaVitebsk @ Oct 6 2015, 10:11)  У меня создаётся впечатление, что библиотеками пользуются те, кто сами вообще ничего не пишут. А берут готовый пример с просторов инета, и прикручивают что-то своё с косяками. +1. Запустить UART - это вообще тривиально. А режимы там разные могут быть, как верное подмечено, то есть рассчитывать на то, что чудо-библиотека всё сделает сама, не стоит. Если UART пугает, то, может, и подходить к МК не нужно? Цитата(SasaVitebsk @ Oct 6 2015, 10:11)  Например Ethernet. Но думаю, там то же самое. Просто недостаток моих знаний и времени. Я уверен, что если переписать это всё под себя то работать будет комфортней намного. Я думаю, самому делать TCP - неблагодарное занятие. Читать все эти RFC (а их много), отлаживать алгоритмы в реальных условиях (а эти условия могут быть сильно разные) - куча работы. Если кто-то это уже проделал, глупо повторять этот же путь снова.
|
|
|
|
|
Oct 6 2015, 08:18
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(scifi @ Oct 6 2015, 13:17)  +1. Запустить UART - это вообще тривиально. Ну тривиально, тривиально. Также, как и SPI. Может я неправильно устроен, но, когда я таскаю из проекта в проект вывод printf в UART/USB, мне хочется запихать это уже в законченный .c + .h и подключать, как модуль. А ведь периферии много. И UARTов может быть много, а это, как правильно подметили, 1% от серьезной программы. Код неплохо было бы иметь читаемый, а не CR |= 0x01b1;
Сообщение отредактировал drozel - Oct 6 2015, 08:21
|
|
|
|
|
Oct 6 2015, 10:58
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Дак так и получается, если делать не один проект, то все-равно дорабатываешь либы под себя и убираешь ошибки. Но ИМХО, писать с нуля, например усб стеки - ну это для отпетых "гурманов" не путайте теплое с мягким.... Одно дело написать один свой, нужный именно тебе функционал и проверить его. Другое дело вычистить ошибки в огромном универсальном проекте выполняющим все возможные функционалы. При этом он (куб) реально очень перепутанный и на много что завязан, так что фиг его просто сократишь до нужного.
|
|
|
|
|
Oct 7 2015, 03:28
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(_Pasha @ Oct 6 2015, 18:01)  dma - как бы тоже, чтобы канал и стрим выбирало само исходя из указанного адреса периферии. в принципе - небольшая табличка во флеше решает проблемы с необходимостью лазать по даташиту. Ну так это и есть библиотека более высокого уровня. Что-то вроде того и реализовано в Cube, но, говорят много ошибок и недоработок.
|
|
|
|
|
Oct 7 2015, 04:45
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(drozel @ Oct 7 2015, 06:28)  Ну так это и есть библиотека более высокого уровня. Что-то вроде того и реализовано в Cube, но, говорят много ошибок и недоработок. Из куба один раз попробовал запустить что-то с usb, быстро перехотелось. Высокого уровня... вот например - годами одна и та же функция настройки Код int uart_setup( // >0 - configured yet 0-service busy <0 - error char n,// which one baud_t baud, // may be long or int32 char bits, // ['5'..'9'] char parity, // ['E','O','N'] char stops); // ['1','2'] не включает в себя экзотику типа multiprocessor mode или 1.5 стопа но я что-то не припомню когда ими пользовался...
|
|
|
|
|
Oct 8 2015, 09:24
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Люди, помогите с либой. Пытаюсь завести USB CDC с libopencm3 и вот этим примером. Я допускаю, что туплю, библиотека написана с каким то жонглированием указателями, которое мне пока непривычно + пришлось немного портировать на IAR, т.к. либа содержит много директив от GCC. На данный момент USB поднимается, но устройство не опознается, PID и VID комп видит нулевые. Конкретный вопрос: Код usbd_device *usbd_init(const usbd_driver *driver, const struct usb_device_descriptor *dev, const struct usb_config_descriptor *conf, const char **strings, int num_strings, uint8_t *control_buffer, uint16_t control_buffer_size) { usbd_device *usbd_dev;
usbd_dev = driver->init();
usbd_dev->driver = driver; usbd_dev->desc = dev; usbd_dev->config = conf; usbd_dev->strings = strings; usbd_dev->num_strings = num_strings; usbd_dev->ctrl_buf = control_buffer; usbd_dev->ctrl_buf_len = control_buffer_size;
usbd_dev->user_callback_ctr[0][USB_TRANSACTION_SETUP] = _usbd_control_setup; usbd_dev->user_callback_ctr[0][USB_TRANSACTION_OUT] = _usbd_control_out; usbd_dev->user_callback_ctr[0][USB_TRANSACTION_IN] = _usbd_control_in;
int i; for (i = 0; i < MAX_USER_SET_CONFIG_CALLBACK; i++) { usbd_dev->user_callback_set_config[i] = NULL; }
return usbd_dev; } Что при этом возвращает функция? Указатель на локальную переменную (стек)? Ведь переменная локальная, выделена не динамически. Я просто в ступоре. --- UPD все, наладил, проблема была у меня. Тем не менее, прошу ликбеза по си..
Сообщение отредактировал drozel - Oct 8 2015, 10:10
|
|
|
|
|
Oct 8 2015, 10:34
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(drozel @ Oct 8 2015, 12:24)  Что при этом возвращает функция? Указатель на локальную переменную (стек)? Функция возвращает указатель на структуру типа usbd_device. То есть фактически, на адрес в памяти, где находится переменная. Цитата Ведь переменная локальная, выделена не динамически. Я просто в ступоре. Локальная - не есть выделенная динамически. Локальная выделяется на стеке и уничтожается при выходе из процедуры (точнее становится непредсказуемой). Выделена динамически, значит размещена на куче. Она уничтожается только явно процедурой free. В данном случае локально объявляется указатель. Далее запускается driver->init(), что похоже динамически выделяет память и инициализирует структуру. П/п возвращает этот указатель. В чём вопрос?
|
|
|
|
|
Oct 8 2015, 16:41
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(SasaVitebsk @ Oct 8 2015, 16:34)  В чём вопрос? Да, запарился с этой либой, затупил.
|
|
|
|
|
Oct 9 2015, 09:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(drozel @ Oct 9 2015, 04:57)  Да, уже нашел, спасибо. Просто непривычно: вместо того, чтоб сделать ее глобальной делают ее глобальным статиком и передают указатель через череду фукнций. Более правильно, согласен. Ну это такой сиплюсплюс из костылей: "класс" логики работает с "классом" физического драйвера через указатель на последний. Если понимать принципы C++, всё понятно и очевидно. Но работать всё равно неудобно - IDE не "прыгает" при чтении кода к соотв. функции, да и ошибиться при заполнении структуры с указателями куда легче...
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Oct 12 2015, 11:40
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(drozel @ Oct 12 2015, 14:10)  Почти мигрировал с stdlib и cube на сабж. Остался вопрос, нужна помощь. Где файл, прописывающий в память таблицу векторов прерываний? В stdlib был стартап файл на асме, здесь уже перерыл все, в упор не вижу. это содержимое папки dispatch и далее по дефайну. собирайте сразу в статик либу. гемора потом вообще 0.0% правда, я перед этим выдрал из usb отдельно SCSI и компильнул либы без него. потому что msc полно сюрпризов.
|
|
|
|
|
Oct 12 2015, 11:55
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(_Pasha @ Oct 12 2015, 17:40)  это содержимое папки dispatch и далее по дефайну. Там 2 файла: vector_chipset.c и vector_nvic.c Первый инклудит аналогичный файл из папки f4 (в моем случае), который просто включает сопроцессор: Код static void pre_main(void) { /* Enable access to Floating-Point coprocessor. */ SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); } Второй соответственно ищет vector_nvic.c в папке семейства, но его там нет. Зато есть зацепка в папке scripts, скрипт irq2nvic_h, вроде на питоне (судя по строке #!/usr/bin/env python), содержащий, помимо всего прочего,такие строки Код """Generate an nvic.h header from a small JSON file describing the interrupt numbers.
Code generation is chosen here because the resulting C code needs to be very repetetive (definition of the IRQ numbers, function prototypes, weak fallback definition and vector table definition), all being very repetitive. No portable method to achive the same thing with C preprocessor is known to the author. (Neither is any non-portable method, for that matter.)""" Я на питоне не силен, скачал интерпретатор под винду, пытаюсь его как-то запустить. Пока неудачно, но это вопрос скорее в тему по питону.
|
|
|
|
|
Oct 12 2015, 12:14
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(drozel @ Oct 12 2015, 14:55)  Зато есть зацепка в папке scripts, скрипт irq2nvic_h, вроде на питоне (судя по строке #!/usr/bin/env python), содержащий, помимо всего прочего,такие строки Код """Generate an nvic.h header from a small JSON file describing the interrupt numbers.
Code generation is chosen here because the resulting C code needs to be very repetetive (definition of the IRQ numbers, function prototypes, weak fallback definition and vector table definition), all being very repetitive. No portable method to achive the same thing with C preprocessor is known to the author. (Neither is any non-portable method, for that matter.)""" Я на питоне не силен, скачал интерпретатор под винду, пытаюсь его как-то запустить. Пока неудачно, но это вопрос скорее в тему по питону. держите для F4 CODE /* This file is part of the libopencm3 project. * * It was generated by the irq2nvic_h script. * * This part needs to get included in the compilation unit where * blocking_handler gets defined due to the way #pragma works. */
/** @defgroup CM3_nvic_isrpragmas_STM32F4 User interrupt service routines (ISR) defaults for STM32 F4 series @ingroup CM3_nvic_isrpragmas
@{*/
#pragma weak nvic_wwdg_isr = blocking_handler #pragma weak pvd_isr = blocking_handler #pragma weak tamp_stamp_isr = blocking_handler #pragma weak rtc_wkup_isr = blocking_handler #pragma weak flash_isr = blocking_handler #pragma weak rcc_isr = blocking_handler #pragma weak exti0_isr = blocking_handler #pragma weak exti1_isr = blocking_handler #pragma weak exti2_isr = blocking_handler #pragma weak exti3_isr = blocking_handler #pragma weak exti4_isr = blocking_handler #pragma weak dma1_stream0_isr = blocking_handler #pragma weak dma1_stream1_isr = blocking_handler #pragma weak dma1_stream2_isr = blocking_handler #pragma weak dma1_stream3_isr = blocking_handler #pragma weak dma1_stream4_isr = blocking_handler #pragma weak dma1_stream5_isr = blocking_handler #pragma weak dma1_stream6_isr = blocking_handler #pragma weak adc_isr = blocking_handler #pragma weak can1_tx_isr = blocking_handler #pragma weak can1_rx0_isr = blocking_handler #pragma weak can1_rx1_isr = blocking_handler #pragma weak can1_sce_isr = blocking_handler #pragma weak exti9_5_isr = blocking_handler #pragma weak tim1_brk_tim9_isr = blocking_handler #pragma weak tim1_up_tim10_isr = blocking_handler #pragma weak tim1_trg_com_tim11_isr = blocking_handler #pragma weak tim1_cc_isr = blocking_handler #pragma weak tim2_isr = blocking_handler #pragma weak tim3_isr = blocking_handler #pragma weak tim4_isr = blocking_handler #pragma weak i2c1_ev_isr = blocking_handler #pragma weak i2c1_er_isr = blocking_handler #pragma weak i2c2_ev_isr = blocking_handler #pragma weak i2c2_er_isr = blocking_handler #pragma weak spi1_isr = blocking_handler #pragma weak spi2_isr = blocking_handler #pragma weak usart1_isr = blocking_handler #pragma weak usart2_isr = blocking_handler #pragma weak usart3_isr = blocking_handler #pragma weak exti15_10_isr = blocking_handler #pragma weak rtc_alarm_isr = blocking_handler #pragma weak usb_fs_wkup_isr = blocking_handler #pragma weak tim8_brk_tim12_isr = blocking_handler #pragma weak tim8_up_tim13_isr = blocking_handler #pragma weak tim8_trg_com_tim14_isr = blocking_handler #pragma weak tim8_cc_isr = blocking_handler #pragma weak dma1_stream7_isr = blocking_handler #pragma weak fsmc_isr = blocking_handler #pragma weak sdio_isr = blocking_handler #pragma weak tim5_isr = blocking_handler #pragma weak spi3_isr = blocking_handler #pragma weak uart4_isr = blocking_handler #pragma weak uart5_isr = blocking_handler #pragma weak tim6_dac_isr = blocking_handler #pragma weak tim7_isr = blocking_handler #pragma weak dma2_stream0_isr = blocking_handler #pragma weak dma2_stream1_isr = blocking_handler #pragma weak dma2_stream2_isr = blocking_handler #pragma weak dma2_stream3_isr = blocking_handler #pragma weak dma2_stream4_isr = blocking_handler #pragma weak eth_isr = blocking_handler #pragma weak eth_wkup_isr = blocking_handler #pragma weak can2_tx_isr = blocking_handler #pragma weak can2_rx0_isr = blocking_handler #pragma weak can2_rx1_isr = blocking_handler #pragma weak can2_sce_isr = blocking_handler #pragma weak otg_fs_isr = blocking_handler #pragma weak dma2_stream5_isr = blocking_handler #pragma weak dma2_stream6_isr = blocking_handler #pragma weak dma2_stream7_isr = blocking_handler #pragma weak usart6_isr = blocking_handler #pragma weak i2c3_ev_isr = blocking_handler #pragma weak i2c3_er_isr = blocking_handler #pragma weak otg_hs_ep1_out_isr = blocking_handler #pragma weak otg_hs_ep1_in_isr = blocking_handler #pragma weak otg_hs_wkup_isr = blocking_handler #pragma weak otg_hs_isr = blocking_handler #pragma weak dcmi_isr = blocking_handler #pragma weak cryp_isr = blocking_handler #pragma weak hash_rng_isr = blocking_handler #pragma weak fpu_isr = blocking_handler #pragma weak uart7_isr = blocking_handler #pragma weak uart8_isr = blocking_handler #pragma weak spi4_isr = blocking_handler #pragma weak spi5_isr = blocking_handler #pragma weak spi6_isr = blocking_handler #pragma weak sai1_isr = blocking_handler #pragma weak lcd_tft_isr = blocking_handler #pragma weak lcd_tft_err_isr = blocking_handler #pragma weak dma2d_isr = blocking_handler
/**@}*/
/* Initialization template for the interrupt vector table. This definition is * used by the startup code generator (vector.c) to set the initial values for * the interrupt handling routines to the chip family specific _isr weak * symbols. */
#define IRQ_HANDLERS \ [NVIC_NVIC_WWDG_IRQ] = nvic_wwdg_isr, \ [NVIC_PVD_IRQ] = pvd_isr, \ [NVIC_TAMP_STAMP_IRQ] = tamp_stamp_isr, \ [NVIC_RTC_WKUP_IRQ] = rtc_wkup_isr, \ [NVIC_FLASH_IRQ] = flash_isr, \ [NVIC_RCC_IRQ] = rcc_isr, \ [NVIC_EXTI0_IRQ] = exti0_isr, \ [NVIC_EXTI1_IRQ] = exti1_isr, \ [NVIC_EXTI2_IRQ] = exti2_isr, \ [NVIC_EXTI3_IRQ] = exti3_isr, \ [NVIC_EXTI4_IRQ] = exti4_isr, \ [NVIC_DMA1_STREAM0_IRQ] = dma1_stream0_isr, \ [NVIC_DMA1_STREAM1_IRQ] = dma1_stream1_isr, \ [NVIC_DMA1_STREAM2_IRQ] = dma1_stream2_isr, \ [NVIC_DMA1_STREAM3_IRQ] = dma1_stream3_isr, \ [NVIC_DMA1_STREAM4_IRQ] = dma1_stream4_isr, \ [NVIC_DMA1_STREAM5_IRQ] = dma1_stream5_isr, \ [NVIC_DMA1_STREAM6_IRQ] = dma1_stream6_isr, \ [NVIC_ADC_IRQ] = adc_isr, \ [NVIC_CAN1_TX_IRQ] = can1_tx_isr, \ [NVIC_CAN1_RX0_IRQ] = can1_rx0_isr, \ [NVIC_CAN1_RX1_IRQ] = can1_rx1_isr, \ [NVIC_CAN1_SCE_IRQ] = can1_sce_isr, \ [NVIC_EXTI9_5_IRQ] = exti9_5_isr, \ [NVIC_TIM1_BRK_TIM9_IRQ] = tim1_brk_tim9_isr, \ [NVIC_TIM1_UP_TIM10_IRQ] = tim1_up_tim10_isr, \ [NVIC_TIM1_TRG_COM_TIM11_IRQ] = tim1_trg_com_tim11_isr, \ [NVIC_TIM1_CC_IRQ] = tim1_cc_isr, \ [NVIC_TIM2_IRQ] = tim2_isr, \ [NVIC_TIM3_IRQ] = tim3_isr, \ [NVIC_TIM4_IRQ] = tim4_isr, \ [NVIC_I2C1_EV_IRQ] = i2c1_ev_isr, \ [NVIC_I2C1_ER_IRQ] = i2c1_er_isr, \ [NVIC_I2C2_EV_IRQ] = i2c2_ev_isr, \ [NVIC_I2C2_ER_IRQ] = i2c2_er_isr, \ [NVIC_SPI1_IRQ] = spi1_isr, \ [NVIC_SPI2_IRQ] = spi2_isr, \ [NVIC_USART1_IRQ] = usart1_isr, \ [NVIC_USART2_IRQ] = usart2_isr, \ [NVIC_USART3_IRQ] = usart3_isr, \ [NVIC_EXTI15_10_IRQ] = exti15_10_isr, \ [NVIC_RTC_ALARM_IRQ] = rtc_alarm_isr, \ [NVIC_USB_FS_WKUP_IRQ] = usb_fs_wkup_isr, \ [NVIC_TIM8_BRK_TIM12_IRQ] = tim8_brk_tim12_isr, \ [NVIC_TIM8_UP_TIM13_IRQ] = tim8_up_tim13_isr, \ [NVIC_TIM8_TRG_COM_TIM14_IRQ] = tim8_trg_com_tim14_isr, \ [NVIC_TIM8_CC_IRQ] = tim8_cc_isr, \ [NVIC_DMA1_STREAM7_IRQ] = dma1_stream7_isr, \ [NVIC_FSMC_IRQ] = fsmc_isr, \ [NVIC_SDIO_IRQ] = sdio_isr, \ [NVIC_TIM5_IRQ] = tim5_isr, \ [NVIC_SPI3_IRQ] = spi3_isr, \ [NVIC_UART4_IRQ] = uart4_isr, \ [NVIC_UART5_IRQ] = uart5_isr, \ [NVIC_TIM6_DAC_IRQ] = tim6_dac_isr, \ [NVIC_TIM7_IRQ] = tim7_isr, \ [NVIC_DMA2_STREAM0_IRQ] = dma2_stream0_isr, \ [NVIC_DMA2_STREAM1_IRQ] = dma2_stream1_isr, \ [NVIC_DMA2_STREAM2_IRQ] = dma2_stream2_isr, \ [NVIC_DMA2_STREAM3_IRQ] = dma2_stream3_isr, \ [NVIC_DMA2_STREAM4_IRQ] = dma2_stream4_isr, \ [NVIC_ETH_IRQ] = eth_isr, \ [NVIC_ETH_WKUP_IRQ] = eth_wkup_isr, \ [NVIC_CAN2_TX_IRQ] = can2_tx_isr, \ [NVIC_CAN2_RX0_IRQ] = can2_rx0_isr, \ [NVIC_CAN2_RX1_IRQ] = can2_rx1_isr, \ [NVIC_CAN2_SCE_IRQ] = can2_sce_isr, \ [NVIC_OTG_FS_IRQ] = otg_fs_isr, \ [NVIC_DMA2_STREAM5_IRQ] = dma2_stream5_isr, \ [NVIC_DMA2_STREAM6_IRQ] = dma2_stream6_isr, \ [NVIC_DMA2_STREAM7_IRQ] = dma2_stream7_isr, \ [NVIC_USART6_IRQ] = usart6_isr, \ [NVIC_I2C3_EV_IRQ] = i2c3_ev_isr, \ [NVIC_I2C3_ER_IRQ] = i2c3_er_isr, \ [NVIC_OTG_HS_EP1_OUT_IRQ] = otg_hs_ep1_out_isr, \ [NVIC_OTG_HS_EP1_IN_IRQ] = otg_hs_ep1_in_isr, \ [NVIC_OTG_HS_WKUP_IRQ] = otg_hs_wkup_isr, \ [NVIC_OTG_HS_IRQ] = otg_hs_isr, \ [NVIC_DCMI_IRQ] = dcmi_isr, \ [NVIC_CRYP_IRQ] = cryp_isr, \ [NVIC_HASH_RNG_IRQ] = hash_rng_isr, \ [NVIC_FPU_IRQ] = fpu_isr, \ [NVIC_UART7_IRQ] = uart7_isr, \ [NVIC_UART8_IRQ] = uart8_isr, \ [NVIC_SPI4_IRQ] = spi4_isr, \ [NVIC_SPI5_IRQ] = spi5_isr, \ [NVIC_SPI6_IRQ] = spi6_isr, \ [NVIC_SAI1_IRQ] = sai1_isr, \ [NVIC_LCD_TFT_IRQ] = lcd_tft_isr, \ [NVIC_LCD_TFT_ERR_IRQ] = lcd_tft_err_isr, \ [NVIC_DMA2D_IRQ] = dma2d_isr
питон можно портабл взять
|
|
|
|
|
Oct 12 2015, 17:14
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(esaulenka @ Oct 12 2015, 18:43)  Я пользуюсь гибридом - USB'шный стек на libopencm3, а всё остальное - стандарные ST'шные описания регистров (на мой взгляд, они удобнее. А функции работы с периферией? Или все в регистры пишете?
|
|
|
|
|
Oct 13 2015, 03:33
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(_Pasha @ Oct 12 2015, 18:14)  держите для F4 Спасибо. Но это ведь h, а где тот самый vector.c, который должен помещать таблицу в память? Код #elif defined(STM32F4) # include "../stm32/f4/vector_nvic.c" По этому пути его нет и непохоже, что он генерится этим же скриптом. Цитата(Эдди @ Oct 13 2015, 00:14)  Быстрее по даташиту с регистрами разобраться, нежели перелопачивать код opencm3 в поисках нужного функционала! Не согласен я с этим. Я смотрю, людям волю дай, они скажут "быстрее свой МК сделать, чем разбираться с даташитом на этот". Сложность железа растет. Раньше программы для ПК на асме писали, теперь функциями ОС пользуются. Если есть нормальная библиотека, ей надо пользоваться. А изобретение велосипедов и мнение "все дураки, сам сделаю лучше" - чисто славянская черта. Имхо, конечно. Но это не значит. что я не знаю регистры и делаю все вслепую, а когда функция не работает, пугаюсь и плАчу. И вообще, это оффтоп.
Сообщение отредактировал drozel - Oct 13 2015, 03:37
|
|
|
|
|
Oct 13 2015, 04:58
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(drozel @ Oct 13 2015, 06:33)  Спасибо. Но это ведь h, а где тот самый vector.c, который должен помещать таблицу в память? я не пойму две вещи 1. чем Вы пользуетесь, что так упорно не можете найти cm3/vector.c есть understand, eclipse тупо grep, в конце концов... Код grep -r IRQ_HANDLERS * 2. зачем этот закат солнца вручную, если можно вызвать make -n для того мейкфайла и посмотреть что ж там такое вызывается. и поттом смело со списком собирать то же самое, например в кейле
Сообщение отредактировал _Pasha - Oct 13 2015, 04:59
|
|
|
|
|
Oct 13 2015, 07:58
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(_Pasha @ Oct 13 2015, 10:58)  я не пойму две вещи 1. чем Вы пользуетесь, что так упорно не можете найти cm3/vector.c Ну grep мне недоступен (винда), но искил я и эклипсом, и тотал командером. Качал либу отсюда. Если уверены, что я туплю, пожалуйста, ткните носом. vector_chipset.c не считается, там только включение сопроцессора, вызов этой функции тоже должен помещаться стартап-файлом в начало памяти. Цитата(_Pasha @ Oct 13 2015, 10:58)  2. зачем этот закат солнца вручную, если можно вызвать make -n для того мейкфайла и посмотреть что ж там такое вызывается. и поттом смело со списком собирать то же самое, например в кейле Как сказать.. GCC я никогда не пользовался, пользуюсь иаром. Думал, либа нормально поднимется. Если для того, чтобы использовать либу, надо поставить GCC и посмотреть, что делает мейк, то это уже какой-то С другой стороны, повод научиться пользоваться GCC, можно даже либу собрать в статическую...
|
|
|
|
|
Oct 13 2015, 08:26
|
Знающий
   
Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250

|
Цитата(drozel @ Oct 13 2015, 10:58)  Если уверены, что я туплю, пожалуйста, ткните носом. Код ls lib/stm32/f4/vector.c lib/stm32/f4/vector.c Пример makefile для F1 можно у меня в репах на гитхабе/сосфорже/битбакете/гитлабе посмотреть (stm32samples).
|
|
|
|
|
Oct 13 2015, 08:35
|
Частый гость
 
Группа: Свой
Сообщений: 108
Регистрация: 2-02-11
Пользователь №: 62 650

|
Цитата(Эдди @ Oct 13 2015, 14:26)  Код ls lib/stm32/f4/vector.c lib/stm32/f4/vector.c Это у Вас в папке или в репе на гитхабе?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|