- Vote on answer
- posted
19 years ago
Embedded OS
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
HZ>> Была еще идея рулить векторами прерываний - т.е. иметь два HZ>> обработчика: один для приема всех символов, кроме последнего, другой - HZ>> для приема последнего. Первый ISR выполняется обычным образом, без HZ>> манипуляций контекстами, при приеме предпоследнего символа,
[...]AB> Брр... Зачем так сложно-то? Задача обрабатывающая пакет спит (никакого AB> поллинга), точнее ждет семафора. В прерываниях AB> приняли последний байт пакета и выставили евент/семафор. Тогда при AB> выходе из _этого_ прерывания мы автоматически AB> активизируем ждущую задачу, если нет более приоритетных, иначе задача AB> активизируется после окончания работы этих более AB> приоритетных.
AB> В RTOS, обычно, перепланировка происходит каждый раз при выходе из AB> любого прерывания, т.к. в них выставляются семафоры. AB> Если семафоры небыли выставлены, то переключение контекста просто не AB> происходит.
Это HZ просто без предупреждения продолжает наше с ним почтовое обсуждение этого дела, боюсь, уже двухгодичной давности :-)
В том-то и дело, что не "переключения контекста не происходит", а "он переключается назад туда, где был"
Т.е. с точки зрения затрат времени "логическое" отсутствие переключения и "логическое" его наличие эквивалентны - так как "физическое" происходит. Т.е. ISR полностью сохраняет всё, делает свою работу, потом работает перепланировщик и при необходимости делает переключение на другой контекст. При такой постановке по каждому байту переключаться на процесс приёма и обработки пакета или накапливать пакет без перепланировки - разница тоже есть, в _дополнительное_ переключение контекста уже _после_ отработки процесса приёма байта.
Но хочется же не просто мёд, а ещё и ложкой.
Подмена вектора или использование другого прерывания, которое будет отработано после возврата из ISR, просто складывающей байты в буфер пакета - предназначено устранить и "холостое" сохранение/восстановление контекста, довльно толстое, к примеру, у AVR. Хотелось бы приём байта сделать "внеосевым" прерыванием, просто оформленным как SYGNAL/interrupt и т.п. конкретного компилятора С. В этом случае сохраняться/восстанавливаться будут только необходимые регистры и только в конце приёма пакета надо сделать взведение семафора и переключение контекста. Но... не получается. На стеке - *огрызок* контекста текущего процесса, причём с большой вероятностью совершенно не соответствующий начальной части "осевого" формата и вообще зависит от перекомпиляции. Его надо вернуть взад и только затем соорудить полное сохранение и перепланировку. Это можно сделать подменой вектора (если известно, когда его подменять) или инициацией другого прерывания, оформленного "по-осевому" - если есть где его взять :-)
WBR,
- Vote on answer
- posted
19 years ago
OR>> Переключение разряда индикатора вкупе с опросом кнопок в "обычном" OR>> прерывании займут времени столько, сколько одно переключение контекста.
OR>> Почему бы не считать, что динамическая индикация вообще "как бы OR>> аппаратная", просто её буфер лежит в ОЗУ процессора - [...]
HZ> Мне кажется, ты вполне понял, что этот псевдокод был приведен HZ> исключительно для того, чтобы проиллюстрировать идею. Будем считать, что я тебе намекаю, что для иллюстрации идеи надо брать примеры, которые не будут у многих в качестве первой (а у многих из них - и последней) реакции вызывать мысль "тю, ради такого простого - и столько городить", так как таким методом идею можно опорочить.
HZ> Представь, что там не переключение цифры индикатора, а обновление HZ> видеоозу, которое занимает... HZ> Представь, что там не три кнопки, а клавиатура, где не HZ> только нажатия надо обрабатывать, но и определять события (клик, нажали HZ> и HZ> держим, отпустили) и комбинации (нажаты две кнопки) и т.д. Это тоже все HZ> в прерывание пихать? Вот с чем у меня в таких случаях туго - так это с воображением. Ну не ставлю я ни в реальную схему, ни в учебный пример с
10-милиамперным током -- 10-амперный транзистор. ВидеоОЗУ *обновляться* в прерывании не должно, в прерывании оно может только выбрасываться в индикатор, если ПДП нет :-), поэтому мне тяжело такое представить. Обновление видеоОЗУ - это, грубо говоря, топтание по знакогенератору как результат выполнения функции класса printf - такому не место даже в высокоприоритетном управляющем потоке - всю диагностику он должен пихать в очередь к менее приоритетному процессу user interface. Не говоря уже о том, что этому не место в прерывании.OR>> А по поводу коммуникационного - уже когда-то с тобой обсуждал.
HZ> Да, я помню. Тогда же еще витала идея двух обработчиков прерываний с HZ> подменой вектора. Но если скорость 9600, не проще ли написать линейный HZ> код приема? Давай про воображение :-), а ВДРУГ тебе придётся перейти на 115200 - ведь придётся всё переписывать. И ещё немного воображения - приём пакета и его анализ - это, вообще говоря, разные уровни. И тебе может понадобиться сменить способ доставки пакета - добавить/убрать байт-стаффинг, какие-то дополнительные заголовки, etc - тебе же придётся менять код процесса, который обрабатывает ПАКЕТЫ. Для удобства такое дело часто разделяют на два связанных процесса, "верхний" работает с пакетами, не заморачиваясь со способом их доставки. Я просто предложил "нижний" затолкать в прерывание :-)
HZ> Перерасход ресурсов в МК совершенно не важен, пока их хватает. Что интересно - я сам часто такое говорю. Но только у нас разный порог, по которому мы считаем - зря ресурс потрачен или не зря. А тратить зря даже то, что в избытке - это противоречит моим убеждениям.
HZ> Что толку, HZ> если написать все плотно, ужаться до предела и проц будет простаивать и HZ> половина ОЗУ будет не задействованной? Только лишняя трата сил. Каких сил? В случае с индикацией - код, связанный с изыманием очередного байта из дисплейного буфера, возврат на его начало в конце - всё равно присутствуют, его всё равно писать. В случае динамической индикации в прерываниях - его КАК МАКСИМУМ надо завернуть в if( --disp_cnt == 0) { disp_cnt = disp_period; DISPLAY_CODE(); // это placeholder для реального кода дин. индикации. } в случае отдельного процесса - в for(;;) { DISPALY_CODE(); sleep(disp_period); } Я в упор не вижу лишней траты сил. Полтора десятка лишних нажатий клавиш - не в счёт.
HZ> Так вот, он даже магазин за хлебом HZ> на машине едет, хотя там идти 5 минут (и поездка стоит дороже самой HZ> покупки). Подозреваю, что и время он тоже не экономит, а то и наоборот - лишнее тратит. Видел таких. Машина ради машины, а не ради улучшения жизни. Я как раз о том, что если за хлебом - пешком час тюхать, то спору нет - надо взять машину и заодно подумать - что ещё в неё затолкать, чтобы лишний раз не ездить, соседу предложить - "я всё равно еду". А вот если пять минут - то *надо* пройтись пешочком.
HZ> Говорит, что ему так удобнее. Попробуй такого в этом разубедить! :) HZ> И должен признать, что кое в чем он не так уж и не прав. Может быть, может быть... Только не надо тогда жаловаться, что города становятся всё вонючее, реки всё загаженнее и т.п.
wbr,
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
- Vote on answer
- posted
19 years ago
ON> Да, наверное и не надо. Hо динамическое создание и удаление процессов ON> нужно. ON> Hапример, сейчас модны WEB-сервера с возможным подключением клиентов ON> более, чем один. А сколько их будет- оценить трудно. Эту же проблему гораздо легче решить одним едиснвтенным процессом (или, допустим, по одному процессу на одно физическое подключение - будь то сетевая карта, COM, ...). Процесс получает из очереди (туда суёт драйвер) MAC-пакет - всё равно это делает один процесс, а затем вместо выбора по полям пакета - какому готовому процессу пользователя перслать этот пакет или породить новый - выбрать из массива/списка структуру, связанную с этим клиентом или найти в массиве свободную структуру (добавить в список распределённую по malloc). В структуре - всё связанное с этим подключением (это были бы локальные переменные процесса в многопроцессной модели). И один код, построенный по принципу автомата (машины состояний). Такой сервер и работать быстрее должен - "контекст процесса" заменяется на "контекст соединения", а последний переключается сменой одного указателя.
ON> Пол-года вообще может не ON> быть ни одного. Динамическое размещение процессов решает эту проблему, Этот единственый процесс можно породить статически и пусть спит пол-года. ОЗУ он жрать не будет (кроме *одного* описателя процесса), если структуры, отвечающие за соедниение - выделять динамически. Код в ПЗУ он жрёт всё равно, раз он вообще есть в системе. Так что нужно просто правильно комбинировать подходы.
ON>>> Hо на практике, для неймановской архитектуры, которой ON>>> обладают подавляющее большинство мелких однокристаллок, Тебе уже сказали - что-то ты путаешь в нейманах/гарвардах.
ON>>> никакой ON>>> независимости Cи-программ от платформы достичь не удается. *программ* - да, не удаётся. *модулей* - смотря каких, чем дальше от железа (процессора) - тем проще сделать независимым (с небольшим конфигурированием через h-файл либо проекто-зависимые функции, которые тоже могут быть #define или inline в том h-файле).
13-Mar-05 19:53 Olga Nonova wrote to Andy Mozzhevilov:ON>>> Hа приложение ничего не остается. ON>>> Кроме того, там не хватает внутреннего 4К RAM и люди вынуждены ставить ON>>> дополнительные 64K чтобы все это работало как-то.
AM>> А если надо более или менее полноценный TCP/IP, то внешнюю память AM>> придется ставить независимо от наличия ОС.
ON> Вот именно! Для связных задач нужны буферы обмена внушительных размеров. Так причём тут ОС??? Такую задачу как не пиши - памяти под буферы пойдёт много. Так и в том проекте - внешнее ОЗУ не из-за ОС, а из-за задачи.
AM>> Ставить соответствующий uC, потому что на мелких uC такие задачи не AM>> решаются ни с ОС, ни без них. ОС требует относительно мало ресурсов, если AM>> это именно то количество ресурсов, которого нахватает для реализации AM>> задачи при использовании ОС, значит uC выбран неверно, следовательно AM>> точно также эти ресурсы могут закончиться и без использования ОС.
ON> Все это правильно. Hо, постепенно мы так отходим от изначальной мечты- ON> все ON> упихать в мелкую однокристаллку за счет жуткой экономии байтов и битов. ON> Ведь, именно эта идея лежит в снове операционки Harry. Нет у него идеи упихать в маленькую однокристалку толстый проект, который независимо ни от чего требует кучу ОЗУ и немеряно кода. У него есть идея задачи, которые с лезут в 512-1K байт ОЗУ (т.е. уровень начиная от ATmega8, ATmega48/88/168) решать по той же идеологии.
Чем это хуже, чем твоё желание наплодить по процессу на каждое TCP/IP подключение - я не понимаю.
ON> Hу где же тут интуиция, когда я лично наблюдала в дизассем,лере, как Си ON> компилятор копирует из Flash в SRAM константы? Зачем? Можете обьяснить? Потому, что C-компилятор -- не телепат. Ему сказали const - он только не даст обратиться к этому объекту на запись. А может ты сама хочешь, чтобы строка лежала в ОЗУ и чтобы обращение к ней было более простым и быстрым? Есть же разница - обращаться разными командами (lds/ldd в случае AVR) или только одной (lpm). Надо было почиать описание компилятора и разобраться, как ему указать - где хранить строки и как к ним обращаться.
ON> Это все в классической теории. Hа практике же Си компиляторы для AVR ON> начинают ON> пользоваться стеком для передачи формальных параметров в процедуры, ON> только когда исчерпан запас рабочих регистров R16...R23. А для PDP-11 - когда исчерпан запас R2..R5 (если я не забыл). Ну и что?
ON> Для стека данных ON> используется только регистры YL,YH. И это вы называте платформонезависимымым ON> решением? А для PDP-11 - только R6. Ну и что?
Какая мне разница - во что оно скомпилируется? Платфоромнезависим - исходный текст (понтяно, что не всего, а аппаратно-независимого).
ON> которые могут располагаться только в ОЗУ. Попробуйте средствами компилятора ON> Cи ON> в неймановской архитектуре создать в SRAM программный код и отдать ON> управление ему. В гарвардской же такое делается одним движением. И это будет платфоромнезависимо??? :-) В гарвардской это вообще невозможно в силу того, что адресное пространство кода - совсем другое, из адресного пространства данных процессор код выбирать не умеет (даже если извернуться и объединить их физически, как одним элементом 555ЛИ1 дать MCS51 использовать ОЗУ и как код и как данные - выбирается код всё равно из пространства кода). В неймановской - а тоже не во всякой, если защита памяти есть, то "обычная" программа не сможет записать в область ОЗУ кода и выполнить команды из области ОЗУ данных, несмотря на то, что они в одном пространстве.
ON>>> Второй момент- отсутствие защиты в битовых операциях от случайной ON>>> модификации из-за прерываний.
AM>> Можно узнать, в каком языке эта защита есть?
ON> Hапример в PLM-51 от Intel. Там используются нормальные команды обращения Это не в языке, это в процессоре. Переменные типа bit для MCS51, существующие во всех расширениях C для этого кристалла - нормально обслуживаются при помощи setb/clr. Но вот если я захочу изменить
3-битовое поле - то и PL/M-51 не будет "надёжным", так как такова архитектура процессора.AM>> Что там особо ценного в библиотеках?
ON> Самому не нужно заниматься рутиной математики, строками, TCP/IP. Времени ON> отнимает - тучу. А без самого языка высокого уровня вполне можно обходится ON> на одном лишь макроассемблере. На ошибки в работе со строками не нарывался (Avocet C51, Keil C51, IAR/AVR, avr-gcc). С математикой - у меня её сложной не было. Подпрограмма вычисления CRC16 используется одна и та же и в проектах на MCS51, и AVR, и win32 (BorlandC). Нормальная библиотека TCP/IP - вещь вообще независимая от процессора, если в библиотеке есть глюк, то её можно компилировать хоть для пентиума - глюк останется.
ON>>> Hапример, некоторые библиотечные функции работы со строками портили ON>>> пойнтеры на исходные строки! Вряд-ли такое можно считать фичей. А как это? Может что-то типа того, что компилятор строки в ОЗУ разместил - просто что-то ещё прочесть надо было??
wbr,
- Vote on answer
- posted
19 years ago
MP>>> Скажем у тебя usart имеет самый высокий уровень а обработчик MP>>> пакетов должен быть с уровнем выше main но ниже usart. Берешь MP>>> любое незадействованное в программе прерывание ставишь ему низкий MP>>> приоритет и взводишь в теле usart interupt его битик в точке MP>>> приема пакета. Оно будет вызванно сразу-же по выходу из usart, OR>> Тю, зачем? MP> Красиво, понятно, 100% будет везде работать. Не "везде", а только там, где найдутся свободные прерывания (что? и ты тоже ставишь процессоры с лишними ресурсами? :-)) и где можно программно инициировать аппаратное прерывание путём записи битика. Флаги прерываний-то запросто могут быть read-only со сбросом чтением регистра или со сбросом записью единицы - т.е. установить программно флаг прерывания невозможно.
Так что "100% будет работать" на MCS51, но там же 100% будет работать и очистка через reti.
OR>> Очистили логику прерываний выполнением reti - теперь все остальные OR>> прерывания будут спокойно прерывать данное, оно уже выполняется OR>> на уровне фоновой. MP> Классический Синклеризм. Hо раз работает то в принципе можно и так. Взведение программно бита прерывания от аппаратуры - точно так же синклеризм или пикоманство (по вкусу), так как есть использование специфических особенностей данного железа.
А понижение приоритета процессора после того, как драйвер выполнил критическую часть - подход более древний чем сам MCS51 и более прямой, более экономичный (не делаются лишние push/pop-ы и менее приоритетная часть драйвера часть информаци получает уже на регистрах). В данном случае с вызовом голого reti кривизна только в том, что у MCS51 биты IPL программно недоступны и приводить в состояние "разрешено" их приходится той единственной командой, которая это делает.
wbr,