|
Data type: Программы
Updated: 15.06.2011 18:34
Библиотека для работы с контроллером CC02
Библиотека имеет простой интерфейс и возможность подключения пользовательских функций-обработчиков аппаратных прерываний. Предоставляет возможность анализировать любые сигналы в крейте КАМАК и выполнять любые команды на магистрали крейта предусмотренные стандартом ГОСТ 26.201-80.
Библиотека camlib является динамически загружаемой библиотекой Windows. Вся ее реализация находится в файле camac.dll, который является импортируемой библиотекой и может использоваться для статической компоновки с приложением. Определение типов и функций находится в файле camlib.h.
Файл camac.lib является импортируемой библиотекой и может использоваться для статической компоновки с приложением.Расположение файлов библиотеки:
Windows 2000/XP: |
System32 \ camac.dll |
|
System32 \ camac.lib |
Windows 9x/Me: |
System \ camac.dll |
|
System \ camac.lib |
В данной библиотеке определены следующие типы данных:
mod_name_camac - целое число, 32 бита. Переменная, в которой кодируется объект адресации (регистр). Формат переменной следующий:
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
x |
B |
x |
x |
x |
x |
C |
C |
N |
N |
N |
N |
N |
A |
A |
A |
x - зарезервированные (незначащие) разряды; B - определяет физическую разрядность адресуемого регистра (0 - 16 бит, 1 - 24 бита); C - разряды определяющие номер крейта; N - разряды определяющие номер станции; A - разряды определяющие субадрес регистра.
bool_camac - целая, беззнаковая величина, 8 бит. Определяет логический уровень. При значении 0 логический уровень - ложь, иначе - истина.
camac_L - беззнаковая, целая величина, 32 бита. Используется для хранения состояния шины прерываний L1-L24. Младшему биту соответствует значение сигнала L1, а биту 24 соответственно L24. Старшие 8 бит этого слова не используются.
camac_r - беззнаковое целое, 32 бита. Значение такого типа возвращает любая из функций библиотеки camlib.
void (*int_name_function) (void) - указатель на пользовательскую функцию, которая будет вызвана из драйвера при возникновении запроса на обслуживание. Таким образом значение переменной этого типа, использованное в качестве параметра для функции cclnk, будет являться указателем на пользовательский обработчик прерываний.
Также внутри библиотеки camlib определена структура CAM_DATA, которая содержит данные необходимые для взаимодействия с контроллером крейта. Получить доступ, к этой структуре для чтения данных можно с помощью функции cdata.
CAM_DATA *cdata(); - возвращает указатель на структуру CAM_DATA. Ниже приведена выдержка из файла camlib.h с описанием структуры CAM_DATA.
Листинг 1. Описание структуры CAM_DATA.
typedef struct { unsigned short ERRCODE; bool_camac X; bool_camac Q; bool_camac LAM; bool_camac I; camac_L L; bool_camac FH; bool_camac FL;
int R; int W; } CAM_DATA;
|
Описание полей стркутуры:
Таблица 1
ERRCODE |
Содержит код ошибки после выполнения любой функции. Значение 0 свидетельствует о отсутствии ошбок. |
X |
Состояние сигнала X: 1 - установлен, 0 - не установлен |
Q |
Состояние сигнала Q: 1 - установлен, 0 - не установлен |
LAM |
Индикатор наличия запроса на обслуживание. Содержит логическую сумму сигналов L1-L24. |
I |
Состояние сигнала Inhibit |
L |
Значение типа camac_L. Содержит информацию о состоянии шины прерываний L1-L24. |
FH |
Флаг подтверждения получения старшего байта данных (для 24 битного режима обмена) |
FL |
Флаг подтверждения получения младшего слова данных |
R |
Последние прочитанные данные |
W |
Данные которые были записаны последний раз |
Для работы с библиотекой необходимо один раз выполнить инициализацию, которая будет предшествовать вызову любых функций библиотеки.Инициализация осуществляется с помощью вызова функции ccinit().
Листинг 2. Алгоритм выполнения инициализации.
... // описание переменной типа camac_r для получения результата работы функции. camac_r cinitf; // вызов функции инициализации cinitf = ccinit(); // анализ результата. if (cinitf) { // если получено ненулевое значение // Инициализация завершилась ошибкой. // Продолжение работы невозможно ... } else { // Инициализация проведена успешно. ... }
|
Для выполнения любых адресных и безадресных команд на магистрали крейта КАМАК необходимо знать, как минимум, номер крейта для безадресных команд, и полный адрес (крейт, место, субадрес), а так же разрядность для адресных команд. Вся эта информация может быть закодирована в одной переменной типа mod_name_camac. В последствии эта переменная может использоваться во всех операциях с крейтом и регистром, адреса которых закодированы в ней.
Существует две функции для работы с именоваными регистрами. Функция именования cdreg и функция разименования cgreg.
camac_r cdreg(mod_name_camac *name, int b /* 16,24 */, int c, int n, int a);
Кодирует полный адрес и разрядность регистра в переменную типа mod_name_camac на которую указывает параметр name.
Таблица 2
name |
Указатель на переменную типа mod_name_camac которая будет описывать один регистр |
b |
Разрядность регистра. Может принимать значения 16, 24 |
c |
Номер крейта от 0 до 3 |
n |
Номер места в крейте от 1 до 24 |
a |
Субадрес (адрес регистра) от 0 до 15 |
Возвращаемые значения:0 - если функция выполнилась успешно; не 0 в противном случае.
camac_r cgreg(mod_name_camac name, int *b, int *c, int *n, int *a);
Разименовывает (декодирует) разрядность и адрес регистра из переменной name в переменные на которые указывают параметры b, c, n, a.
Листинг 3. Пример работы функций.
#include "camlib.h" ... camac_r cresult;
// переменная в которой будет храниться //адрес и разрядность регистра счетчика mod_name_camac Counter;
// разрядность, крейт, место, субадрес соответственно int b, c, n, a;
// Создаем адрес счетчика разрядностью 24 бит, // в крейте 0 на месте 14 по субадресу 1 cresult = cdreg( &Counter, 24, 0, 14, 1);
if (cresult) { // ошибка } else { // Разименовываем Counter cgreg(Counter, &b, &c, &n, &a);
// теперь переменные b, c, n, a будут содержать // значения 24, 0, 14, 1 соответственно. }
|
Для выполнения адресных команд используется функция
camac_r cssa(int f, mod_name_camac name, int *buf, bool_camac *q)
Таблица 3
f |
Номер функции от 0 до 31 |
name |
Переменная типа mod_name_camac описывающая регистр |
buf |
Указатель на переменную целого типа (32 бита), значение которой будет записано в регистр, если выполняется команда записи или, если выполняется команда чтения - в эту переменную будет записано прочитанное значение |
q |
Указатель на логическую переменную типа bool_camac, которая примет значение истина, если после выполнения команды адресуемый модуль вернул сигнал Q, и ложь - в противном случае |
После выполнение команды структура CAM_DATA будет содержать дополнительные данные. Если функция вернула значение отличное от 0, то поле ERRCODE структуры CAM_DATA будет содержать код ошибки.
Листинг 4. Пример работы функции.
#include "camlib.h"
...
camac_r cresult;
// переменная в которой будет храниться //адрес и разрядность регистра счетчика mod_name_camac Counter;
int b, c, n, a; // разрядность, крейт, место, субадрес соответственно int Data; // Данные для передачи и принимаемые данные bool_camac intr; // состояние сигнала Q CAM_DATA* cam_data;
cam_data = cdata();
// Создаем адрес счетчика разрядностью 24 бита, // в крейте 0 на месте 14 по субадресу 1
cresult = cdreg( &Counter, 24, 0, 14, 1);
if (cresult || !cam_data->X) { // ошибка } else { // Чтение функцией F1 содержимого счетчика Counter в переменную Data cresult=cssa( 1, Counter, &Data, &intr); if (cresult) { // обработка ошибки } else { // Обнуление счетчика Counter функцией F17 Data = 0; cresult=cssa( 17, &Data, &intr); if (cresult || !cam_data->X) { // обработка ошибки } } }
|
Генерация одиночных безадресных команд:
Z (Zero) - генерирует сигнал Z в крейте, адрес которого закодирован в переменной name. Если возвращенное значение отлично от 0, то поле ERRCODE структуры CAM_DATA содержит код ошибки.
camac_r cccz(mod_name_camac name)
C (Clear) - генерирует сигнал C в крейте, адрес которого закодирован в переменной name. Если возвращенное значение отлично от 0, то поле ERRCODE структуры CAM_DATA содержит код ошибки.
camac_r cccc(mod_name_camac name)
I (Inhibit) - устанавливает запрет в крейте, адрес которого зашифрован в переменной name при истинном значении параметра l(l>0), и сбрасывает в противном случае (l=0). Если возвращенное значение отлично от 0, то поле ERRCODE структуры CAM_DATA содержит код ошибки.
camac_r ccci(mod_name_camac name, bool_camac l)
Читает состояние сигнала Inhibit в крейте, адрес которого зашифрован в переменной name и помещает его в переменную типа bool_cam на которую указывает параметр l.
camac_r ctci(mod_name_camac name, bool_camac *l)
Тест наличия LAM:
Проверяет наличие LAM (сумма сигналов L1..L24) в крейте, адрес которого зашифрован в переменной name и записывает результат по адресу, значение которого хранится в параметре l. Если сигнал находится в активном состоянии (есть запрос на обслуживание), то читается состояние всей шины прерываний L1..L24, и результат записывается в поле L структуры CAM_DATA. Если возвращенное значение отлично от 0, то поле ERRCODE структуры CAM_DATA содержит код ошибки.
camac_r ctgl(mod_name_camac name, bool_camac *l)
Перывания:
При возникновении запроса на обслуживание от любого крейта генерируется аппаратное прерывание, при условии, что оно разрешено.
Разрешает аппаратное прерывание по запросу на обслуживание.
camac_r cclnk(int_name_function int_func)
int_func - Переменная типа int_name_function, указывающая на определенную пользователем функцию-обработчик прерываний. Если возвращенное значение отлично от 0, то поле ERRCODE структуры CAM_DATA содержит код ошибки.
Запрещает аппаратные прерывания по запросу на обслуживание.Если возвращенное значение отлично от 0, то поле ERRCODE структуры CAM_DATA содержит код ошибки.
camac_r cculnk()
Анализ ошибок:
После выполнения любой команды код ошибки будет записан в поле ERRCODE структуры CAM_DATA. Ниже приведены возможные коды ошибок и их расшифровки.
Таблица 4
0x0100 |
Аппаратная ошибка. Возникает в случае сбоя в работе оборудования |
0x0200 |
Ошибка обмена. Возникает с случае отсутствия входящих данных по истечению внутреннего временного интервала |
0x0400 |
Может возникнуть при вызове функции cdreg одно или несколько значений параметров этой функции не лежат в допустимом диапазоне |
0x0500 |
Ошибка обмена. Возникает если в течении внутреннего интервала времени не удалось передать данные |
Воздействие функций на поля структуры CAM_DATA:
Таблица 5
|
ERRCODE |
X |
Q |
LAM |
I |
L |
FH |
FL |
R |
W |
ccinit |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
cdreg |
+ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
cgreg |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
cssa |
+ |
+ |
+ |
- |
+/- |
+/- |
+/- |
+/- |
+/- |
+/- |
cccz |
+ |
- |
- |
+ |
+/- |
- |
- |
- |
- |
- |
cccc |
+ |
- |
- |
+ |
+/- |
- |
- |
- |
- |
- |
Ccci |
+ |
- |
- |
+ |
+/- |
- |
- |
- |
- |
- |
Ctci |
+ |
- |
- |
+ |
+ |
+ |
- |
- |
- |
- |
Ctgl |
+ |
- |
- |
+ |
+ |
+ |
- |
- |
- |
- |
cclnk |
+ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
cculnk |
+ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Листинг 5. Файл camlib.h.
#define WCYCLES_EXCEEDED 0x0100 #define TIMEOUT_ERROR 0x0200 #define INCORRECT_CNAF 0x0400 #define TRANSMITT_ERROR 0x0500
typedef int mod_name_camac; // CCNNNNNAAAA typedef unsigned char bool_camac; typedef void (*int_name_function) (void); typedef unsigned int camac_L; typedef unsigned int camac_r; typedef struct { unsigned short ERRCODE; bool_camac X; bool_camac Q; bool_camac LAM; bool_camac I; camac_L L; bool_camac FH; bool_camac FL;
int R; int W; } CAM_DATA;
#ifdef CAMAC_DLL_BUILD #define dll_mod camac_r __export #define dll_mod_data CAM_DATA* __export #else #define dll_mod extern "C" __declspec(dllimport) camac_r #define dll_mod_data extern "C" __declspec(dllimport) CAM_DATA* #endif
// получить указатель на структуру CAM_DATA dll_mod_data cdata();
// Инициализация контроллера dll_mod ccinit();
// присвоить имя имя регистру КАМАК dll_mod cdreg(mod_name_camac *name, int b /* 16,24 */, int c, int n, int a); // получить параметры регистра КАМАК dll_mod cgreg(mod_name_camac name, int *b, int *c, int *n, int *a);
// выполнить одиночную команду КАМАК dll_mod cssa(int f, mod_name_camac name, int *buf, bool_camac *q);
// генерация одиночных, безадресных команд dll_mod cccz(mod_name_camac name); dll_mod cccc(mod_name_camac name); dll_mod ccci(mod_name_camac name, bool_camac l);
// тест состояния Inhibit в крейте КАМАК dll_mod ctci(mod_name_camac name, bool_camac *l);
// тест наличия LAM в крейте КАМАК // Если L присутствует то читаются состояния со всех мест крейта (24 bit) dll_mod ctgl(mod_name_camac name, bool_camac *l);
// Разрешить работу по прерываниям от LAM dll_mod cclnk(int_name_function int_func);
// Запретить работу по прерываниям от LAM dll_mod cculnk();
|
|