Subversion Repositories Kolibri OS

Rev

Rev 7136 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7136 Rev 7587
Line 1... Line 1...
1
Дата последней правки 26/07/2013.
1
Last edit: 26/07/2013
-
 
2
 
2
Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра.
3
Kernel event subsystem may be useful when writing drivers and kernel space
3
Она не имеет отношения к подсистеме событий пользовательского интерфейса.
4
services. It is not related to the subsystem of GUI events. An event, from the
4
С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.
5
kernel's point of view, is a kernel space object which is owned by the thread
-
 
6
that created it.
Line 5... Line 7...
5
 
7
 
6
struc EVENT
8
struc EVENT
7
{
9
{
8
   .magic       dd ?    ; 'EVNT'
10
   .magic       dd ?    ; 'EVNT'
9
   .destroy     dd ?    ; internal destructor
11
   .destroy     dd ?    ; internal destructor
10
   .fd          dd ?    ; next object in list
12
   .fd          dd ?    ; next object in list
11
   .bk          dd ?    ; prev object in list
13
   .bk          dd ?    ; prev object in list
12
   .pid         dd ?    ; owner id. идентификатор владельца (потока)
14
   .pid         dd ?    ; owner (thread) id
13
   .id          dd ?    ; event uid. уникальный идентификатор события (просто номерок)
15
   .id          dd ?    ; event uid. (just a number)
14
   .state       dd ?    ; internal flags; см. далее.
16
   .state       dd ?    ; internal flags; see below
15
   .code        dd ?    ; старший байт класс события, ; следующий байт приоритет 
17
   .code        dd ?    ; MSB: event class; next byte: priority
16
                        ; (будет использоваться только внутри ядра, при чтении всегда 0),
18
                        ; (used by kernel only, always 0 for reading),
17
                        ; Чем больше численное значение двойного слова тем важнее событие.
19
                        ; The higher dword value the higher event priority.
18
                        ; два младших байта код события. 
20
                        ; Two LSBs: event code.
19
                rd 5    ; .data - точная структура этого поля не определена и зависит
-
 
20
                        ; от поля .code. (Здесь можно передавать какие-то свои данные,
21
                rd 5    ; .data: the structure of this field is not defined and
21
                        ; при необходимости :)
22
                        ; depends on .code field. (Pass any data you need here)
22
   .size     =  $ - .magic
23
   .size     =  $ - .magic
23
   .codesize =  $ - .code
24
   .codesize =  $ - .code
Line 24... Line 25...
24
}
25
}
25
 
26
 
26
События реального времени получили класс 0хFF. Пока определёны только:
27
Realtime events have class 0хFF. Currently defined:
27
EVENT.code= 				;(Используется в звуковой подсистеме).
28
EVENT.code=                             ; (Used in sound subsystem)
28
        RT_INP_EMPTY      = 0xFF000001
29
        RT_INP_EMPTY      = 0xFF000001
29
        RT_OUT_EMPTY      = 0xFF000002
30
        RT_OUT_EMPTY      = 0xFF000002
Line 30... Line 31...
30
        RT_INP_FULL       = 0xFF000003
31
        RT_INP_FULL       = 0xFF000003
31
        RT_OUT_FULL       = 0xFF000004
32
        RT_OUT_FULL       = 0xFF000004
32
 
33
 
-
 
34
 
33
 
35
Flags of EVENT.state field are defined in gui/event.inc.
-
 
36
        EVENT_SIGNALED   = 0x20000000 ; bit 29: event is active/inactive
34
Флаги поля EVENT.state определены в gui/event.inc.
37
        EVENT_WATCHED    = 0x10000000 ; bit 28: owner thread is waiting for the
-
 
38
                                      ;         event to be active
Line 35... Line 39...
35
	EVENT_SIGNALED   = 0x20000000 ;бит 29  событие активно/неактивно;
39
        MANUAL_RESET     = 0x40000000 ; bit 30: do not deactivate event
36
	EVENT_WATCHED    = 0x10000000 ;бит 28, поток-владелец ожидает активации события;
40
                                      :         automatically on receive
Line 37... Line 41...
37
	MANUAL_RESET     = 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
41
        MANUAL_DESTROY   = 0x80000000 ; bit 31: do not return event to a list of
38
	MANUAL_DESTROY   = 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.
42
                                      ;         free ones on receive
39
 
43
 
40
На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc
44
As of SVN r3732 (assume same below) the definition is located in
Line 53... Line 57...
53
        state           dd ?   ;internal flags
