Обсуждение схемы от Makar

Разработка впрыска топлива на базе SECU-3. Fuel injection related discussion.

Moderator: STC

Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Обсуждение схемы от Makar

Post by Qwertty »

nikll wrote:Qwertty, там не несколько тактов разницы будет, посущественней.
Вот смотри твой вариант по прерываниям:
1. ДПКВ - вытесняет все, отрабатывает тактов за 300
Не на весь обработчик. Всегда есть критичная по времени часть и не критичная. Между ними можно понизить приоритет. Критичная часть будет тактов 30. Остальное подождет. Ну либо запрета оптимизации при записи например в порт. Пусть даже будет 100-150 тактов для обработки очереди при 2 одновременных событиях.
nikll wrote:
2. таймер очереди - отрабатывает 1000-2000 тактов (на обработку очереди, т.к. очередь в прерывании то соответсвенно volatile и каждая операция размазывается существенно)
Обработка очереди - простейшая операция. Какие 1000 тактов? Увеличить указатель, считать по нему значение загружаемое в таймер и взвести/сбросить максимум два вывода и 1 флаг. Все. И никаких волатайлов тут не надо. Они вообще совсем для другого - для основного цикла работающего с изменяющимися в прерывании переменными. В самом прерывании эффекта от этого квалификатора не будет.
nikll wrote: если прервания очереди сделать приоритетней ДПКВ то это будет плохо т.к. очередь довольно долго относительно ДПКВ отрабатывает (что приведет к неправельному замеру времени между зубьями), если на оборот то получаем погрешность кроме того что в самой очереди еще и время прерывания ДПКВ.
Очередь - самая шустрая операция. :lol: Никаких расчетов, изменение только одной переменной - указателя. 50 тактов максимум вместе со входом и выходом. Это около 2 мкс при такте 24МГц.
nikll wrote: Вариант с индивидуальными прерываниями:
1. ДПКВ - вытесняет все кроме форсунок и катушек
2. пачка индивидуальных таймеров на форсунки и катушки, в прерывании происходит толко смена состояния пина и если это срабатывание на открытие то взвод таймера на следующее срабатывание для закрытия - время 10-30 тактов и то если програмно рулить, в том же январе форсунки рулятся через аппаратный ШИМ который конфигурируется каждые пол оборота в основном цикле после расчета времени впрыска и соответсвенно не занимают времени прерываний и ресурсов вообще... В stm32f103v каналов таймеров с шимом вполне достаточно...
Да я же не против - делайте на нем. :lol: Это проще конечно в плане что и думать особо не надо. Я нигде не уверждал, что кортекс не справится. :lol: Конечно справится, если Вемс вон на 8 битах и 16 МГц справляется с 8 форсунками и 8 каналами зажигания. Имея всего 6 каналов таймеров. Граблей с кортексом правда будет ничуть не меньше и не больше. В аппаратном плане , кроме таймеров, он даже менее удобен - теми же приоритетами рулить на лету сложно. Но вычислительные возможности конечно выше. Сможете заодно от HIP9011 отказаться, кортекс при 72МГц спокойно обсчитает FFT прямо в реалтайме. Это можно и на 8-ми битнике попробовать даже, но конечно не с FFT, а с Гертцелем. И считать только три спектральных линии, подобрав частоту центральной под центральную частоту детонации. Только аналоговая обвязка ДД неясна. Мне в общем тоже ничто не мешает подвесить выходы форсунок на выходы таймеров и в 8-ми битном автомобильном проце. Каналов 16 битных таймеров у меня 9. 1 - ДПКВ, 4 на форсунки и 2 на зажигание. Еще 2 канала в запасе. Можно еще 2 форсунки добавить или полностью на статическую раздачу искры перейти. Выбор есть. Если не понравится с очередью - всегда можно перейти на аппаратный таймер. :lol:
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Обсуждение схемы от Makar

Post by Qwertty »

