Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

Обработка ошибок при чтении\записи в устройство.

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
ULiX



Зарегистрирован: 18.04.2007
Сообщения: 3
Откуда: Комсомольск-на-Амуре

СообщениеДобавлено: Ср Апр 18 2007 12:46    Заголовок сообщения: Обработка ошибок при чтении\записи в устройство. Ответить с цитатой

По ппорядку о проблеме.

-= Объект =-
Существует определённое устройство.
Это устройство подключено через интерфейсную плату KOP.
Для данной платы устанавливается драйвер под DOS.
Драйвер обеспечиывает доступ к устройству посредством чтения записи в интерфейсы "KOP0" ... "KOPF".

Т.е. например, "Мост переменного тока" подключен к интерфейсной плате с адресом 1. Тогда для общения с данным прибором, мы должны посылать и считывать управляющие последовательности символов в интерфейс "KOP1".
Открывается интерфейс как обычный поток, или файл:

p5083=open("KOP1",O_RDWR);

или в BASIC:

OPEN "KOP1" FOR RANDOM AS 1

Запись чтение осуществляется командами:

n_bait = _write(p5083,s,len);
err = _read(p5083,p,ReadMsr);


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

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

Привожу полный листинг поцедур библиотеки управления:

Код:

   /*
    * Файл CP5083.h
    * Макроопределения для работы
    *  и описания функций управления
    *  МОСТОМ P5083
    */
#ifndef   _CP5083_H
#define _CP5083_H

#ifndef __STDIO_H
#include<stdio.h>
#endif

#define   LenMsr      40   /* Длина (байт) сообщения от МОСТА */
#define LenStringMsr   (50+1)
#define ReadMsr      29
      /* Ошибки при работе с МОСТОМ */
#define   NO_ERR_M   0   /* Нет ошибок */
#define   NO_OPEN_KOP   1   /* Не открыт канал на устройство КОП */
#define ERR_OPEN_KOP   2   /* Ошибка открытия устройства КОП */
#define   ERR_WR_M   3   /* Ошибка записи в МОСТ */
#define   ERR_RD_M   4   /* - - - чтения с МОСТА */
#define   ERR_PARM_M   5   /* - - -  в задании параметров */
#define   ERR_F_M      6   /* - - -  в задании частоты */
#define   PRIMARY_MSR   1
#define   SECOND_MSR   2

//#define   ERR_FILENAME   7   /* - - -  в задании имени файла */
//#define   ERR_OPEN_FILE   8   /* - - -  открытия файла */
//#define   ERR_WR_FILE   9   /* - - -  записи в файл */

enum P5083SW { Off,On,R,C,L,Parallel,Serial,Tg_fi,Tg_s };

extern int cdecl ch_setmost();
extern int cdecl most_msr();
extern char* cdecl read_msr1(char *s);

struct Measure_P5083
       { float   primary_msr,
       second_msr,
       frequency;
   char   prim_s,second_s;
   int   measure();
   int   measure(float f);
   float   ret(int btypemsr);
   int   sprint(char *pszStr);
   char   **primname();
   char   **secondname();
   char    primsym();
       };

struct DriverMostP5083
   {
    int   PrmP5083,
      NumberUsr;
    int  init(char dev[]);
    void closse(void);
    int  chset()      { return(ch_setmost()); }
    int  msr()      { return(most_msr());   }
    int  mode(P5083SW);
    int  mode();
    int  schema(P5083SW);
    int  schema();
    int  var(P5083SW);
    int  var();
    int  modes(P5083SW);
    int  modes();
    int synchrS(P5083SW);
    int synchrS();
    int Umin(P5083SW);
    int Umin();
    int Usr(int n);
    int Usr();
    float frq(float ff);
    float frq();
    int parm(int p);
    int parm();
    //int set_parm(int p,int n=0,float v=0.0,P5083SW sw=C);
    int procent(float v,P5083SW sw);
    int error(void);
    int error(int);
    char* strerr(void);
    char* readmsr1(char *s)   { return(read_msr1(s)); }
    char* readmsr(char *s);
    char* measure1(char *s);
   };
#endif


Код:

   /* Файл P5083L3.C
    * Функции урпавления мостом
    * Ver. 1.3
    *
    *
    */
#include<fcntl.h>
#include <io.h>
#include<dos.h>
#include <string.h>
#include"cp5083.h"

