8-900-374-94-44
[email protected]
Slide Image
Меню

Диспетчер система – Система мониторинга «Диспетчер» – мониторинг работы оборудования, станков с ЧПУ и автоматических линий

Диспетчер Система мониторинга промышленного оборудования и персонала

АИС «Диспетчер» — универсальная российская система мониторинга промышленного оборудования и персонала, которая позволяет контролировать работу любого оборудования и рабочих мест, обеспечивая объективными данные все системы управления предприятием.

2019: Интеграция с «Галактикой ЕАМ»

Корпорация «Галактика» и компания «Цифра» 25 марта 2019 года объявили о старте стратегического партнерства в области продвижения решений Индустрии 4.0 в отечественной промышленности. В рамках партнерства компании планируют осуществить бесшовную интеграцию цифровых решений для производственных предприятий и осуществлять их совместное продвижение в рамках единого стека. Подробнее здесь.

Интеграция систем «Галактика ЕАМ» и «Диспетчер» позволит повысить надежность работы оборудования: автоматизировать контроль наработки, получаемой в режиме реального времени, планировать ТОиР на основе оперативной информации о техническом состоянии станочного парка, объективно оценивать остаточный ресурс, выявлять причину выхода оборудования из строя и предупреждать поломки оборудования, — считает Александр Бургардт, вице-президент корпорации «Галактика», руководитель дирекции ЕАМ.

2017: Возможности АИС «Диспетчер»

(Данные актуальны на ноябрь 2017 года)

Мониторинг производства

  • Контроль использования и загрузка оборудования
  • Оценка производственные потерь, в том числе рабочего времени
  • Автоматизация процесса непрерывного контроля производства

Оптимизация производства

  • Определение узких мест технологической цепочки
  • Оптимизация технологических процессов
  • Сокращение выпуска бракованной продукции
  • Оптимизация графика работы

Управление простоями

  • Сокращение продолжительности внеплановых простоев
  • Оптимальное планирование и проведение работ по техобслуживанию
  • Учет и использование типовых ремонтных случаев
  • Прогнозирование использования запчастей и расходных материалов

Цифровизация производства

  • Подключение всех рабочих мест в локальную сеть
  • Отказ от «бумажного» документооборота
  • Объединение производственных систем в единое информационное пространство
  • Контроль всего жизненного цикла изделия

www.tadviser.ru

ИАС Диспетчер установка и работа в системе

ИАС «Диспетчер ЖКХ» — программа предназначена для автоматизации работы диспетчерской службы ЖКХ в области приема заявок от населения на любые виды работ и контроля их выполнения. Автоматизация диспетчерского пункта ЖКХ, созданного при УК, ТСЖ, ЖЭУ, РЭУ и других компаний, работающих в этой сфере. ИАС Диспетчер ЖКХ, позволяет вести журналы заявок в электронном виде, производить звукозапись телефонных разговоров, печатать наряды, отмечать выполнение заявок, а также формировать различные отчеты по поступившим заявкам. Если Вас заинтересовал наш программный продукт, напишите или позвоните нам, чтобы мы могли договорится о проведении удаленной презентации системы. Мы ответим на любые Ваши вопросы и покажем как наш программный продукт решает все задачи, связанные с данной сферой деятельности. телефон офиса +7 (4722) 78-14-07 [email protected] или [email protected] http://ciritas.ru Сейчас заканчивается разработка новой версии системы Диспетчер ЖКХ ОНЛАЙН Система полностью расположена в интернете, доступ к ней осуществляется через браузер. Теперь не требуется покупка оборудования или приложения, работать в системе возможно из любого браузера, где бы вы не находились. Система имеет гибкую структуру и позволяет организовать работу как собственного диспетчерского пункта в вашей УК, так и объединенного диспетчерского пункта, с приемом заявок в одном или в нескольких местах, с распределением заявок по УК, по исполнителям, по жилому фонду. Также предусматриватеся интеграция данной системы с ГИС ЖКХ. SaaS система Диспетчер ЖКХ имеет большой ряд преимуществ по сравнению с обычной десктопной версией. Если вам инетерсна данная система, вы можете оставить ваш емеил на сайте системы, и мы обязательно вас уведомим о ее запуске. Сайт системы расположен по адресу http://gkh.city Всем подписавшимся на уведомление о запуске системы на нашем сайте, будет БЕСПЛАТНО предоставлен доступ на срок 6 месяцев. Преимущества нашего программного продукта: — Программа работает более 15 лет. — САМАЯ низкая цена на рынке. — Полностью соответствует законодательству РФ. — Встроенный редактор отчетных форм. — Более 50 готовых базовых отчетных форм. — Постоянно поддерживается и развивается. — Проста и недорога в обслуживании и поддержке. Функционал системы позволяет производить: — Массовый ввод данных — Импорт данных — Прием заявок — Импорт заявок — Автоматизация обратной связи — Звукозапись разговора — Печать нарядов — Обработка нарядов — Просмотр долгов — Отметка материалов — Отображение на карте — Формирование отчетов ТЭГИ: ИАС Диспетчер, ИАС Диспетчер ЖКХ, Диспетчер ЖКХ, купить Диспетчер ЖКХ, диспетчерская ЖКХ, прием заявок, печать нарядов, плановые работы, аварийные работы, услуги ЖКХ, жилищно-коммунальное хозяйство