nikll wrote: Порядковая приотерезация в диспетчере позволит сдвигать менее важные функции в конец и соответсвенно они будут отрабатывать только после того как затребованные более важные отработают, уж лудьше shift-light (или что там Stranger21 хотел) перестанет работать после 12000 чем УОЗ перестанет расчитываться, или логи перестанут записываться вместо существенного опаздания расчета наполнения.
Это самый стандартный подход - урезанный по возможностям шедулер от кооперативной ОС. Фокус тут только в том, что для работы приоритетов длинные операции приходится делить. Допустим имеем 2 задачи. Одна важная и с высоким приоритетом, другая неважная, длительная и вообще может в фоне выполняться. Расположили их по порядку - сначала проверяется флаг более приоритетной, потом менее. Взводится флажок менее приоритетной и она начинает выполняться. И тут приходит запрос более приоритетной. Но пока менее приоритетная не вернет управление в основной цикл более приоритетная будет ждать. Приходится менее приоритетные задачи делить на части. Собственно это и есть - кооперативная ОС с приоритетами. Их много даже готовых. Хоть под кортекс, хоть под почти любое другое ядро. Не всегда это получается безболезненно для логики работы, но есть и ОС с вытесняющим приоритетом. Я даже на STM8 могу такую использовать - памяти много, а контекст минимальный. А уж на Кортекс сам бог велел внедрить что то типа FreeRTOS. Проблема с приоритетами будет автоматом решена.
nikll
LQFP144 - On Top Of The Game
Posts: 553
Joined: Sun Nov 06, 2011 9:20 pm
Location: Russia, Yekaterinburg
Contact:

Re: Обсуждение схемы от Makar

Post by nikll »

Ну да, для корректной работы очереди любые длинные и низкоприоретентые задачи следует делить, банально через switch бьющий код функции по частям с хранением номера шага гдето во внешней переменной текущего модуля, или заюзать либу типа protothreads которая сама все это разрулит. Все критически важное по времени выполняется в прерываниях, но по сути там нет ничего тяжолго по времени (ну запустить преобразование АЦП ДАДа, или запустить таймер для зажигания). Все остальное ко времени не критично, на низких обротах ресурсов более чем достаточно чтобы все успевать, а на высоких пропуск расчета наполнения на несколько циклов некритичен.
Я думал по FreeRTOS, пришел к выводу что для нашей задачи FreeRTOS будет лишним оверхедом не предоставляющим существенного преимущества, не те задачи :), tcp стек не нужен,интерфейсного взаимодейсвия нет, все четко распределенно по порядкам приорететам и времени выполнения, зачем городить полноценную ОСь?
На мой взгляд вполне достаточно суперцикла с захардкоженными приорететами через порядок в switch'е (обьем кода меньше сотни строк на все - вечер покодить, RTOS со всеми семафорами мьютексами потоками и прочим апи так быстро не освоить).

про volatile ты правельно заметил, вот только почити все значения используемые в прерываниях расчитываются в основном цикле. Если делать управление всеми форсунками в одном прерывании то выходит следующее:
обращение к очереди
считывание текущей записи
определение что именно требуется сделать (открыть/заркрыть, порт.пин)
если было открытие форсунки то добавляем в очередь таймер на закрытие форсунки
выбрасывание текущего элемента из очереди с переходом на следующий

все остальное запихать все в прерывание ДПКВ и там уже определять из угла начала впрыска конкретный зуб на котором сосчитать добавочное время для таймера прерывания форсунок

В общем получается немало кода и нифига не десятки тактов (очередь придется делать volatile т.к. заполнятся она будет в основном цикле и изменятся в прерывании ДПКВ)
Гораздо проще назначить нужные функции к конкретным прерываниям и не парить себе мозг, или вообще заюзать аппаратные возможности (ШИМ) как это сделанно в январях/микасах.
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Обсуждение схемы от Makar

Post by Qwertty »

