Из платы АОН

Микропроцессоры и микроконтроллеры от фирмы Zilog, а также компьютеры на них построенные

Moderator: Shaos

User avatar
MC68k
Retired
Posts: 1328
Joined: 25 Jul 2011 00:14
Location: WWW

Post by MC68k »

HardWareMan wrote:
MC68k wrote:товарищ попутал многозадачность с драйверами устройств.
Ну это не драйвера, ибо в классическом понимании у каждого драйвера должно быть свое прерывание. А тут оно одно и на таймере. Это и не многозадачность в классическом смысле - так как нету управления памятью и переключения контента. Это обычная псевдомногозадачность на событиях, которые вызываются таймером, при этом каждое событие должно занимать по времени выполнения не больше половины интервала таймера, иначе жуткие тормоза обеспечены. На таком же принципе есть RTOS для Атмег, удобная штука с простой реализацией, я вам хочу сказать.
то есть 100% недо...
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Г-н Андрей Плеханов (Andrey Plekhanov) тянуть кота за хвост не стал,
и весьма оперативно исходники своей ОС выложил! :lol:
Andrey Plekhanov wrote:Выложил исходники на свой сайт:

http://andyplekhanov.narod.ru/soft/soft.htm

Если будут вопросы, можно создать отдельную тему
в конференции.

Андрей
Кому интересно - прямая ссылка.
iLavr
User avatar
MC68k
Retired
Posts: 1328
Joined: 25 Jul 2011 00:14
Location: WWW

Post by MC68k »

занятно. и всего-то две с половиной тысячи строк кода. ну с таким раскладом и спектрум можно многозадачным объявить.
andyp
Junior
Posts: 6
Joined: 26 Nov 2008 13:54
Location: Москва-Кассиопея

Post by andyp »

Увидел обсуждение моей конструкции на этом форуме.
Попробую прояснить некоторые вопросы.
MC68k wrote:занятно. и всего-то две с половиной тысячи строк кода. ну с таким раскладом и спектрум можно многозадачным объявить.
Конечно, если сравнивать с многозадачностью на РС, то она очень ограничена. На прерывании сидят не только обработчик клавиатуры,
но и некоторые задачи - таймеры и будильники.

На самом деле была задумка добавить возможность создавать
переменное число фоновых задач, каждая из которых имела бы свой
управляющий блок и стек и запускались бы в момент, когда процессор
ждет следующее событие. Это было необходимо, например, для решения систем дифференциальных уравнений одновременно с взаимодействием с пользователем.

По поводу времени обработки прерывания. Процент этого времени достаточно мал, поскольку я уменьшил частоту прерываний с 400 раз в секунду до 10, потому, что отпала необходимость обновлять 9 разрядный индикатор АОН в реальном времени. Поэтому тормозов нет абсолютно.
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Shaos wrote:Кстати по сабжу - я эту страничку видел несколько лет назад и может даже упоминал
где-то на просторах этого форума (с ходу не нашёл) - вот этот текст отлично помню:
CPU Z80
Memory RAM 32K
Memory ROM 32K
LCD 24 X 2
OS My own
Эту конструкцию здесь на форуме упоминал сам автор в топике "Маленький комп".
Но в 2008 году меня здесь не было, а все остальные вполне могли этот симпатичный
комп видеть.
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

MC68k wrote:занятно. и всего-то две с половиной тысячи строк кода. ну с таким раскладом и спектрум можно многозадачным объявить.
А реализация многозадачности должна быть маленькой. Очень маленькой и очень быстрой. Потому как все эти игры с многозадачностью очень влияют на производительность системы в общем.
Когда-то давным-давно, когда я знакомился с ассемблером на примере x86, я впихивал многозадачность и в меньшее число строк. В реальном режиме, имеется в виду. Да, конечно, при этом в качестве задачи нельзя было запустить, допустим, досовский "процесс". Задачи должны были быть написаны с соблюдением определённых правил, специфичных для моей реализации многозадачности (например, задачам нельзя было менять сегментные регистры и нельзя было трогать таймер). Да и вообще всё было весьма ограничено -- ни тебе примитивов синхронизации, ни IPC интерфейсов. Да и диспетчер задач был туп до невозможности: он просто передавал управление от одной задачи к другой по кругу, не парясь насчёт, допустим, того, что время между задачами можно делить не поровну, а по-справедливости. Но и тем не менее, когда я написал задачу, которая в бесконечном цикле гоняла змейку по экрану, я легко смог запустить сразу десять таких бесконечных циклов и видеть на экране десять ползающих змеек. Это ли не многозадачность? Причём не какая-нибудь там "кооперативная", а самая что ни на есть "вытесняющая" многозадачность.
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

