⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_iac.c

📁 linux下的RS485的驱动 值得一看
💻 C
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_iac.c	- ulan immetiately action command  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************/#include "ul_drv_iac.h"typedef struct ul_iac_chain {	struct ul_iac_chain *prev;	struct ul_iac_chain *next;	int cmd;        int op;	unsigned flg;	ul_msginfo msginfo;	char *ibuff;	ul_iac_data iac_data;	ul_iac_call_fnc *fnc;} ul_iac_chain;static void add_to_iac_chain(ul_iac_chain **chain,ul_iac_chain *member){  UL_DRV_LOCK_FINI  UL_DRV_LOCK;  if(!*chain) *chain=member->next=member->prev=member;  else {    ((volatile ul_iac_chain*)member)->next=*chain;    ((volatile ul_iac_chain*)member)->prev=(*chain)->prev;    UL_MB();    ((volatile ul_iac_chain*)(*chain))->prev->next=member;    ((volatile ul_iac_chain*)(*chain))->prev=member;  };  UL_DRV_UNLOCK;};static void del_from_iac_chain(ul_iac_chain **chain,ul_iac_chain *member){  UL_DRV_LOCK_FINI  UL_DRV_LOCK;  member->next->prev=member->prev;  member->prev->next=member->next;  if(*chain==member)   { if(member->next==member) *chain=NULL;    else *chain=member->next;  };  UL_DRV_UNLOCK;};int ul_drv_add_iac(ul_drv *udrv,int cmd,int op,ul_iac_call_fnc *fnc,char *buff, unsigned len,unsigned flg,void *ctx){  ul_iac_chain *member;  member=(ul_iac_chain*)MALLOC(sizeof(ul_iac_chain));  if(!member) return -ENOMEM;  memset(member,0,sizeof(ul_iac_chain));  member->cmd=cmd;  member->op=op;  member->flg=flg;  member->fnc=fnc;  member->iac_data.buff=buff;  member->iac_data.len=len;  member->iac_data.ctx=ctx;  add_to_iac_chain(&udrv->iac_chain,member);  LOG_IAC("ulan_add_iac : cmd %d\n", member->cmd);  return 0;}int ul_drv_del_iac(ul_drv *udrv,int cmd){  ul_iac_chain *member,*next;  int r=-1;  member=udrv->iac_chain;  if(member) do  { next=member->next;    if(next==udrv->iac_chain) next=NULL;    if (member->cmd==cmd) {      del_from_iac_chain(&udrv->iac_chain,member);      if (member->flg&UL_IAC_BFL_FREEBUFF) FREE(member->iac_data.buff);      FREE(member);      r=0;      break;    }  } while((member=next)!=NULL);  return r;}INLINE int conv_iac_rc(int iac_rc) {  if (iac_rc==UL_IAC_RC_PROC) return UL_RC_PROC;  if (iac_rc==UL_IAC_RC_FREEMSG) return UL_RC_FREEMSG;  return UL_IAC_RC_ERR;}/*******************************************************************//* Message and frame proccessor for user commands */int uld_prmess_iac_s4(ul_drv *udrv, int ret_code){  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  UL_FRET;  return udrv->iac_ret_code;};int uld_prmess_iac_s3(ul_drv *udrv, int ret_code){  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  udrv->con_flg=0; /* UL_END */  UL_FCALL2(uld_sndend,uld_prmess_iac_s4);  return UL_RC_PROC;};int uld_prmess_iac_s2(ul_drv *udrv, int ret_code){  ul_iac_data *iac_data;  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  iac_data=&(udrv->iac_act->iac_data);  if (iac_data->len!=iac_data->ptr) {    udrv->char_buff=iac_data->buff[iac_data->ptr];    UL_FCALL(*udrv->fnc_sndch);    iac_data->ptr++;  } else     UL_FNEXT(uld_prmess_iac_s3);  return UL_RC_PROC;};int uld_prmess_iac_s1(ul_drv *udrv, int ret_code){  udrv->con_sadr=udrv->my_adr;	  udrv->con_cmd&=0x7f;  udrv->con_flg=4; /* UL_BEG */  UL_FCALL2(uld_sndbeg,uld_prmess_iac_s2);  return UL_RC_PROC;};int uld_prmess_iac_r5(ul_drv *udrv, int ret_code){  ul_iac_data *iac_data;  struct ul_iac_chain *iac_act;  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  iac_act=udrv->iac_act;  iac_data=&(iac_act->iac_data);  UL_FRET;  return conv_iac_rc(udrv->iac_act->fnc(udrv,&iac_act->msginfo,iac_act->ibuff,iac_data));};int uld_prmess_iac_r4(ul_drv *udrv, int ret_code){  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  udrv->con_flg=0; /* UL_END */  UL_FCALL2(uld_recend,uld_prmess_iac_r5);  return UL_RC_PROC;};int uld_prmess_iac_r3(ul_drv *udrv, int ret_code){  ul_iac_data *iac_data;  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  iac_data=&(udrv->iac_act->iac_data);  if(!(udrv->char_buff&0xFF00)) {    iac_data->buff[iac_data->ptr]=udrv->char_buff;    iac_data->ptr++;     iac_data->len++;    UL_FCALL(*udrv->fnc_recch);    return UL_RC_PROC;  }  UL_FNEXT(uld_prmess_iac_r4);  return UL_RC_PROC;}int uld_prmess_iac_r2(ul_drv *udrv, int ret_code){  if(ret_code<0) {UL_FNEXT(uld_prmess_error);return UL_RC_EPRMESS;};  UL_FCALL2(*udrv->fnc_recch,uld_prmess_iac_r3);  return UL_RC_PROC;}int uld_prmess_iac_r1(ul_drv *udrv, int ret_code){  udrv->con_flg=8; /* UL_BEG */  UL_FCALL2(uld_recbeg,uld_prmess_iac_r2);  return UL_RC_PROC;};int get_iac_op(ul_drv *udrv, uchar cmd){  ul_iac_chain *member,*next;  member=udrv->iac_chain;  if(member) do  { next=member->next;    if(next==udrv->iac_chain) next=NULL;    if (member->cmd==cmd) {      udrv->iac_act=member;      return member->op;    }  } while((member=next)!=NULL);  return -1;}int uld_prmess_iac(ul_drv *udrv, int ret_code){  ul_iac_data *iac_data;  struct ul_iac_chain *iac_act;  ul_mem_blk *mes;  int r;  ret_code=UL_RC_PROC;  mes=udrv->con_message;  r=get_iac_op(udrv,udrv->con_cmd);  if (r==-1) {    UL_FRET;    return ret_code;  }  iac_act=udrv->iac_act;  iac_data=&(iac_act->iac_data);  iac_act->msginfo.dadr=UL_BLK_HEAD(mes).dadr;  iac_act->msginfo.sadr=UL_BLK_HEAD(mes).sadr;  iac_act->msginfo.flg=UL_BLK_HEAD(mes).flg;  iac_act->msginfo.len=UL_BLK_HEAD(mes).len;  if (iac_act->msginfo.len>UL_BLK_SIZE)    iac_act->msginfo.len=UL_BLK_SIZE;  iac_act->ibuff=UL_BLK_FDATA(mes);  switch (r) {    case UL_IAC_OP_CALLBACK:      ret_code=conv_iac_rc(udrv->iac_act->fnc(udrv,&iac_act->msginfo,iac_act->ibuff,iac_data));      break;    case UL_IAC_OP_SNDBUFF:    case UL_IAC_OP_SND:      if (udrv->con_flg&2) {        udrv->iac_ret_code=UL_RC_FREEMSG;        iac_data->ptr=0;        UL_FNEXT(uld_prmess_iac_s1);        if (r==UL_IAC_OP_SND)          udrv->iac_ret_code=conv_iac_rc(udrv->iac_act->fnc(udrv,&iac_act->msginfo,iac_act->ibuff,iac_data));        return UL_RC_PROC;      }      break;    case UL_IAC_OP_REC:      if (udrv->con_flg&2) {        iac_data->ptr=0;	iac_data->len=0;        UL_FNEXT(uld_prmess_iac_r1);        return UL_RC_PROC;      }    default:      break;  }  UL_FRET;  return ret_code;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -