Embedded OS

Reply to
Maxim Polyanskiy
Loading thread data ...
Reply to
Maxim Polyanskiy
Reply to
Alexander Torres
Reply to
Nickita A Startcev
Reply to
Vladimir Vassilevsky
Reply to
Maxim Polyanskiy
13-Mar-05 16:01 Alexey V Bugrov wrote to Harry Zhurov:

HZ>> Была еще идея рулить векторами прерываний - т.е. иметь два HZ>> обработчика: один для приема всех символов, кроме последнего, другой - HZ>> для приема последнего. Первый ISR выполняется обычным образом, без HZ>> манипуляций контекстами, при приеме предпоследнего символа,

[...]

AB> Брр... Зачем так сложно-то? Задача обрабатывающая пакет спит (никакого AB> поллинга), точнее ждет семафора. В прерываниях AB> приняли последний байт пакета и выставили евент/семафор. Тогда при AB> выходе из _этого_ прерывания мы автоматически AB> активизируем ждущую задачу, если нет более приоритетных, иначе задача AB> активизируется после окончания работы этих более AB> приоритетных.

AB> В RTOS, обычно, перепланировка происходит каждый раз при выходе из AB> любого прерывания, т.к. в них выставляются семафоры. AB> Если семафоры небыли выставлены, то переключение контекста просто не AB> происходит.

Это HZ просто без предупреждения продолжает наше с ним почтовое обсуждение этого дела, боюсь, уже двухгодичной давности :-)

В том-то и дело, что не "переключения контекста не происходит", а "он переключается назад туда, где был"

Т.е. с точки зрения затрат времени "логическое" отсутствие переключения и "логическое" его наличие эквивалентны - так как "физическое" происходит. Т.е. ISR полностью сохраняет всё, делает свою работу, потом работает перепланировщик и при необходимости делает переключение на другой контекст. При такой постановке по каждому байту переключаться на процесс приёма и обработки пакета или накапливать пакет без перепланировки - разница тоже есть, в _дополнительное_ переключение контекста уже _после_ отработки процесса приёма байта.

Но хочется же не просто мёд, а ещё и ложкой.

Подмена вектора или использование другого прерывания, которое будет отработано после возврата из ISR, просто складывающей байты в буфер пакета - предназначено устранить и "холостое" сохранение/восстановление контекста, довльно толстое, к примеру, у AVR. Хотелось бы приём байта сделать "внеосевым" прерыванием, просто оформленным как SYGNAL/interrupt и т.п. конкретного компилятора С. В этом случае сохраняться/восстанавливаться будут только необходимые регистры и только в конце приёма пакета надо сделать взведение семафора и переключение контекста. Но... не получается. На стеке - *огрызок* контекста текущего процесса, причём с большой вероятностью совершенно не соответствующий начальной части "осевого" формата и вообще зависит от перекомпиляции. Его надо вернуть взад и только затем соорудить полное сохранение и перепланировку. Это можно сделать подменой вектора (если известно, когда его подменять) или инициацией другого прерывания, оформленного "по-осевому" - если есть где его взять :-)

WBR,

Reply to
Oleksandr Redchuk
13-Mar-05 12:33 Harry Zhurov wrote to Oleksandr Redchuk:

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,

Reply to
Oleksandr Redchuk
Reply to
Andy Mozzhevilov
Reply to
Andy Mozzhevilov
Reply to
Andy Mozzhevilov
Reply to
Alexey V Bugrov
Reply to
Alexey V Bugrov
13-Mar-05 16:03 Olga Nonova wrote to Andy Mozzhevilov:

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,

Reply to
Oleksandr Redchuk
13-Mar-05 23:37 Maxim Polyanskiy wrote to Oleksandr Redchuk:

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,

Reply to
Oleksandr Redchuk

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.