nikll wrote: Я думал по FreeRTOS, пришел к выводу что для нашей задачи FreeRTOS будет лишним оверхедом не предоставляющим существенного преимущества, не те задачи :), tcp стек не нужен,интерфейсного взаимодейсвия нет, все четко распределенно по порядкам приорететам и времени выполнения, зачем городить полноценную ОСь?
На мой взгляд вполне достаточно суперцикла с захардкоженными приорететами через порядок в switch'е (обьем кода меньше сотни строк на все - вечер покодить, RTOS со всеми семафорами мьютексами потоками и прочим апи так быстро не освоить).
Реально ОС даст многое. Например сама разрулит ситуацию с длинными фоновыми вычислениями. Их не так то просто разбивать на этапы. Кроме того ОС позволит достаточно просто расширять возможности не переписывая все заново. Я не планирую расти - есть конкретная задача, надо ее решить и ездить. Максимум в дальнейшем дорабатывать алгоритмы расчета смеси. Никаких дополнительных возможностей вводить не буду. Мне это просто не надо. Хотя о ОС еще подумаю. Уж очень хорошо вытесняющая многозадачность должна лечь на архитектуру STM8 :) Тут кортекс ей не конкурент. Одна команда полностью! переключает контекст. Всего за 9 тактов. Кортекс впрочем примерно за то же время справится, но только за счет в 3 раза более высокой частоты. При равных тактах ему ничего не светит. :)
nikll wrote: про volatile ты правельно заметил, вот только почити все значения используемые в прерываниях расчитываются в основном цикле.
Прочитай что ли книжку по Си. Того же Кернигана с Ричи. Узнаешь что такое volatile и когда он нужен. Для использования переменных в прерывании рассчитываемых в основном цикле этот квалификатор нужен как корове седло. Он нужен для обратных действий. Впрочем если его и добавить для очереди - ничего не изменится. Там очень короткий и простой обработчик.
nikll wrote: Если делать управление всеми форсунками в одном прерывании то выходит следующее:
обращение к очереди
считывание текущей записи
определение что именно требуется сделать (открыть/заркрыть, порт.пин)
если было открытие форсунки то добавляем в очередь таймер на закрытие форсунки
выбрасывание текущего элемента из очереди с переходом на следующий
все остальное запихать все в прерывание ДПКВ и там уже определять из угла начала впрыска конкретный зуб на котором сосчитать добавочное время для таймера прерывания форсунок
В общем получается немало кода и нифига не десятки тактов (очередь придется делать volatile т.к. заполнятся она будет в основном цикле и изменятся в прерывании ДПКВ)
Нда. Очередь - массив структур по количеству равный числу цилиндров. Действия в очереди однотипные, вычислять что делать не надо. В структуре содержится указатель на следующую структуру - это чтоб не считать индексы или не сравнивать указатели. Собственно в структуре 4 поля. 1 - значение загружаемое в канал сравнения таймера, 1 - маска на порт, 1 - значение для вывода, 1 - указатель на следующий элемент очереди, считай на следующую структуру в массиве. И есть один указатель вне структур - на текущую структуру в очереди. Он и изменяется и используется только в прерывании, так что volatile и ему не нужен. И так наши действия примерно такие:
Загружаем указатель на текущий элемент очереди - на текущую структуру. Загружаем по нему маску и значение для вывода. Накладываем маску на порт и затем устанавливаем значение выходов. Сбрасываем флаг прерывания от этого канала. Загружаем указатель на следующий элемент очереди и сохраняем его как указатель на текущий. ВСЕ! На вскидку - обработчик около 20-25 тактов. Плюс 9+3 на вход и 11 на выход из прерывания - итого 48 тактов примерно. Около 2мкс при такте 24МГц. При этом нет ограничений - я например могу управлять сразу двумя рядами форсунок. То есть иногда включать две одновременно, а иногда только одну. Допустим наддутый мотор и соответственно высокая производительность форс. Так можно их разбить, одну большую на 2 поменьше. И на ХХ будет только одна включаться, а на режиме полной мощности - две. И это не потребует ни одного лишнего такта при обработке очереди! Только изменятся маска и значение для вывода в порт. Масштабируемость - запредельная :lol: Мне она впрочем не понадобится. :mrgreen:
Теперь прикинем загрузку на примере 4ц бензовпрыска. Имеем за оборот 2 события на открытие и 2 на закрытие. Период при 6000 оборотов - 10мС. За это время мы тратим пусть 4*60 = 240 тактов. При частоте 24МГц за 10мс имеем 240000 тактов. 240/240000 = 0,1% загрузки. Да, без таймеров просто никуда... :mrgreen: Это ж пипец - бедный проц. :mrgreen: Да, если распределить форсунки по 1 на канал таймера то можно вообще без прерываний обойтись. И целую 0,1% производительности сэкономить! Вот в этом и есть разница между решением задачи в лоб и продумыванием алгоритма. 0,1% всего. Вемсовцы явно думают над алгоритмами, я не все понимаю как они смогли реализовать. Но явно принцип на форсунки примерно такой же. Впрочем можно еще подумать, может и не 0,1% удастся занять. Вот только ИМХО это и так не напряжно.
nikll
LQFP144 - On Top Of The Game
Posts: 553
Joined: Sun Nov 06, 2011 9:20 pm
Location: Russia, Yekaterinburg
Contact:

Re: Обсуждение схемы от Makar

Post by nikll »