#define ReadMsr 29
#define IGNORE  0
#define ABORT   2
#define RETRY   1
#define NSTOP   10000l
#define NP      12
#define NS      9
#define NF      6
#define TIME    5

void interrupt (*vect24)(...);
void interrupt (*vect24_err)(...);

static float f_mosta=1.5;
static int  parm_most=0xab,str_len,flag_most=1,
       p5083=0,error_m=NO_OPEN_KOP;

static char M_ON[]={'S',0x04,0};
static char M_O[]={'O',0x04,0};

static char data[]={'U',10,
        'S','U',040,'C',040,'P',040,'1',040,'D',040,040,10,
        'F','R',040,040,'1',',','5','0',040,'S',040,'H',10,
        'A','V',040,'1','0',10,
        'P','R',040,'1',',','0','0','0','0','0',040,'-','0','9',
        040,'F',
        'W',0x04,0};
static char *StrErrorMost[]={{"Нет ошибок."},
        {"Не открыт канал на устройство КОП."},
        {"Ошибка открытия устройства КОП."},
        {"Записи в МОСТ."},
        {"Чтения с МОСТА."},
        {" "},
        {"В задании частоты."},
        {" "}
       };
int handler(int err,int ax,int bp,int si)
{
 long int i;

 if((ax&0x0100) == 0) {
         bdosptr(0x09,"ERROR READ KOP !$",0);
         return(ABORT);
            }
 i=NSTOP;
 while( i-- > 0 ) ;
 return(RETRY);
}

int write_p5083(char *s,int len)
{
  int n_bait;

  setvect(0x24,vect24_err);
  n_bait=_write(p5083,s,len);
  setvect(0x24,vect24);
  return(n_bait);
}

int ch_setmost()
{
 if( flag_most )
   {
    if( write_p5083(data,str_len) != str_len)
              error_m=ERR_WR_M;
       else { flag_most=0;   error_m=NO_ERR_M; }
   }
 return error_m;
}

char * DriverMostP5083::strerr(void)
{
 return StrErrorMost[error_m];
}

int most_msr()
{
 if(write_p5083(M_ON,2) != 2) error_m=ERR_WR_M;
         else  error_m=NO_ERR_M;
 return error_m;
}
int DriverMostP5083::init(char dev[])
{
int handler(int err,int ax,int bp,int si);
  if( (p5083=open(dev,O_RDWR)) > 0)
         {
          vect24=getvect(0x24);
          harderr((int (*)())handler);
          vect24_err=getvect(0x24);
          setvect(0x24,vect24);
          str_len=strlen(data);
          ch_setmost();
         }
  else error_m=ERR_OPEN_KOP;
  return(p5083);
}
// Программы оставленные от версии 1.1
//***********************************************
char *read_msr1(char *s)
{
  int err,i;
  char *p;

  *s=0;
  switch(error_m)
  {
   case ERR_OPEN_KOP: break;
   case NO_OPEN_KOP:  break;
   default:
   p=s;
   for(i=0;i<5;i++)
   { *p=data[18+i];
     p++;
   }
   *p=' '; p++;
   *p='к'; p++;
   *p='Г'; p++;
   *p='ц'; p++;
   *p=' '; p++;
   if( _write(p5083,M_O,2) == 2 )
   {
    err=_read(p5083,p,ReadMsr);
     if( err != ReadMsr )  error_m=ERR_RD_M;
      else {
         p=p+ReadMsr;
         *p=0;
         error_m=NO_ERR_M;
         return(s);
           }
   }
   else    error_m=ERR_WR_M;
  }
 return(NULL);
}

char *DriverMostP5083::measure1(char *s)
{
  *s=0;
  switch(error_m)
  {
   case ERR_OPEN_KOP: break;
   case NO_OPEN_KOP:  break;
   case ERR_PARM_M:   break;
   default:
   ch_setmost();
   if( most_msr() == NO_ERR_M)
     return(read_msr1(s));
  //   else    error_m=ERR_WR_M;
   }
  return(NULL);
}
// ***************************************************
char *DriverMostP5083::readmsr(char *s)
{
  int err;
  char *p;

  *s=0;
  switch(error_m)
  {
   case ERR_OPEN_KOP: break;
   case NO_OPEN_KOP:  break;
   default: p=s;
   if( _write(p5083,M_O,2) == 2 )
   {
    err=_read(p5083,p,ReadMsr);
     if( err != ReadMsr )  error_m=ERR_RD_M;
      else {
         p=p+ReadMsr;
         *p=0;
         error_m=NO_ERR_M;
         return(s);
           }
   }
   else    error_m=ERR_WR_M;
  }
 return(NULL);
}

