2313 и многозадачность

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Прорезались зубы
Аватара пользователя
Сообщения: 244
Зарегистрирован: Ср авг 31, 2005 20:09:08
Откуда: Петрозаводск, Карелия.

Сообщение Pa5ha »

Если будет время, то к следующей паре по ОС хочу собрать девайс на 2313, показывающий как работает многозадачность. Т.е. сохранение и восстановление контекстов процессов. Примеры видел только в АлгоритмБилдере. Итак. Есть ли примеры на асме? Реально ли замутить такую шнягу? Собсна щас мучает вопрос как это можно сделать )

Хочу ещё сделать селекторы процессов, чтоб сделать относительную адресацию, правда придется делать по указателям. Но ничо :)

Мысли?
2kb of eeprom should be enought for everybody (C) Bill Gates` cat :)
Контактная информация:
Реклама
SfS
Друг Кота
Сообщения: 19429
Зарегистрирован: Пт янв 12, 2007 11:21:39
Откуда: Томск

Сообщение SfS »

Pa5ha писал(а):Если будет время, то к следующей паре по ОС хочу собрать девайс на 2313, показывающий как работает многозадачность. Т.е. сохранение и восстановление контекстов процессов. Примеры видел только в АлгоритмБилдере. Итак. Есть ли примеры на асме? Реально ли замутить такую шнягу? Собсна щас мучает вопрос как это можно сделать )
Хочу ещё сделать селекторы процессов, чтоб сделать относительную адресацию, правда придется делать по указателям. Но ничо :)
Мысли?
1. Есть примеры на С с ассемблерными вставками (как раз для сохранения контекста они и используются) - полуготовая ОС, используемая мной (сейчас реализовано - переключение задач, приоритеты, менеджер динамического выделения памяти). В процессе реализации находится - обработка сигналов, ожидание смерти потомков и получение кода их завершения, работа с файлами-устройствами (что-то POSIX-подобное).

2. Поскольку уже работающая ОС есть, то - реально :)

3. Принцип переключения контекста прост до ужаса - у каждой задачи свой отдельный стек, на котором она хранит все свои регистры и переменные.
Таким образом при переключении контекста происходит следующее:
а) Приходит прерывание от системного таймера.
б) Все регистры сохраняются на стеке.
в) Текущее значение SP сохраняется в описателе задачи.
г) В SP заностится значение из следующего описателя задачи.
д) Все регистры берутся со стека (это уже не тот стек, что был при входе в прерывание !!!).
е) Происходит выход из обработчика системного таймера.

4. У 2313 памяти всего -2Кбайта флеша. Для чегото более-менее серьёзного - не достаточно. Разве что для примера светодиодами помигать. Ну и, естественно, никакого динамического выделения памяти реализовать не получится...

5. Для сохранения контекста задачи надо 35 байт (32 регистра R0-R31, SREG и 2 байта - адрес возврата). Ну и для работы программы на стеке место нужно. Таким образом, на каждую задачу нужно как минимум 48 байт ОЗУ (из рассчёта, что переменные задачи занимают не более 13 байт на стеке).. То есть на 2313 может быть запущено не более lde[ (128/48 = 2.6) задач. (можно и больше, но с ограничениями. Так что лучше взять скажем 8535 или, как я, Мегу128 с внешним ОЗУ. Там простора для реализации ОС - гораздо больше.

6. При создании задачи необходимо подготовить её стек таким образом, чтобы при первом переключении на неё она начала выполняться. Пример на С:

Код: Выделить всё

/*----------------------------------------------------------------------------*/
/* Создаёт стековый фрейм задачи.
    sp          - указатель стека до создания фрейма.
    task        - адрес процедуры задачи.
    par         - параметр задачи.
    fexit       - адрес функции завершения

    Возвращает указатель стека после создания фрейма.
*/
/*----------------------------------------------------------------------------*/
void* __sys_build_stack_frame(unsigned char* sp, void* ftask, void* arg, void* fexit)
    {
        *sp-- = ((unsigned int)fexit);   /* Адрес функции завершения мл. байт */
        *sp-- = ((unsigned int)fexit)>>8;/* Адрес функции завершения ст. байт */
        *sp-- = ((unsigned int)ftask);   /* Адрес функции-задачи мл. байт */
        *sp-- = ((unsigned int)ftask)>>8;/* Адрес функции-задачи ст. байт */
        *sp-- = 0;                      /* r31 */
        *sp-- = 0;                      /* SREG  */
        *sp-- = 0;                      /* r30 */
        *sp-- = 0;                      /* r29 */
        *sp-- = 0;                      /* r28 */
        *sp-- = 0;                      /* r27 */
        *sp-- = 0;                      /* r26 */
        *sp-- = ((unsigned int)arg)>>8; /* r25 Аргумент функции-задачи ст. байт */
        *sp-- = ((unsigned int)arg);    /* r24 Аргумент функции-задачи мл. байт */
        *sp-- = 0;                      /* r23 */
        *sp-- = 0;                      /* r22 */
        *sp-- = 0;                      /* r21 */
        *sp-- = 0;                      /* r20 */
        *sp-- = 0;                      /* r19 */
        *sp-- = 0;                      /* r18 */
        *sp-- = 0;                      /* r17 */
        *sp-- = 0;                      /* r16 */
        *sp-- = 0;                      /* r15 */
        *sp-- = 0;                      /* r14 */
        *sp-- = 0;                      /* r13 */
        *sp-- = 0;                      /* r12 */
        *sp-- = 0;                      /* r11 */
        *sp-- = 0;                      /* r10 */
        *sp-- = 0;                      /* r9 */
        *sp-- = 0;                      /* r8 */
        *sp-- = 0;                      /* r7 */
        *sp-- = 0;                      /* r6 */
        *sp-- = 0;                      /* r5 */
        *sp-- = 0;                      /* r4 */
        *sp-- = 0;                      /* r3 */
        *sp-- = 0;                      /* r2 */
        *sp-- = 0;                      /* r1 */
        *sp-- = 0;                      /* r0 */
        return(sp);
    }
/*----------------------------------------------------------------------------*/
На входе в процедуру самое верхнее значение стека задачи (помним, что в АВР стек растёт ВНИЗ!). Процедура возвращает значение указателя стека, которое должно быть помещено в SP при переключении контекста задач, чтобы при выходе из обработчика системного таймера запустилась процедура по адресу task. при возврате из задачи по команде ret (задача завершена), происходит переход на процедуру по адресу fexit.
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»