volatile это всеголиж указание компилятору неоптимизировать работу с данной переменной по средствам хранения ее значения в регистре (достали - сделали действие - записали). К примеру gcc предпочитает хранить значения переменных в регистрах во время активной работы с этими переменными, все хорошо пока нет прерываний, но вот если в прервании переменная будет изменена то по выходу из прерывания основной поток продолжет выполнятся с места прерывания не догадываясь о том что переменная была изменена. "Того же Кернигана с Ричи" :) про "талмуд" ты конечно знатно вспомнил, во только в той книги про volatile какраз помоему ничего небыло (если конечно память не изменяет).

По поводу очереди, а кто эту очередь по твоему заполнять то будет? В моем представлении это работает так:
В основном цикле расчитывается время впрыска и угол начала впрыска (по 3д карте наполенние/обороты), можно конечно тупо лить в вмт но это ощутимо хуже (тестировал на Мольт - jc-tech.ru)
Любые события привязанные к углам по КВ определяются сначала грубо по ДПКВ (начало или конец определенного зуба перед нужным углом). Потом в прерывании ДПКВ в зависимости от текущей скорости вращения (предыдущий период за 3 градуса) определяется время таймера для точного позиционированния с привязкой к коленвалу от текущего момента (и это надо делать очень быстро, если скорости не будет хватать возможно имеет смысл брать не последний зуб перед углом, а предыдущий). Взводится таймер прерывания и делаются дальше свои дела. Прерывания форсунок/катушек имеют наивысший приоритет и отрабатывают за минимальное время (20 тактов на вход/выход если я ничего не путаю, четыре такта для определения закрыт ли пин, четыре такта на открытие/закрытие форсунки/катушки, и меньше десятка тактов на перевзвод таймера для закрытия если текущее состояние "открыто") - итого пара десятков тактов что даже в ДПКВ не сыграет существенную роль.

Та схема что ты описал умеет только переключать состояние порта по таймеру беря данные из списка. Ни углов начала открытия ни времени закрытия я в ней не нашел. Сильно напомнило мой код "тройника" для подключения четырехканального ЭБУ на виэйт с полным повторением сигналов по портам и длительности но со сдвигом в 90 градусов относительно коленвала.

Если же еще в самом прерывании единсвенного таймера который будет рулить всем делать очередь то придется ее во первых обрабатывать что как минимум в несколько раз раздует время выполнения и во вторых потребуется эту очередь заполнять в ДПКВ вместо простой инициализации конкретного таймера.
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Обсуждение схемы от Makar

Post by Qwertty »

Есть у K%R про volatile, хотя и не все аспекты освещены. Полностью этот квалификатор описан в стандарте языка Си. И он имеет множество применений. Некоторые не связаны с переменными вообще. Любишь GCC? Попробуй такое - asm volatile ("nop")
Переменной тут как бы нет. Но основное применение все же - указать компилятору, что переменная может меняться сама по себе. Это прямо из названия квалификатора вытекает. Во время прерывания никакие переменные, изменяемые в основном цикле, меняться не будут. Так что volatile тут как корове седло.
Очередь конечно не считает углы. Зачем ей это? Это всего лишь замена нескольких каналов аппаратного таймера на один канал. Т.е. просто разделение ресурса по времени. Углы должен считать основной цикл. А в прерывании от ДПКВ эти рассчитанные углы корректируются при необходимости и грузятся в... В одном случае в железный регистр таймера, в другом в структуру очереди. Никакого оверхеда при этом нет - как было два значения для загрузки в таймер, так два и осталось. Какая разница куда их записать?
Насчет раздутия обработчика - все куда проще. О указателях на функции слышал? Кроме того этот выбор с каким каналом работать у тебя тоже будет. Потому как на одном векторе аж 4 канала сидит. У меня даже короче выйдет - меньше вариантов. :) Я не вижу серьезных преимуществ с распределением форсунок по железным каналам таймера. Да, небольшие есть - можно приоритет прерывания от форсунок сделать минимальным. Вот пожалуй и все. Выигрыш в 0,1% по загрузке во внимание не берем - не та цифра. На 2ц моторах метод с очередью ничего не дает. А например на 4ц позволяет сократить требуемые каналы вдвое. Лучше ли иметь много таймеров? Да. Но это не настолько критично, чтобы пихать не предназначенный для авто проц в автомобильный ЭБУ. Трахаться с согласованием с датчиками и защитой входов. А также и с согласованием выходов. Но это лично мое мнение, я его не навязываю. :) У каждого свои приоритеты. Для меня простота и надежность аппаратной части перевешивает небольшое усложнение программы. И я точно знаю что при необходимости разрулю и 8 форсунок с приемлемой точностью, даже на 8 битном процессоре. Да, нормальный таймер позволит поднять точность. К примеру на LPC1768 я гарантированно уложился бы по точности в 10нс. Нано, не микро :) Вот только зачем? Если я дозирую топливо с таким разрешением и точностью это не значит что и рассчитал я настолько же точно. А именно в расчете и будет основная погрешность. По первым мыслям расчет достаточно непростой. Даже не в плане расчета - все же тактов на него дофига. А вот учесть кучу факторов непросто...
ender11
LQFP112 - Up with the play
Posts: 197
Joined: Sat Dec 11, 2010 4:05 pm