rutube.ru

Как открыть диспетчер устройств

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

Содержание

• Что такое диспетчер устройств Windows; • Как открыть диспетчер устройств Windows; • Настройка компьютера при помощи диспетчера.

Что такое диспетчер устройств Windows


Диспетчер устройств Windows – это встроенная в Windows утилита, выполняющая функции своеобразного «пункта управлении» устройствами, входящими в состав компьютера. Она присутствует во всех версиях Windows и внешне представляет собой список устройств (см. изображение ниже). Диспетчер устройств позволяет получить информацию о названии и некоторых характеристиках центрального процессора, видеокарты, звуковой карты, сетевого адаптера, жестких дисков и других устройств компьютера, проконтролировать состояние их использования, узнать о возможных проблемах в их работе, обновить для них программное обеспечение (драйверы), и даже временно отключить некоторые из них. Устройства в диспетчере систематизированы по разделам. Чтобы открыть какой-то раздел, достаточно дважды щелкнуть по нему левой кнопкой мышки.


Как открыть диспетчер устройств Windows


Существует несколько способов открыть диспетчер устройств Windows: Универсальный способ (работает во всех версиях Windows): • на клавиатуре нажать кнопку Win (обозначена логотипом Windows, находится в левом ближнем углу клавиатуры между кнопками Ctrl и Alt) и, не отпуская ее, один раз нажать кнопку R (в русской раскладке К). После этого кнопку Win отпустить; • в появившемся окне напечатать или скопировать с этой страницы слово devmgmt.msc • нажать «Enter».

Способ для Windows XP: • щелкнуть по значку «Мой компьютер», находящемуся на рабочем столе или в меню «Пуск», и в открывшемся контекстном меню выбрать пункт «Свойства»; • в появившемся окне перейти на вкладку «Оборудование» и нажать на кнопку «Диспетчер устройств».

Способ для Windows Vista, Windows 7, Windows 8
:
• щелкнуть правой кнопкой мышки по значку «Компьютер» («Этот компьютер»), находящемуся на рабочем столе или в меню «Пуск», в появившемся контекстном меню выбрать пункт «Свойства»; • в левом верхнем углу открывшегося окна щелкнуть по пункту «Диспетчер устройств»

Еще один способ для Windows 8: щелкнуть правой кнопкой мышки по кнопке меню «Пуск» (в левом нижнем углу экрана) и в появившемся контекстном меню выбрать пункт «Диспетчер устройств»


Настройка устройств компьютера при помощи Диспетчера


Диспетчер устройств Windows позволяет решать следующие основные задачи:1. Получить информацию о любом устройстве компьютера. Достаточно открыть раздел, к которому это устройство принадлежит. Например, чтобы узнать название видеокарты компьютера, нужно открыть раздел Диспетчера с названием «Видеоадаптеры», дважды щелкнув по нему левой кнопкой мышки. Чтобы получить более подробную информацию об устройстве, необходимо один раз щелкнуть по нему правой кнопкой мышки и в контекстном меню выбрать пункт «Свойства»;
2
. Получить информацию о наличии проблем в работе устройств. Обычно, «проблемные» устройства в Диспетчере обозначены специальными значками (красный крестик, знак вопроса, восклицательный знак и др.) и их видно сразу же после открытия Диспетчера;3. Установить драйвер устройства. Для установки драйвера устройства необходимо щелкнуть по нему правой кнопкой мышки и выбрать пункт «Обновить драйверы…», после чего указать путь к папке с файлами драйверов. Подробнее о том, что такое драйвер и как его установить, читайте здесь;4. Переустановить драйвер устройства. Бывает, что определенные устройства компьютера перестают правильно работать (например, при неполадках звуковой карты пропадает звук). Часто такие проблемы решаются переустановкой драйвера. Необходимо в диспетчере устройств щелкнуть правой кнопкой мышки по проблемному устройству (в нашем примере звуковая карта) и выбрать пункт «Удалить». После того, как устройство исчезнет из списка, в меню Диспетчера щелкнуть по разделу «Действие» и выбрать пункт «Обновить конфигурацию оборудования»;

5. Отключить устройство. Необходимо щелкнуть по устройству правой кнопкой мышки и выбрать пункт «Отключить». В любой момент отключенное устройство можно включить, щелкнув по нему правой кнопкой мышки в Диспетчере устройств и выбрав пункт «Задействовать». Отключать временно не используемые устройства целесообразно, например, в ноутбуках. Это уменьшает расход заряда батареи.

www.chaynikam.info

AVR. Учебный курс. Операционная система. Диспетчер задач.

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

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

Общая диаграмма работы ОС

Что из себя представляет задача
Это практически то же самое, что и процедура, вызываемая командой RCALL с тремя отличиями:

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

Сама задача представляет собой обычную процедуру, записанную без каких либо замудреностей.

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

В тестовом примере это выглядит так:

Расположение: Trash-rtos.asm — главный файл программы

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
;=========================================================
;Tasks		
;=========================================================
Idle:		RET	; Задача пустого цикла, но ничего
			; не мешает сунуть сюда любой код.
			; Он будет выполнен. В последнюю очередь.
;-------------------------------------------------------
Fire:		LDS	OSRG,U_B	; Это код задачи "Fire"
		OUTI	UDR,'A'		; Выдрано из реального проекта
					; Суть данного кода не важна
		CBI	PORTD,7		; Поэтому можешь не вникать. Тут
		NOP			; Может быть абсолютно любой
		NOP			; код -- код твоей задачи!
		SBI	PORTD,7
					; Если любопытно, то тут обычное
		LDS	Counter,PovCT	; заполнение сдвигового регистра
		LDPA	Lines		; из трех микросхем 74HC164
					; средствами SPI передатчика
		CLR	OSRG		; Оставил его лишь для примера.
					; Чтобы наглядно показать, что 
		ADD	ZL,Counter	; Из себя представляет задача.
		ADC	ZH,OSRG
 
		LPM	OSRG,Z+
		OUT	SPDR,OSRG
 
Wait0:      	SBIS    SPSR,SPIF
            		RJMP    Wait0
 
		INC	Counter
 
		CPI	Counter,150
		BRSH	Clear
 
		STS	PovCT,Counter
		RET	
 
Clear:		CLR	Counter
		STS	PovCT,Counter 
		RET			; Выход из задачи только по RET!!!
;-------------------------------------------------------
Task2:		RET			; Это пустые заглушки. На этом месте
					; могла бы быть ваша задача! :)
;-------------------------------------------------------
Task3:		RET			; Аналогично, надо будет задействую.
;-------------------------------------------------------
Task4:		RET			; Названия в стиле Task4 тоже живут 
					; недолго. Обычно переименовываю
;-------------------------------------------------------
Task5:		RET			; Как с задачей "Fire"
;-------------------------------------------------------
Task6:		RET
;-------------------------------------------------------
Task7:		RET
;-------------------------------------------------------
Task8:		RET
;-------------------------------------------------------
Task9:		RET

;========================================================= ;Tasks ;========================================================= Idle: RET ; Задача пустого цикла, но ничего ; не мешает сунуть сюда любой код. ; Он будет выполнен. В последнюю очередь. ;——————————————————- Fire: LDS OSRG,U_B ; Это код задачи «Fire» OUTI UDR,’A’ ; Выдрано из реального проекта ; Суть данного кода не важна CBI PORTD,7 ; Поэтому можешь не вникать. Тут NOP ; Может быть абсолютно любой NOP ; код — код твоей задачи! SBI PORTD,7 ; Если любопытно, то тут обычное LDS Counter,PovCT ; заполнение сдвигового регистра LDPA Lines ; из трех микросхем 74HC164 ; средствами SPI передатчика CLR OSRG ; Оставил его лишь для примера. ; Чтобы наглядно показать, что ADD ZL,Counter ; Из себя представляет задача. ADC ZH,OSRG LPM OSRG,Z+ OUT SPDR,OSRG Wait0: SBIS SPSR,SPIF RJMP Wait0 INC Counter CPI Counter,150 BRSH Clear STS PovCT,Counter RET Clear: CLR Counter STS PovCT,Counter RET ; Выход из задачи только по RET!!! ;——————————————————- Task2: RET ; Это пустые заглушки. На этом месте ; могла бы быть ваша задача! :) ;——————————————————- Task3: RET ; Аналогично, надо будет задействую. ;——————————————————- Task4: RET ; Названия в стиле Task4 тоже живут ; недолго. Обычно переименовываю ;——————————————————- Task5: RET ; Как с задачей «Fire» ;——————————————————- Task6: RET ;——————————————————- Task7: RET ;——————————————————- Task8: RET ;——————————————————- Task9: RET

Таблица переходов
После всего кода задач распологается таблица переходов и код самой ОС:

Расположение: Trash-rtos.asm — главный файл программы, в самом низу, в конце ПЗУ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
;========================================================================
; RTOS Here
;========================================================================
		.include "kerneldef.asm"	; Настройки ядра - переменные и ряд макросов.
		.include "kernel.asm"		; Подклчюаем ядро ОС.
				;Это таблица переходов.
TaskProcs: 	.dw Idle		; [00]  Она содержит в себе реальные адреса задач
		.dw Fire		; [01] Как видишь, 0 тут у задачи пустого цикла,  
		.dw Task2		; [02] 01 у "Fire", ну и дальше	  
		.dw Task3		; [03] По порядку.
		.dw Task4 		; [04] 	
		.dw Task5		; [05] 
		.dw Task6		; [06] 
		.dw Task7		; [07] 
		.dw Task8		; [08]
		.dw Task9		; [09]

;======================================================================== ; RTOS Here ;======================================================================== .include «kerneldef.asm» ; Настройки ядра — переменные и ряд макросов. .include «kernel.asm» ; Подклчюаем ядро ОС. ;Это таблица переходов. TaskProcs: .dw Idle ; [00] Она содержит в себе реальные адреса задач .dw Fire ; [01] Как видишь, 0 тут у задачи пустого цикла, .dw Task2 ; [02] 01 у «Fire», ну и дальше .dw Task3 ; [03] По порядку. .dw Task4 ; [04] .dw Task5 ; [05] .dw Task6 ; [06] .dw Task7 ; [07] .dw Task8 ; [08] .dw Task9 ; [09]

Причем, в таблице задач не обязательно должны быть разные задачи. Можно делать одну, но на разные ячейки, например так:

1
2
3
4
5
6
7
8
9
10
TaskProcs: 	.dw Idle		; [00] 	
		.dw Fire		; [01] 	
		.dw Task2		; [02] 
		.dw Task3		; [03]  
		.dw Task4 		; [04] 	
		.dw Fire		; [05] 
		.dw Task6		; [06] 
		.dw Idle		; [07] 
		.dw Idle		; [08]
		.dw Task9		; [09]

TaskProcs: .dw Idle ; [00] .dw Fire ; [01] .dw Task2 ; [02] .dw Task3 ; [03] .dw Task4 ; [04] .dw Fire ; [05] .dw Task6 ; [06] .dw Idle ; [07] .dw Idle ; [08] .dw Task9 ; [09]

Это иногда бывает удобно.
Таблица переходов нужна для того, чтобы можно было любому адресу в программе дать адрес-смещение относительно начала таблицы перехода. То есть, теперь, чтобы перейти на Task4 нам не нужно знать точный адрес этой задачи, достаточно лишь знать, что ее адрес записан в таблице переходов в четвертой ячейке. Адрес начала таблицы переходов у нас фиксированный, поэтому просто прибавляем к нему смещение (равное номеру задачи*2) и берем оттуда искомый адрес. Благодаря этому, мы можем в очереди задач держать не двубайтные адреса переходов, а однобайтные номера под которыми эти адреса размещены в таблице.

А чтобы не путаться под каким номером какая задача спрятана, то введем для них символическое обозначение:
Расположение: kerneldef.asm — файл макроопределений ядра

1
2
3
4
5
6
7
8
9
10
.equ TS_Idle 	= 0 	; Просто нумерация. Не более того
.equ TS_Fire	= 1 	; Зато теперь можно смело отправлять в очередь 
.equ TS_Task2 	= 2 	; задачу с именем TS_Fire и не париться на счет того,
.equ TS_Task3	= 3 	; что запишется что то не то. 
.equ TS_Task4	= 4	; Тут все по порядку, жестко привязано к ячейкам таблицы!
.equ TS_Task5	= 5	; Так что если в таблице и можно делать одинаковые задачи,
.equ TS_Task6	= 6 	; то тут у них идентификаторы должны быть разные!!!
.equ TS_Task7	= 7	; А имена можно придумывать любые, они не привязаны ни к чему,
.equ TS_Task8 	= 8	; Главное самому не забыть что где. 
.equ TS_Task9	= 9

.equ TS_Idle = 0 ; Просто нумерация. Не более того .equ TS_Fire = 1 ; Зато теперь можно смело отправлять в очередь .equ TS_Task2 = 2 ; задачу с именем TS_Fire и не париться на счет того, .equ TS_Task3 = 3 ; что запишется что то не то. .equ TS_Task4 = 4 ; Тут все по порядку, жестко привязано к ячейкам таблицы! .equ TS_Task5 = 5 ; Так что если в таблице и можно делать одинаковые задачи, .equ TS_Task6 = 6 ; то тут у них идентификаторы должны быть разные!!! .equ TS_Task7 = 7 ; А имена можно придумывать любые, они не привязаны ни к чему, .equ TS_Task8 = 8 ; Главное самому не забыть что где. .equ TS_Task9 = 9

Очередь задач.
Логически выглядит как строка в памяти, где каждый байт это номер задачи. Два числа 0 и FF зарезервированы системой. 0 — это Idle, холостой цикл диспетчера. FF — нет задачи, конец очереди.

В коде это выглядит так:
Расположение: Trash-rtos.asm — главный файл программы, самое начало. Где идет разметка ОЗУ

1
2
3
		.DSEG
		.equ TaskQueueSize 	= 11		; Длина очереди задач
TaskQueue: 	.byte			TaskQueueSize 	; Адрес очереди сотытий в SRAM

.DSEG .equ TaskQueueSize = 11 ; Длина очереди задач TaskQueue: .byte TaskQueueSize ; Адрес очереди сотытий в SRAM

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

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

Главный цикл программы при этом выглядит следующим образом:
Расположение: Trash-rtos.asm — главный файл программы

1
2
3
4
5
Main:		SEI					; Разрешаем прерывания.
		WDR 					; Reset Watch DOG 
		RCALL 	ProcessTaskQueue		; Обработка очереди процессов (Диспетчер)
		RCALL 	Idle				; Простой Ядра
		RJMP 	Main

Main: SEI ; Разрешаем прерывания. WDR ; Reset Watch DOG RCALL ProcessTaskQueue ; Обработка очереди процессов (Диспетчер) RCALL Idle ; Простой Ядра RJMP Main

Сам обработчик очереди несложен. Распологается в файле kernel.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
ProcessTaskQueue:
		ldi 	ZL, low(TaskQueue)	; Берем адрес начала очереди задач
		ldi 	ZH, high(TaskQueue)	; Напомню, что это в ОЗУ.
 
		ld 	OSRG, Z		; Берем первый байт (OSRG = R17 рабочий
		cpi 	OSRG, $FF	; регистр OS) Сравниваем с FF
		breq	 PTQL02		; Равно? Значит очередь пуста - выход.
 
		clr 	ZH		; Сбрасываем старший байт
		lsl 	OSRG		; А взятый номер задачи умножаем на 2
		mov 	ZL, OSRG	; Так как адреса у нас двубайтные, а значит
					; И ячейки в таблице перехода двубайтные
						; Получается смещение по таблице
 
		subi 	ZL, low(-TaskProcs*2)	; Прибавляем получившееся смещение к адресу
		sbci 	ZH, high(-TaskProcs*2) 	; начала таблицы переходов. Ну и что, что AVR
						; не умеет
						; складывать регистр с числом + перенос. 
					; Зато умеет вычитать, а минус на минус дают плюс! :) 
					; Математика царица всех наук! 
					; Теперь в Z у нас адрес где лежит адрес перехода. 
 
		lpm			; Берем этот адрес! Сначала в R0
		mov 	OSRG, r0	; Потом в OSRG
		ld 	r0, Z+		; Эта команда ничего ценного на грузит, мы ее применили
					; Ради "Z+" чтобы увеличить адрес в Z и взять второй байт
					; Целевого адреса по которому мы перейдем. 
		lpm			; Берем в R0 второй байт адреса.
 
		mov 	ZL, OSRG	; А из OSRG перекладываем в ZL
		mov 	ZH, r0		; И из R0 в ZH. Теперь у нас в Z полный адрес перехода.
					; Можно драпать, в смысле IJMP - индексный переход по Z
					; Но пока рано! Надо же еще очередь в порядок привести!
		push 	ZL		; Спрячем наш адрес, наше сокровище, в стек...
		push 	ZH		; Глубоко зароем нашу прелесссть.... 
 
						; Займемся грязной работой. Продвинем очередь.
		ldi 	Counter, TaskQueueSize-1; Загрузим длинну очереди. Иначе мы всю память
		ldi 	ZL, low(TaskQueue)	; подвинем. И хапнем в Z начало очереди. 
		ldi 	ZH, high(TaskQueue)
 
		cli			; Запретим прерывания. А то если очередь сорвет получим
					; армагедец. 
 
PTQL01:		ldd 	OSRG, Z+1 	; Грузим из следующего Z+1 байта и перекладываем 
		st 	Z+, OSRG	; все в Z, а Z после этого увеличиваем на 1
		dec 	Counter		; Уменьшаем счетчик (там длинна очереди!)
		brne 	PTQL01		; Если не конец, то в цикле.
		ldi 	OSRG, $FF	; А если конец, то по последнему адресу записываем FF
		st 	Z+, OSRG	; Который является признаком конца очереди. 
 
		sei			; Разрешаем прерывания. Можно расслабиться
 
		pop 	ZH		; Достаем из стека нашу прелессть... наш адрес перехода
		pop 	ZL		; Оба байта, старший и младший. 
 
		ijmp 	; Переходим в задачу!!!
			; Обрати внимание - сюда мы пришли по RCALL из главного цикла
			; Значит в стеке у нас лежит адрес возврата. А ушли мы в задачу по IJMP 
			; который стек не меняет. Но это не страшно! Ведь из задачи мы 
			; выходим по RET!
PTQL02:		ret

ProcessTaskQueue: ldi ZL, low(TaskQueue) ; Берем адрес начала очереди задач ldi ZH, high(TaskQueue) ; Напомню, что это в ОЗУ. ld OSRG, Z ; Берем первый байт (OSRG = R17 рабочий cpi OSRG, $FF ; регистр OS) Сравниваем с FF breq PTQL02 ; Равно? Значит очередь пуста — выход. clr ZH ; Сбрасываем старший байт lsl OSRG ; А взятый номер задачи умножаем на 2 mov ZL, OSRG ; Так как адреса у нас двубайтные, а значит ; И ячейки в таблице перехода двубайтные ; Получается смещение по таблице subi ZL, low(-TaskProcs*2) ; Прибавляем получившееся смещение к адресу sbci ZH, high(-TaskProcs*2) ; начала таблицы переходов. Ну и что, что AVR ; не умеет ; складывать регистр с числом + перенос. ; Зато умеет вычитать, а минус на минус дают плюс! 🙂 ; Математика царица всех наук! ; Теперь в Z у нас адрес где лежит адрес перехода. lpm ; Берем этот адрес! Сначала в R0 mov OSRG, r0 ; Потом в OSRG ld r0, Z+ ; Эта команда ничего ценного на грузит, мы ее применили ; Ради «Z+» чтобы увеличить адрес в Z и взять второй байт ; Целевого адреса по которому мы перейдем. lpm ; Берем в R0 второй байт адреса. mov ZL, OSRG ; А из OSRG перекладываем в ZL mov ZH, r0 ; И из R0 в ZH. Теперь у нас в Z полный адрес перехода. ; Можно драпать, в смысле IJMP — индексный переход по Z ; Но пока рано! Надо же еще очередь в порядок привести! push ZL ; Спрячем наш адрес, наше сокровище, в стек… push ZH ; Глубоко зароем нашу прелесссть…. ; Займемся грязной работой. Продвинем очередь. ldi Counter, TaskQueueSize-1; Загрузим длинну очереди. Иначе мы всю память ldi ZL, low(TaskQueue) ; подвинем. И хапнем в Z начало очереди. ldi ZH, high(TaskQueue) cli ; Запретим прерывания. А то если очередь сорвет получим ; армагедец. PTQL01: ldd OSRG, Z+1 ; Грузим из следующего Z+1 байта и перекладываем st Z+, OSRG ; все в Z, а Z после этого увеличиваем на 1 dec Counter ; Уменьшаем счетчик (там длинна очереди!) brne PTQL01 ; Если не конец, то в цикле. ldi OSRG, $FF ; А если конец, то по последнему адресу записываем FF st Z+, OSRG ; Который является признаком конца очереди. sei ; Разрешаем прерывания. Можно расслабиться pop ZH ; Достаем из стека нашу прелессть… наш адрес перехода pop ZL ; Оба байта, старший и младший. ijmp ; Переходим в задачу!!! ; Обрати внимание — сюда мы пришли по RCALL из главного цикла ; Значит в стеке у нас лежит адрес возврата. А ушли мы в задачу по IJMP ; который стек не меняет. Но это не страшно! Ведь из задачи мы ; выходим по RET! PTQL02: ret

Для большей понятности нарисовал диаграммку со стрелочками разными, про то как формируется адрес в таблице переходов:

Задачи кладутся в очередь другой процедурой:

1
2
		ldi 	OSRG, TS_Task4		; Запускаем в очередь задачу Task4
		rcall 	SendTask

ldi OSRG, TS_Task4 ; Запускаем в очередь задачу Task4 rcall SendTask

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

Сама процедура SendTask работает тоже несложно, она всего лишь ставит задачу в очередь.
Расположение: kernel.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
; OSRG - Event				; В рабочем регистре ОС - номер задачи
SendTask:	push 	ZL		; Сохраняем все что используется
		push 	ZH		; в стеке
		push 	Tmp2
		push 	Counter
 
		in	Tmp2,SREG	; Сохраняем значение флагов
		push	Tmp2
 
		ldi 	ZL, low(TaskQueue)	; Грузим в Z адрес очереди задач.
		ldi 	ZH, high(TaskQueue)	
 
		ldi 	Counter, TaskQueueSize	; А в счетчик длинну очереди, чтобы 
						; не начать всю память засаживать.
 
 
		cli				; запрещаем прерывания.
 
SEQL01: 	ld 	Tmp2, Z+		; Грузим в темп байт из очереди
 
		cpi 	Tmp2, $FF	; и ищем ближайшее пустое место = FF
		breq 	SEQL02		; Если нашли, то переходим на сохранение
 
		dec 	Counter		; Либо конец очереди по счетчику. 
		breq 	SEQL03		
		rjmp 	SEQL01
 
SEQL02: 	st -Z, 	OSRG		; Нашли? Сохраняем в очереди номер задачи. 
 
SEQL03:	pop Tmp2		; Возвращаем флаги. Если там прерывание было 
		out SREG,Tmp2		; разрешено, то оно вернется в это значение. 
 
		pop Counter		; Выходим, достав все заныченное.
		pop Tmp2
		pop ZH
		pop ZL
		ret

; OSRG — Event ; В рабочем регистре ОС — номер задачи SendTask: push ZL ; Сохраняем все что используется push ZH ; в стеке push Tmp2 push Counter in Tmp2,SREG ; Сохраняем значение флагов push Tmp2 ldi ZL, low(TaskQueue) ; Грузим в Z адрес очереди задач. ldi ZH, high(TaskQueue) ldi Counter, TaskQueueSize ; А в счетчик длинну очереди, чтобы ; не начать всю память засаживать. cli ; запрещаем прерывания. SEQL01: ld Tmp2, Z+ ; Грузим в темп байт из очереди cpi Tmp2, $FF ; и ищем ближайшее пустое место = FF breq SEQL02 ; Если нашли, то переходим на сохранение dec Counter ; Либо конец очереди по счетчику. breq SEQL03 rjmp SEQL01 SEQL02: st -Z, OSRG ; Нашли? Сохраняем в очереди номер задачи. SEQL03: pop Tmp2 ; Возвращаем флаги. Если там прерывание было out SREG,Tmp2 ; разрешено, то оно вернется в это значение. pop Counter ; Выходим, достав все заныченное. pop Tmp2 pop ZH pop ZL ret

Архив с исходниками и работающим проектом для ATMega8

З.Ы.
Ухх, ну накатал телегу. Аж самому страшно. А там еще столько же, про таймерную службу, да пошаговые руководства по инсталляции и использованию… Но это после. Пока переварите это.

Продолжение следует…

easyelectronics.ru

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *