|
Стек для прерываний, и недостаток таймеров |
|
|
|
Jul 26 2009, 20:51
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Кто нибудь делал отдельный стек для прерываний? есть ли смысл? код думаю писать как то так, Код handler: sts stack-0, r16 sts stack-1, r17 in r16, __SP_L_ in r17, __SP_H_ sts stack-2, r16 sts stack-3, r17 ldi r16, lo8(stack-4) ldi r17, hi8(stack-4) out __SP_L__, r16 out __SP_H__, r17 //здесь код обработчика прерывания // востановление писать лень ) тут все понятно reti_ Не слишком ли будет тяжеловесно? хотя это не главный вопрос, основная сложность с компилятором (GCC) как его заставить генерировать обработчтки в таком виде? можно __attribute__ ((__naked__)) но тогда надо как то следить за тем какие регистры были использованы, не сохранять же все. Похоже надо начинать смотреть исходники GCC. Правка: push/pop и st/ld длятся все по 2 такта, можно просто заменить все push на sts с фиксированными адресами ... потерь в скорости не будет.
Сообщение отредактировал amaora - Jul 26 2009, 21:17
|
|
|
|
|
Jul 26 2009, 20:58
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
И вопрос второй, в atmega16 три таймера, а что если надо больше? нулевой занят планировщиком для прееключения задач, первый планирую для ШИМ, второй для часов с отдельным 32.768 кГц резонатором. А надо вот ещё опрашивать небольшую клавиатуру с частотой от 60..120 Гц. Что можно сделать? сменить MCU не вариант. Цитата(aaarrr @ Jul 27 2009, 00:55)  Вот на этот вопрос Вам и надо сначала найти ответ. Я лично не вижу ни малейшего смысла. Не хочется держать на стеке каждой задачи пустое место размером ~20 байт. Пока сложно сказать хватит ли 1кб на все.
Сообщение отредактировал amaora - Jul 26 2009, 20:59
|
|
|
|
|
Jul 26 2009, 21:19
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(amaora @ Jul 27 2009, 00:58)  А надо вот ещё опрашивать небольшую клавиатуру с частотой от 60..120 Гц. Что можно сделать? сменить MCU не вариант. Можно сделать программный таймер, не обязательно же для каждого чиха иметь отдельный аппаратный. Цитата(amaora @ Jul 27 2009, 00:58)  Не хочется держать на стеке каждой задачи пустое место размером ~20 байт. Пока сложно сказать хватит ли 1кб на все. Понятно. Тогда нужно оценивать все в целом - от тяжеловесности прерываний, до целесообразности вообще применения ОС в столь стесненных условиях. Я бы делать еще один стек не стал, но хозяин - барин.
|
|
|
|
|
Jul 27 2009, 05:47
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(amaora @ Jul 26 2009, 23:51)  Кто нибудь делал отдельный стек для прерываний? есть ли смысл? Когда писАл на асме, оформлял задачи "для каждого чиха", в виде подпрограмм с переопределяемой точкой входа, простенький TCB содержал 8 байт (pc:2, sp:2, X:2,Z:2), за ним следовали локальные переменные (на них всегда указывает Y) и стек. Все задачи, ессно, могли быть реентерабельны. Принимая во внимание, что на мега16 нельзя создать андроида  , рискну предположить, что глубина стека в этом случае будет байт 16. Но вот Сишные концепты - не влезают в эту схему. Грубое юзание стека не позволит.
|
|
|
|
|
Jul 27 2009, 09:35
|
Местный
  
Группа: Свой
Сообщений: 327
Регистрация: 12-04-05
Из: Новосибирск
Пользователь №: 4 057

|
Цитата(defunct @ Jul 27 2009, 05:01)  Возьмите за основу кооперативную ОС, - один общий стек на все задачи и прерывания. А разве в кооперативной ОС один стек на все задачи? Насколько я понимаю, кооперативная ОС отличается от некооперативной тем, что в первом случае, задача сама решает, когда передать управление другой задаче, а во втором - ОС насильно прерывает одну задачу и передает управление другой. Или я ошибаюсь в терминологии?
|
|
|
|
|
Jul 27 2009, 11:01
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Zlumd @ Jul 27 2009, 12:35)  А разве в кооперативной ОС один стек на все задачи? Да. Иначе какой в ней смысл и преимущество над вытесняющей ОС? Цитата Насколько я понимаю, кооперативная ОС отличается от некооперативной тем, что в первом случае, задача сама решает, когда передать управление другой задаче, а во втором - ОС насильно прерывает одну задачу и передает управление другой. Или я ошибаюсь в терминологии? В общем верно, если "передать управление другой задаче" заменить на "передать управление системе". Теперь, возьмем во внимание, - если задача сама решает когда передать управление системе, то что мешает ее построить в виде конечной функции, а планировщику периодически эту функцию вызывать? Цитата(SasaVitebsk @ Jul 27 2009, 13:04)  Я бы тоже. Да ещё бы ввёл флаг-байт с временными метками... ну типа светодиодиком помигать с частотой 2Гц либо 1Гц и т.д. Не проще на один таймер посадить только планировщик. Который бы вызывал остальные задачи ровно тогда когда их нужно вызывать?
|
|
|
|
|
Jul 27 2009, 16:54
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(amaora @ Jul 27 2009, 18:56)  А вот генерацию пролога/эпилога прерываний придется похоже выполнять с помощью скриптов Имхо, это шаг в сторону. Жизнеспособны в этом случае только варианты написания прерываний либо на чистом Си, либо на чистом асме. Остальное - полумеры, рано или поздно кривизна такого подхода себя обнаружит. Цитата По поводу кооперативной многозадачности Например, так Код void system (int priority) { switch(priority) { case 0: task0(); case 1: task1(); task2(); case 2: task3(); } } /*........................*/ void task0(void) { if(!data_ready()) system(1); /*............*/ } int main(void) { while(1) system(0); return 0; } ЗЫ: при невозможности разрулить приоритетами мютексы проще встраивать в саму задачу.
|
|
|
|
|
Jul 28 2009, 01:05
|
Местный
  
Группа: Свой
Сообщений: 327
Регистрация: 12-04-05
Из: Новосибирск
Пользователь №: 4 057

|
Цитата(defunct @ Jul 27 2009, 18:01)  Да. Иначе какой в ней смысл и преимущество над вытесняющей ОС? Преимущество в том, что нужно тратить меньше усилий по разделению доступа к общим ресурсам. Например, если какая-то многобайтовая переменная используется в обоих задачах, то в вытесняющей ОС при изменении этой переменной приходится запрещать прерывания, а в кооперативной этого не надо делать. Цитата(defunct @ Jul 27 2009, 18:01)  В общем верно, если "передать управление другой задаче" заменить на "передать управление системе". Теперь, возьмем во внимание, - если задача сама решает когда передать управление системе, то что мешает ее построить в виде конечной функции, а планировщику периодически эту функцию вызывать? Так это не несколько паралельно выполняющихся задач. Это одна задача. Каждая задача подразумевает сохранение всех локальных переменных, которые лежат в стеке, при переключении с задачи на задачу.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|