Re: Обсуждение схемы от Makar

Post by ender11 »

STC wrote:(нужна обязательно аппаратная реализация деления)
аппаратное деление тоже дофига циклов занимает.
Qwertty wrote:Автомобильный - от 31$. В ЭФО нет вообще.
это, в общем-то, экзотика. почти как военный. можно купить дорого в партии 1000 штук (утрирую, но по efind он у всех под заказ. и 1 штуку они наверняка не повезут).
а собственно надо ли automotive(125)? разве для эбу не хватит industrial(85)?
Sergey89
QFP80 - Contributor
Posts: 71
Joined: Sat Dec 03, 2011 1:28 pm
Location: Russia, Velikiy Novgorod
Contact:

Re: Обсуждение схемы от Makar

Post by Sergey89 »

у той же at32uc3c ацп трёхвольтовое, т.ч. для авто применения тоже не очень то и подходит. у ST есть хорошие серии 16 битников st10 и 32 битные spc56 для автомобильного применения, но про цену и доставаемость наверное лучше не упоминать.
Qwertty
LQFP144 - On Top Of The Game
Posts: 252
Joined: Thu Jul 26, 2012 12:35 pm

Re: Обсуждение схемы от Makar

Post by Qwertty »

Нет в жизни счастья. :) С 3В АЦП связываться не хочется. Автомобильные 16-32 битные от СТ по цене вполне приемлемы - 20-30$, но с доставаемостью проблемы. Да и фиг с ними - мне хватит и STM8A52AA за 5$. Не такой и плохой выбор. Посмотрите на тот же Вемс - жалкая мега128, а мозг получился весьма накрученным. Про половину его возможностей я даже не знаю что это :) Очень оригинально там сделана поддержка ШИМ на форсунки. Впечатлило количество стабилизаторов на плате. Чуть ли не к каждой микросхеме/датчику свое отдельное питание. Хотя так наверно уже перебор.
nikll
LQFP144 - On Top Of The Game
Posts: 553
Joined: Sun Nov 06, 2011 9:20 pm
Location: Russia, Yekaterinburg
Contact:

Re: Обсуждение схемы от Makar

Post by nikll »

по питанию мне понравился подход Макара, индивидуально к всему смысла нет но поделить как минимум на две части стоит.
вместо аппаратного деления можно юзать умножение со сдвигом (правда не всегда), в многошаговых расчетах где много операций деления можно пересмотреть порядок для сведения всего к одному делению.

Очередь придется заполнять и в прерывании тоже, иначе как взводить таймер на закритие одной из форсунок которую мы толко что открыли? А с учетом того что во первых скваженность работы одной форсунки относительно двух оборотов кв может колебатся от долей процента до 100% (вообще не закрывается) алгоритм получится довольно сложным. Так же требуется открывать форсунки не тупо в ВМТ, а на определенном углу поворта КВ согласно 3д таблице начала фаз впрыска вида наполенние/обороты - угол. В итоге простая на первый взгляд задачка выльется в хороший набор кода который будет как минимум в несколько раз дольше работать в прерывании таймера и даст дополнительное время в прерывании ДПКВ для руления этой очередью (а там итак дохера всего вылазит).

В общем можеш сделать и на stm8, у тебя получится, во только перспектив роста на такой платформе небудет т.к. ресурсов камня маловато да и переферии на нем раз два и закончилась.
P.S. stm32f103v у нас стоит в 1,5 раза МЕНЬШЕ твоего stm8 за 5$ :) вот те линк http://www.promelec.ru/catalog/1/11/1777/0/136282/ STM32F103V8T6 - за 3,5 бакса и это в розницу, если брать хотябы 15 штук то еще дешевле
Post Reply