57
        state           dd ?    ; internal flags
54
        code            dd ?
58
        code            dd ?
55
                        rd 5   ; .data
59
                        rd 5    ; .data
56
ends
60
ends
Line 57... Line 61...
57
 
61
 
58
Код находится в gui/event.inc.
62
Code is located in gui/event.inc.
59
Сами события как обьекты существуют в памяти ядра в виде двусвязного списка (см. поля .bk и .fd).
63
Event objects live in kernel memory as a double-linked list (see fields .bk and
60
При инициализации ядро резервирует память и создает 512 таких обьектов, помещая их в список FreeEvents
64
.fd). While initialization the kernel reserves memory, creates 512 events and
61
(свободных событий). При нехватке событий (все заняты, а нужно ещё) ядро создает ещё 512 свободных
65
places them into FreeEvents list. When out of free event, kernel creates another
-
 
66
512 ones etc. Each thread has own double-linked lists where an event may be
62
и т.д. Каждый поток имеет свои (двусвязные) списки (в которые может быть помещено событие):
67
placed to:
63
ObjList - список объектов ядра, ассоциированных с этим потоком; 
68
        ObjList -- a list of kernel objects associated with the thread;
64
EventList - список событий ядра для потока.
69
        EventList -- a list of kernel events for the thread.
65
Сами события, физически, при перемещении между списками и смене очередности в списке не перемещаются
70
When events are moved between lists or reordered their data are not copied. This
66
и не копируются. Это происходит только благодаря модификации полей .fd и .bk. Принцип работы списков,
71
is done only via modification of .fd and .bk fields. These lists work as FIFO
67
как очередей - FIFO. Использутся неблокирующая отправка и блокирующее получение. Адресация - прямая
72
queues. Sending does not block, receiving blocks. Addressing is direct, by
68
(у события всегда есть поток-владелец), по идентификатору потока. 
73
thread id. There always is an owner thread for an event.
69
 
74
 
70
Жизненый цикл событий определяется флагами при создании. По умолчанию ядро использует значения 
75
Event's life cycle is defined by flags while creation. By default the kernel
71
MANUAL_RESET = 0 и MANUAL_DESTROY = 0. Такое событие является "одноразовым", и автоматически освобождается 
76
uses values MANUAL_RESET = 0 and MANUAL_DESTROY = 0. Such an event is oneshot
72
ядром, возвращаясь в список свободных событий после получения.
77
and is automatically freed by the kernel and returned to the FreeEvents list
73
Событие с флагом MANUAL_DESTROY = 1 после получения переходит в неактивное состояние, но остаётся в списке 
78
when received. An event with flag MANUAL_DESTROY = 1 becomes inactive when
74
объектов потока и может использоваться снова. Событие с флагами MANUAL_DESTROY =1 и MANUAL_RESET = 1 
79
received but remains in thread's object list and can be reused. An event with
-
 
80
flags MANUAL_DESTROY = 1 and MANUAL_RESET = 1 remains active when received and
75
остаётся активным после получения и может быть сброшено вызовом ClearEvent.
81
can be reset via call to ClearEvent.
76
 
82
 
77
Пример (вариант) жизненного цикла события из звуковой подсистемы:
83
A life cycle example of a sound subsystem event:
-
 
84
 * For an audio buffer (possibly several) the driver creates an event in ObjList
78
Для зукового буфера (их может быть несколько) драйвер создает событие в списке ObjList с помощью
85
   by calling CreateEvent with flag MANUAL_DESTROY.
79
CreateEvent и флагом MANUAL_DESTROY. Далее драйвер вызывает WaitEvent для этого события (ожидает флага
86
 * Then driver calls WaitEvent for the event (waits for EVENT_SIGNALED event
80
EVENT_SIGNALED в событии) и блокируется, в ожидании запроса на пополнение буфера. Запрос отправляется
87
   flag) and blocks waiting for buffer update request.
81
с помощью RaiseEvent из другого потока. Отправка (RaiseEvent) и получение (WaitEvent) циклически 
88
 * The buffer update request is sent with RaiseEvent from another thread.
82
повторяются при опустошении буфера. При остановке воспроизведения драйвер деактивирует событие с помощью
89
 * Sending (RaiseEvent) and receiving (WaitEvent) are repeated as buffer gets
-
 
90
   empty.
83
ClearEvent.
91
 * Driver deactivates the event with ClearEvent when playback is stopped.