bar wrote:Причём не какая-нибудь там "кооперативная", а самая что ни на есть "вытесняющая" многозадачность.
А у меня впечатление, что ни та, ни та...

Для корпоративной - задачи твои должны бы отдавать управление сами,
а для вытесняющей, так у тебя, как мне кажется, приоритет всех задач одинаков.

Впрочем, я для этого и попросил у автора исходники, чтобы в этом поразбираться
на простеньком примере...

В рамках этого форума мы неоднократно заявляли желание осуществить много-
процессорную многозадачную конструкцию, но воз и ныне там... :(

А этот простой компьютер работает - вот и поучусь на его примере. :wink:
iLavr
User avatar
MC68k
Retired
Posts: 1328
Joined: 25 Jul 2011 00:14
Location: WWW

Post by MC68k »

вот и автор подтянулся :) можно задавть странные вопросы?

2 bar понятно, что "диспетчер" должен быть маленький и быстрый
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

andyp wrote:Увидел обсуждение моей конструкции на этом форуме.
Попробую прояснить некоторые вопросы.
С исходниками пока ознакомился весьма бегло, возник вот какой вопрос:
А на каком С Вы делали их сборку, и на какой платформе?
iLavr
andyp
Junior
Posts: 6
Joined: 26 Nov 2008 13:54
Location: Москва-Кассиопея

Post by andyp »

bar wrote:
MC68k wrote:занятно. и всего-то две с половиной тысячи строк кода. ну с таким раскладом и спектрум можно многозадачным объявить.
А реализация многозадачности должна быть маленькой.
Она на самом деле маленькая.
Заключается в том, что прикладная задача ставит в очередь выполнения другие задачи, например, играть музыку, таймеры, устанавливает будильники и продолжает заниматься своим делом.
А потом получает сообщения от этих задач и производит соответствующие действия.
User avatar
Shaos
Admin
Posts: 24086
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Lavr wrote:
Shaos wrote:Кстати по сабжу - я эту страничку видел несколько лет назад и может даже упоминал
где-то на просторах этого форума (с ходу не нашёл) - вот этот текст отлично помню:
CPU Z80
Memory RAM 32K
Memory ROM 32K
LCD 24 X 2
OS My own
Эту конструкцию здесь на форуме упоминал сам автор в топике "Маленький комп".
Но в 2008 году меня здесь не было, а все остальные вполне могли этот симпатичный
комп видеть.
Точно! А я совсем забыл - склероз :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

bar wrote:Когда-то давным-давно, когда я знакомился с ассемблером на примере x86, я впихивал многозадачность и в меньшее число строк. В реальном режиме, имеется в виду.
А у тебя твоих x86-исходников не осталось? Тоже было бы интересно посмотреть...
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Lavr wrote:
bar wrote:Когда-то давным-давно, когда я знакомился с ассемблером на примере x86, я впихивал многозадачность и в меньшее число строк. В реальном режиме, имеется в виду.
А у тебя твоих x86-исходников не осталось? Тоже было бы интересно посмотреть...
Нет, увы. Те мои первые опыты программирования почили в бозе сыплющихся жёстких дисков и моих кривых рук.

Но я подумаю. Если найду линуксовый дебуггер DOS'а, может напишу снова. Просто ради развлечения. =)
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

bar wrote:
Lavr wrote:А у тебя твоих x86-исходников не осталось? Тоже было бы интересно посмотреть...
Если найду линуксовый дебуггер DOS'а, может напишу снова. Просто ради развлечения. =)
Ну тогда, с учетом имеющегося опыта, может быть сделаешь это с отражением в форуме?
Просто интересно - сейчас ты наверняка напишешь не так как давно...

Или, если хочешь, - изложи общую концепцию компактно... ПисАть-то мы все научились...
Может кто ещё в проект подключится. :wink:
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Lavr wrote:
bar wrote:
Lavr wrote:А у тебя твоих x86-исходников не осталось? Тоже было бы интересно посмотреть...
Если найду линуксовый дебуггер DOS'а, может напишу снова. Просто ради развлечения. =)
Ну тогда, с учетом имеющегося опыта, может быть сделаешь это с отражением в форуме?
Просто интересно - сейчас ты наверняка напишешь не так как давно...

Или, если хочешь, - изложи общую концепцию компактно... ПисАть-то мы все научились...
Может кто ещё в проект подключится. :wink:
Да там излагать-то, собственно, нечего. Там надо просто писать код.

Code: Select all

struct task {
    struct task *next, *prev; /* циклический список */
    void *sp; /* указатель стека хранится здесь */
    unsigned char stack[1024];
};
Заводим глобальную переменную:

Code: Select all

struct task *current_task;
Ну и, что-то типа:

Code: Select all

timer_interrupt:
	pusha
	mov	bx, current_task
	mov	[bx+4], sp	; сохраним указатель стека
	mov	bx, [bx]	; bx = bx->next
	mov	current_task, bx
	mov	sp, [bx+4]	; меняем стек
	popa			; восстанавливаем регистры
	iret			; возвращаем управление
Думаю так. В упор не помню, надо ли там делать cli/sti, или это уже сделано за нас. И не совсем я уверен, в синтаксисе -- давно не сталкивался с x86 в intel-синтаксисе.
Создание нового процесса:

Code: Select all

void new_task(void (*func)())
{
	int i;
	struct task *new = malloc(sizeof(*new));
	struct {
		/* AFAIR, pusha кладёт регистры в таком порядке: */
		int di, si, sp, bp, bx, cx, dx, ax;
		/* для iret нужен сегментный адрес: */
		int ip, cs, flags;
		/* и в хвосте, адрес возврата, чтоб задача могла бы
		   завершиться выполнив команду ret */
		void (*ret)();
	} *stk_frame;
	new->sp = stk_frame = &new->stack[1024 - sizeof(*stk_frame)];
	memset(stk_frame, 0, sizeof(*stk_frame));
	stk_frame->ip = func;
	stk_frame->cs = get_CS();
	stk_frame->sp = &new->stack[1024-2]; /* по-моему, pusha бы положило именно
					 * такое значение */
	stk_frame->ret = finish_task;
	new->sp = &new->stack[1024];
	/* осталось вставить новую структуру в список: */
	cli();
	new->next = current_task->next;
	new->prev = current_task;
	current_task->next->prev = new;
	current_task->prev->next = new;
	sti()
}
Ещё интересная функция -- finish_task, указатель на которую используется выше. Мой сегодняшний опыт подсказывает мне, что освобождать память занимаемую задачей надо из контекста другой задачи. Может быть из контекста диспетчера задач (в нашей ситуации обработчика прерываний таймера). Но не стоит делать этого из самой задачи. Но я всё же поступлю наперекор опыту, поскольку иначе придётся привязывать к каждой задаче состояние, коих должно быть как минимум два: TASK_ALIVE и TASK_DEAD.
По идее мой "неправильный" подход должен сработать, я просто не очень уверен насчёт флага прерываний: сбрасывается ли он по IRET или нет. По-моему, iret восстанавливает из стека все флаги, в том числе и тот, что ответственнен за прерывания.

Code: Select all

void finish_task()
{
	/* Удалим текущую задачу из списка: */
	cli();
	current_task->prev->next = current_task->next;
	current_task->next->prev = current_task->prev;
	free(current_task);
	current_task = current_task->next;
	/* Ну и: */
	asm(
		"mov	bx, current_task"
		"mov	sp, [bx+4]"
		"popa"
		"iret"
	);
};
Просто интересно - сейчас ты наверняка напишешь не так как давно...
Нну да, наверное. Смотря зачем буду писать. Можно же вообще взять, что-нибудь типа libpth и портировать в DOS. Ну или не в DOS, а в качестве замены ему. =)
Но я не планирую заниматься подобным.