tskbuf.c

来自「一个可以立即使用的嵌入式操作系统」· C语言 代码 · 共 215 行

C
215
字号
/*
   --- Version 2.2 91-05-17 00:02 ---

   TSKBUF.C - CTask - Buffered Message handling routines.

   Public Domain Software written by
      Thomas Wagner
      Ferrari electronic Gmbh
      Beusselstrasse 27
      D-1000 Berlin 21
      Germany

   NOTE: None of the Buffer routines my be used from inside an interrupt
         handler. The routines are relatively slow, since they use
         the normal word pipe and resource calls. Optimization would be 
         possible by using block moves and internally handling resources.
*/

#include "tsk.h"
#include "tsklocal.h"


bufferptr Globalfunc create_buffer (bufferptr buf, farptr pbuf, 
                                    word bufsize TN(byteptr name))
{
#if (TSK_DYNAMIC)
   if (buf == LNULL)
      {
      if ((buf = (bufferptr)tsk_palloc (sizeof (buffer))) == LNULL)
         return LNULL;
      buf->flags = F_TEMP;
      }
   else
      buf->flags = 0;
   if (pbuf == LNULL)
      {
      if ((pbuf = tsk_palloc (bufsize)) == LNULL)
         {
         if (buf->flags & F_TEMP)
            tsk_pfree (buf);
         return LNULL;
         }
      buf->flags |= F_STTEMP;
      }
#endif

   create_wpipe (&buf->pip, pbuf, bufsize TN(name));
   create_resource (&buf->buf_read TN(name));
   create_resource (&buf->buf_write TN(name));
   buf->msgcnt = 0;

#if (TSK_NAMED)
   tsk_add_name (&buf->name, name, TYP_BUFFER, buf);
#endif

   return buf;
}


void Globalfunc delete_buffer (bufferptr buf)
{
   CHECK_EVTPTR (buf, TYP_RESOURCE, "Delete Buffer");

   delete_wpipe (&buf->pip);
   delete_resource (&buf->buf_read);
   delete_resource (&buf->buf_write);
   buf->msgcnt = 0;

#if (TSK_NAMED)
   tsk_del_name (&buf->name);
#endif

#if (TSK_DYNAMIC)
   if (buf->flags & F_STTEMP)
      tsk_pfree (buf->pip.wcontents);
   if (buf->flags & F_TEMP)
      tsk_pfree (buf);
#endif
}


int Globalfunc read_buffer (bufferptr buf, farptr msg, int size, dword timeout)
{
   int i, len, l1, l2;
   word w;

   CHECK_EVTPTR (buf, TYP_RESOURCE, "Read Buffer");

   if ((i = request_resource (&buf->buf_read, timeout)) < 0)
      return i;

   if ((len = read_wpipe (&buf->pip, timeout)) < 0)
      {
      release_resource (&buf->buf_read);
      return len;
      }

   l1 = (len < size) ? len : size;

   for (i = 0; i < l1; i++)
      {
      if (!(i & 1))
         w = read_wpipe (&buf->pip, 0L);
      else
         w = w >> 8;
      ((byteptr)msg) [i] = (byte)w;
      }

   l2 = (len + 1) >> 1;
   for (i = (l1 + 1) >> 1; i < l2; i++)
      read_wpipe (&buf->pip, 0L);
   if (l1 < size)
      ((byteptr)msg) [l1] = 0;

   buf->msgcnt--;

   release_resource (&buf->buf_read);
   return len;
}


int Globalfunc c_read_buffer (bufferptr buf, farptr msg, int size)
{
   int res;
   CRITICAL;

   CHECK_EVTPTR (buf, TYP_RESOURCE, "Cond Read Buffer");

   res = -1;
   C_ENTER;

   if (buf->pip.filled && !buf->buf_read.count)
      {
      request_resource (&buf->buf_read, 0L);
      C_LEAVE;
      res = read_buffer (buf, msg, size, 0L);
      }
   else
      C_LEAVE;

   return res;
}


local int Staticfunc tsk_wrbuf (bufferptr buf, word w, dword timeout)
{
   int i;

   if ((i = write_wpipe (&buf->pip, w, timeout)) < 0)
      release_resource (&buf->buf_write);
   return i;
}


int Globalfunc write_buffer (bufferptr buf, farptr msg, int size, dword timeout)
{
   int i, res, l2;

   CHECK_EVTPTR (buf, TYP_RESOURCE, "Write Buffer");

   if (size < 0 || (word)((size + 3) >> 1) > buf->pip.bufsize)
      return -3;

   if ((i = request_resource (&buf->buf_write, timeout)) < 0)
      return i;

   if ((i = tsk_wrbuf (buf, (word)size, timeout)) < 0)
      return i;

   l2 = (size + 1) >> 1;

   for (i = 0; i < l2; i++)
      if ((res = tsk_wrbuf (buf, ((wordptr)msg) [i], timeout)) < 0)
         return res;

   buf->msgcnt++;

   release_resource (&buf->buf_write);
   return size;
}


int Globalfunc c_write_buffer (bufferptr buf, farptr msg, int size)
{
   int res;
   CRITICAL;

   CHECK_EVTPTR (buf, TYP_RESOURCE, "Cond Write Buffer");

   if (size < 0 || (word)((size + 3) >> 1) > buf->pip.bufsize)
      return -3;

   C_ENTER;
   res = -1;

   if (wpipe_free (&buf->pip) >= (word)((size + 3) >> 1) && !buf->buf_write.count)
      {
      request_resource (&buf->buf_write, 0L);
      C_LEAVE;
      res = write_buffer (buf, msg, size, 0L);
      }
   else
      C_LEAVE;

   return res;
}


word Globalfunc check_buffer (bufferptr buf)
{
   CHECK_EVTPTR (buf, TYP_RESOURCE, "Check Buffer");
   return buf->msgcnt;
}

⌨️ 快捷键说明

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