84
 
92
 
85
Вообще говоря, структура события приведена здесь только лишь для понимания принципов работы подсистемы.
93
Actually, the event structure is described here only for understanding of
86
Самостоятельная работа с полями не приветствуется, ввиду возможных в будущем проблем с совместимостью.
94
subsystem work principles. Direct field access is discouraged due to possible
87
Работа должна производится только через API (функции подсистемы), с доступом только к тем полям, доступ к
-
 
88
которым предоставляет функция. При этом пару "указатель на событие" и "уникальный идентификатор события"
95
compatibility issues in the future. Only API calls should be used. A pair
89
следует рассматривать как один 64-х битный уникальный идентификатор. (Если вы вызвали CreateEvent, напимер,
96
"pointer to an event" and "event id" is considered a single 64-bit id. This id
-
 
97
should be stored somewhere after a call to CreateEvent for further work with the
Line 90... Line 98...
90
его нужно запомнить где-нибудь [если это нужно] для дальнейшей работы с событием).
98
event.
91
 
99
 
Line 92... Line 100...
92
Функции для работы с событиями экспортитуемые ядром:
100
The kernel exports following event related functions:
93
(для драйверов и т.п.; вызываются в режиме ядра)
101
(for drivers, etc; called from kernel mode)
94
 
102
 
95
        CreateEvent
103
        CreateEvent
96
        RaiseEvent
104
        RaiseEvent
97
        ClearEvent
105
        ClearEvent
98
        SendEvent
106
        SendEvent
99
        DestroyEvent
107
        DestroyEvent
100
        WaitEvent
108
        WaitEvent
Line 101... Line 109...
101
        WaitEventTimeout
109
        WaitEventTimeout
102
        GetEvent
110
        GetEvent
103
        Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)
111
        For user applications sysfn 68.14 (a wrapper to GetEvent)
104
 
112
 
105
---------------------------------------------------------------------------------------------
113
--------------------------------------------------------------------------------
106
CreateEvent:
114
CreateEvent:
107
        Создаёт новое событие в очереди ObjList текущего потока. 
115
        Creates a new event in ObjList queue of current thread.
108
        Устанавливает:
116
        Sets:
109
                EVENT.destroy   <= внутренний деструктор по умолчанию;
117
                EVENT.destroy   <= default internal destructor
110
                EVENT.pid       <= текущий Process id;
118
                EVENT.pid       <= current Process id
111
                EVENT.id        <= уникальный идентификатор;
119
                EVENT.id        <= unique id
112
                EVENT.state     <= ecx - флаги;
120
                EVENT.state     <= ecx: flags
113
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
121
                EVENT.code      <= [esi]: size is 6*dword, do not copy if esi=0
114
        Возвращает:
122
        Returns:
115
                eax - указатель на событие или 0 при ошибке.
123
                eax -- pointer to the event or 0 for error.
116
                edx - Event.id.
124
                edx -- Event.id.
117
        Портит: eax,ebx,edx,ecx,esi,edi     
125
        Destroys: eax,ebx,edx,ecx,esi,edi
118
---------------------------------------------------------------------------------------------        
126
--------------------------------------------------------------------------------
119
RaiseEvent:
127
RaiseEvent:
120
        Активирует уже существующее событие (может принадлежать другому потоку) установкой 
128
        Activates existing event (may be owned by another thread) by setting
121
        флага EVENT_SIGNALED. Если необходимо, -  устанавливает данные EVENT.code.
129
        EVENT_SIGNALED flag. Sets EVENT.code data if necessary. Does nothing
-
 
130
        more if EVENT_SIGNALED flag is already active in the event. If
122
        Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает. 
131
        EVENT_SIGNALED flag is not set in the event it will be set, except when
123
        Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
-
 
124
                {EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
132
        EVENT_WATCHED in edx = 1 and EVENT_WATCHED in the event = 0. I.e. while
125
        Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации
133
        setting EVENT_WATCHED in edx it is checked if owner thread is waiting
126
        события.
134
        for event activation. No flags, except EVENT_SIGNALED, are modified in
127
        Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
135
        the event.
-
 
136
        Gets:
128
        Принимает:
137
                eax     -- pointer to event
129
                eax     - указатель на событие;
138
                ebx     -- id
130
                ebx     - id, уникальный идентификатор события;
139
                edx     -- flags (see EVENT.state)
131
                edx     - флаги для операции (формат EVENT.state);
140
        Sets:
132
                EVENT.code  <= [esi], (если esi=0, то не копирует), размер 6*dword;
141
                EVENT.code    <= [esi]: size is 6*dword, do not copy if esi=0
133
        Возвращает: ?
142
        Returns: ?
134
        Портит: eax,ebx,edx,ecx,esi,edi .
143
        Destroys: eax,ebx,edx,ecx,esi,edi
135
---------------------------------------------------------------------------------------------        
144
--------------------------------------------------------------------------------
136
ClearEvent:
145
ClearEvent:
137
        Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
146
        Move event to ObjList of owner thread. (May be it was already there.)
138
        Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),
147
        Reset flags EVENT_SIGNALED and EVENT_WATCHED, keep other fields (.code,
139
        ничего не делает.
148
        .id).
140
        Принимает:
149
        Gets:
141
                eax     - указатель на событие;
150
                eax     -- pointer to event
142
                ebx     - id, уникальный идентификатор события.
151
                ebx     -- id
143
        Возвращает: ?
152
        Returns: ?
144
        Портит: eax,ebx,ecx,edi .
153
        Destroys: eax,ebx,ecx,edi
145
---------------------------------------------------------------------------------------------        
154
--------------------------------------------------------------------------------
146
SendEvent:
155
SendEvent:
147
        Создаёт новое событие в списке событий целевого потока. Устанавливает в событии
156
        Create a new event in the event list of target thread. Sets
148
        флаг EVENT_SIGNALED.
157
        EVENT_SIGNALED flag in the event.
149
        Принимает:
158
        Gets:
150
                EVENT.pid       <= eax     - pid, идентификатор целевого потока;
159
                EVENT.pid       <= eax: target thread id;
151
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
160
                EVENT.code      <= [esi]: size is 6*dword, do not copy if esi=0
152
        Возвращает:
161
        Returns:
153
                eax - указатель на событие или 0 при ошибке.
162
                eax -- pointer to event or 0 for error
154
                edx - Event.id. уникальный идентификатор.
163
                edx -- Event.id
155
        Портит: eax,ebx,ecx,esi,edi .
164
        Destroys: eax,ebx,ecx,esi,edi
156
---------------------------------------------------------------------------------------------        
165
--------------------------------------------------------------------------------
157
DestroyEvent:
166
DestroyEvent:
158
        Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
167
        Moves event to FreeEvents, clears fields .magic, .destroy, .pid, .id.
159
        Событие может принадлежать другому потоку.
168
        The event may be owned by other thread.
160
        Принимает:
169
        Gets:
161
                eax     - указатель на событие;
170
                eax     -- pointer to event
162
                ebx     - id, уникальный идентификатор события.
171
                ebx     -- event id
163
        Возвращает:
172
        Returns:
164
                eax     - 0 при ошибке, не 0 при успехе.
173
                eax     -- 0 for error, non-zero for success
165
        Портит: eax,ebx,ecx .
174
        Destroy: eax,ebx,ecx
166
---------------------------------------------------------------------------------------------        
175
--------------------------------------------------------------------------------
167
WaitEvent:
176
WaitEvent:
168
        Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
177
        Wait infinitely until flag EVENT_SIGNALED is set in the event owned by
169
        вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
178
        the caller thread. This flag is set by signaling thread via RaiseEvent.
-
 
179
        Waiting thread is frozen by setting TASKDATA.state <= TSTATE_WAITING=5.
-
 
180
        Flag EVENT_WATCHED is set in the event before freeze.
170
        RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
181
        If flag MANUAL_RESET is NOT set in the event then:
171
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
182
                EVENT_SIGNALED and EVENT_WATCHED are reset when the event is
172
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
183
                received.
173
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
184
                When MANUAL_DESTROY is
174
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
185
                        inactive: the event is destroyed by DestroyEvent,
175
                 а при активном - перемещается в список ObjList текущего слота.}
186
                        active: the event is moved to ObjList of current thread.
176
        Принимает:
187
        Gets:
177
                eax     - указатель на событие;
188
                eax     -- pointer to event
178
                ebx     - id, уникальный идентификатор события.
189
                ebx     -- event id
179
        Возвращает: ?
190
        Returns: ?
180
        Портит: eax,ebx,edx,ecx,esi,edi .
191
        Destroys: eax,ebx,edx,ecx,esi,edi
181
---------------------------------------------------------------------------------------------                
192
--------------------------------------------------------------------------------
182
WaitEventTimeout:
193
WaitEventTimeout:
183
        Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
194
        Wait with a timeout until flag EVENT_SIGNALED is set in the event owned
184
        вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
195
        by caller thread. This flag is set by signaling thread via RaiseEvent.
-
 
196
        Waiting thread is frozen by setting TASKDATA.state <= TSTATE_WAITING=5.
-
 
197
        Flag EVENT_WATCHED is set in the event before freeze.
185
        RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
198
        If flag MANUAL_RESET is NOT set in the event then:
186
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
199
                EVENT_SIGNALED and EVENT_WATCHED are reset when the event is
187
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
200
                received.
188
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
201
                When MANUAL_DESTROY is
189
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
202
                        inactive: the event is destroyed by DestroyEvent,
190
                 а при активном - перемещается в список ObjList текущего слота.}
203
                        active: the event is moved to ObjList of current thread.
191
        Принимает:
204
        Gets:
192
                eax     - указатель на событие;
205
                eax     -- pointer to event
193
                ebx     - id, уникальный идентификатор события.
206
                ebx     -- event id
194
                ecx     - время ожидания в тиках системного таймера.
207
                ecx     -- timeout, in ticks of system timer
195
        Возвращает:
208
        Returns:
196
                eax     - 0 - таймаут, если событие не активировалось, или
209
                eax     -- 0 if the event was not activated, or
197
                          не 0, если было активировано.
210
                           not 0 if activated
198
        Портит: eax,ebx,edx,ecx,esi,edi .
211
        Destroys: eax,ebx,edx,ecx,esi,edi
199
---------------------------------------------------------------------------------------------        
212
--------------------------------------------------------------------------------
-
 
213
GetEvent:
200
GetEvent:
214
        Waits infinitely for any event in the queue of current thread. Thread is
201
        Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
215
        frozen by setting TASKDATA.state <= TSTATE_WAITING = 5. Event data
-
 
216
        (EVENT.code + 5*dword) are copied to specified buffer when received.
-
 
217
        Reset priority byte (see above) in the buffer.
202
        путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
218
        If flag MANUAL_RESET is NOT set in the event then:
203
        по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
219
                EVENT_SIGNALED and EVENT_WATCHED are reset when the event is
204
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
220
                received.
205
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
221
                When MANUAL_DESTROY is
206
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
222
                        inactive: the event is destroyed by DestroyEvent,
207
                 а при активном - перемещается в список ObjList текущего слота.}
223
                        active: the event is moved to ObjList of current thread.
208
        Принимает:
224
        Gets:
209
                edi     - указатель на буфер, куда копировать данные.
225
                edi     -- pointer to buffer to copy data
210
        Возвращает:
226
        Returns:
211
                буфер, содержащий следующую информацию:
227
                buffer with following data:
212
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
228
                +0: (EVENT.code) dword: id of following signal data
213
                +4: (EVENT.data, поле формально не определено) данные принятого 
229
                +4: (EVENT.data) 5*dword: signal data, format depends on
214
                сигнала (5*dword), формат которых определяется первым dword-ом.     
230
                    EVENT.code
215
        Портит: eax,ebx,edx,ecx,esi,edi .
231
        Destroys: eax,ebx,edx,ecx,esi,edi
216
--------------------------------------------------------------------------------------------
232
--------------------------------------------------------------------------------
-
 
233
SysFn 68.14 for application:    ; wrapped GetEvent
217
Ф 68.14 для приложений:         ;это тот же GetEvent, но с обёрткой.
234
        Waits infinitely for any event in the queue of current thread. Thread is
218
        Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
235
        frozen by setting TASKDATA.state <= TSTATE_WAITING = 5. Event data
219
        замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
236
        (EVENT.code + 5*dword) are copied to specified buffer when received.
220
        копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
237
        Reset priority byte (see above) in the buffer.
221
        Принимает:
238
        Gets:
222
                eax     - 68 - номер функции
239
                eax     -- 68: function number
223
                ebx     - 14 - номер подфункции
240
                ebx     -- 14: subfunction number
224
                ecx     - указатель на буфер для информации (размер 6*dword)
241
                ecx     -- pointer to data buffer (size is 6*dword)
225
        Возвращает:
242
        Returns:
226
                буфер, на который указывает ecx, содержит следующую информацию:
243
                ecx = buffer with following data:
227
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
244
                +0: (EVENT.code) dword: id of following signal data
228
                +4: (EVENT.data, поле формально не определено) данные принятого 
-