int DriverMostP5083::error()
{
 return(error_m);
}
int DriverMostP5083::error(int err)
{
 error_m=err;
 return error_m;
}

void DriverMostP5083::closse()
{
 close(p5083); error_m=NO_OPEN_KOP;
}

int DriverMostP5083::mode(P5083SW pr)
{
switch(error_m)
 {
  case ERR_OPEN_KOP: case NO_OPEN_KOP:  break;
  default:
  switch(pr)
  {
   case L: data[5]='L'; parm_most&=0xfe; break;
   case C: data[5]='C'; parm_most|=0x01; break;
  }
/*  switch(sc)
  {
   case  Tg_s: data[11]='D'; parm_most|=0x08; break;
   case Tg_fi: data[11]='Q'; parm_most&=0xf7; break;
  }
*/
  flag_most=1;
 }
 return 0;
}

int DriverMostP5083::modes(P5083SW sc)
{
switch(error_m)
 {
  case ERR_OPEN_KOP: case NO_OPEN_KOP:  break;
  default:
  switch(sc)
  {
   case  Tg_s: data[11]='D'; parm_most|=0x08; break;
   case Tg_fi: data[11]='Q'; parm_most&=0xf7; break;
  }
  flag_most=1;
 }
 return 0;
}

int DriverMostP5083::mode()
{ return(parm_most&0xfe); }

int DriverMostP5083::modes()
{ return((parm_most&0xf7)>>3); }

int DriverMostP5083::schema(P5083SW sw)
{
switch(error_m)
 {
  case ERR_OPEN_KOP: case NO_OPEN_KOP:  break;
  default:
  switch(sw)
  {
   case Parallel: data[7]='P'; parm_most|=0x02; break;
   case   Serial: data[7]='S'; parm_most&=0xfd; break;
  }
  flag_most=1;
 }
 return 0;
}
int schema()
{ return((parm_most&0xfd)>>1); }

int DriverMostP5083::var(P5083SW sw)
{
switch(error_m)
 {
  case ERR_OPEN_KOP: case NO_OPEN_KOP:  break;
  default:
  switch(sw)
  {
   case  On: data[9]='V'; parm_most|=0x04; break;
   case Off: data[9]='1'; parm_most&=0xfb; break;
  }
  flag_most=1;
 }
 return 0;
}

int DriverMostP5083::var()
{ return((parm_most&0xfd)>>2); }

int DriverMostP5083::synchrS(P5083SW sw)
{
switch(error_m)
 {
  case ERR_OPEN_KOP: case NO_OPEN_KOP:  break;
  default:
  switch(sw)
  {
   case  On: data[24]='S'; parm_most|=0x20; break;
   case Off: data[24]='A'; parm_most&=0xdf; break;
  }
  flag_most=1;
 }
 return 0;
}
int DriverMostP5083::synchrS()
{ return((parm_most&0xdf)>>5); }

int DriverMostP5083::Umin(P5083SW sw)
{
switch(error_m)
 {
  case ERR_OPEN_KOP: case NO_OPEN_KOP:  break;
  default:
  switch(sw)
  {
   case  On: data[26]='L'; parm_most|=0x40; break;
   case Off: data[26]='H'; parm_most&=0xbf; break;
  }
  flag_most=1;
 }
 return 0;
}
int DriverMostP5083::Umin()
{ return((parm_most&0xbf)>>6); }

int DriverMostP5083::Usr(int n)
{
 char str_n[2];

 if( n==1 || n<0 || n > 99 )
   { error_m=ERR_PARM_M; return(error_m); }
 sprintf(str_n,"%2d",n);
 data[32]=str_n[1];
 if( str_n[0] ==' ' )  data[31]='0';
      else   data[31]=str_n[0];
 if(n == 0)   parm_most&=0x7f;
   else   parm_most|=0x80;
 flag_most=1;
 return 0;
}

int DriverMostP5083::Usr()
{
 int ret_n;
 char str_n[2];

 if((parm_most & 0x80) == 0)  return 0;
 str_n[1]=data[32];
 if( data[31] =='0' )  str_n[0]=' ';
      else   str_n[0]=data[31];
 sscanf(str_n,"%2d", &ret_n);
 return ret_n;
}
int DriverMostP5083::procent(float v,P5083SW sw)
{
 return 0;
}

int DriverMostP5083::parm(int p)
{ parm_most=p;
  return parm_most;
}

int DriverMostP5083::parm()
{ return parm_most; }

/* int set_parm(int p,int n,float v,P5083SW sw)
{
 parm_most=p;
 if((p&0x01)==0x01)  mode_Msr(C);
      else mode_Msr(L);
 if((p&0x02)==0x02)  schema(Parallel);
      else schema(Serial);
 if((p&0x04)==0x04)  mode_Var(On);
      else mode_Var(Off);
 if((p&0x08)==0x08)  mode_Second(Tg_s);
      else mode_Second(Tg_fi);
 if((p&0x10)==0x10)  procent(v,sw);
      else procent(v,sw);
 if((p&0x20)==0x20)  synchrS(On);
      else synchrS(Off);
 if((p&0x40)==0x40)  U_min(On);
      else U_min(Off);
 if((p&0x80)==0x80)  mode_Usr(n);
      else mode_Usr(0);
 ch_setmost();
 return 0;
}  */
/* if( write_p5083(data,str_len) != str_len)
         error_m=ERR_WR_M;
      else    error_m=NO_ERR_M;

 }
return(error_m);
}   */

float DriverMostP5083::frq(float f)
{
  float retcod;
  int i;
  char strf[8];

  retcod=0.;
  if( f < 0.1 ) { f=0.1;  retcod=(-1.); }
  if( f > 100.) { f=100.; retcod=(-1.); }
  if( f < 1 )   sprintf(strf,"%5.3f",f);
   else
   if( f < 10)     sprintf(strf,"%5.2f",f);
      else    if( f == 100.0 ) sprintf(strf,"%5.0f",f);
         else             sprintf(strf,"%5.1f",f);
  for(i=0;i<5;i++)
   if( strf[i] == '.') data[18+i]=',';
          else    data[18+i]=strf[i];
  f_mosta=f;
  flag_most=1;
  return(retcod);
}
float DriverMostP5083::frq()
{ return f_mosta; }
//
 


Первая функция которая будет вызываться из этой библиотеки это процедура инициализации драйвера:
Код:

int DriverMostP5083::init(char dev[])
{
int handler(int err,int ax,int bp,int si);
  if( (p5083=open(dev,O_RDWR)) > 0)
         {
          vect24=getvect(0x24);
          harderr((int (*)())handler);
          vect24_err=getvect(0x24);
          setvect(0x24,vect24);
          str_len=strlen(data);
          ch_setmost();
         }
  else error_m=ERR_OPEN_KOP;
  return(p5083);
}


Как мы отсюда видим обработчиком ошибки задаётся процедура:
Код:
int handler(int err,int ax,int bp,int si)
{
 long int i;

 if((ax&0x0100) == 0) {
         bdosptr(0x09,"ERROR READ KOP !$",0);
         return(ABORT);
            }
 i=NSTOP;
 while( i-- > 0 ) ;
 return(RETRY);
}



\\Запомнили прежний адрес обработчика
vect24=getvect(0x24);

\\Задали новую процедуру вызываемую при генерации ошибки устройства
harderr((int (*)())handler);

\\Снова запомнили адрес обработчика теперь указывающего
\\на наш обработчик
vect24_err=getvect(0x24);

\\Восстановили прежний обработчик прерывания.
setvect(0x24,vect24);

Теперь у нас vect24_err указывает на обработчик handler
а vect24 содержит старый адрес для восстановления.

Далее эти вектора используются при записи в устройство:

Код:

int write_p5083(char *s,int len)
{
  int n_bait;

  setvect(0x24,vect24_err);
  n_bait=_write(p5083,s,len);
  setvect(0x24,vect24);
  return(n_bait);
}




--== ЗАДАЧА ==--
Осуществить перехват ошибки устройства средствами C++Builder.

Функции оперирования с векторами прерываний в C++Builder не поддерживаются. Нужно найти альтернативный способ задать обработчик данной ошибки, не используя функции:
setvect();
getvect();
harderr();

Предусмотреть присутствующую в обработчике проверку:
Код:

 if((ax&0x0100) == 0) {
         bdosptr(0x09,"ERROR READ KOP !$",0);
         return(ABORT);
        }


Интуитивно предпологаю, что нужно использовать блок
try
catch

Но возможно придётся также заменить и функции работы с потоками, так как не уверен, что dos функция _write генерирует ошибки с помощью throw.

Заранее большое спасибо всем, кто откликнется.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...