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

📄 arch_c.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
字号:
/*
 *  Copyright (c) 2004, Dennis Kuschel.
 *  All rights reserved. 
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *   3. The name of the author may not be used to endorse or promote
 *      products derived from this software without specific prior written
 *      permission. 
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 *  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 *  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 *  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 *  OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */


/*
 * This file is originally from the pico]OS realtime operating system
 * (http://picoos.sourceforge.net).
 *
 * CVS-ID $Id: arch_c.c,v 1.3 2004/03/21 18:30:57 dkuschel Exp $
 */


/*  Note on compiler:
 *
 *  This port was successfully tested with Boarland C++ 3.1
 */

#include <dos.h>
#include <conio.h>
#include <picoos.h>


/*-----------------------------------------------------------------------*/

#define TMRINT        0x08
#define KEYBINT       0x09
#define DOSTMRINT     0x81
#define DOSKEYBINT    0x82
#define OSINT         0x80

/*-----------------------------------------------------------------------*/

/* prototypes of external functions */
extern void _pos_softCtxSw(void);
extern void _timerIrq(void);
#ifdef POSNANO
extern void _keyboardIrq(void);
#endif

/* local prototypes */
void p_installInterrupts(void);
void p_pos_initArch(void);



/*-------------------------------------------------------------------------
 * simple MALLOC and FREE
 *-----------------------------------------------------------------------*/
#if (POSCFG_TASKSTACKTYPE == 1)

static void  mem_init(void);
static void* my_malloc(UINT_t size);
static void  my_free(void *p);

#define MEMSIZE_SMALL    0x0200
#define MEMSIZE_BIG      0x0600
#define MEMBLOCKS_SMALL  16
#define MEMBLOCKS_BIG    16

#define ATABSIZE_SMALL   ((MEMBLOCKS_SMALL + MVAR_BITS - 1) / MVAR_BITS)
#define ATABSIZE_BIG     ((MEMBLOCKS_BIG   + MVAR_BITS - 1) / MVAR_BITS)
static unsigned char memSmall_g[MEMBLOCKS_SMALL][MEMSIZE_SMALL];
static unsigned char memBig_g[MEMBLOCKS_BIG][MEMSIZE_BIG];
static UVAR_t atabSmall_g[ATABSIZE_SMALL];
static UVAR_t atabBig_g[ATABSIZE_BIG];


static void mem_init(void)
{
  UVAR_t i;
  for (i=0; i<ATABSIZE_SMALL; i++)
  {
    atabSmall_g[i] = 0;
#if (ATABSIZE_SMALL != ATABSIZE_BIG)
  }
  for (i=0; i<ATABSIZE_BIG; i++)
  {
#endif
    atabBig_g[i] = 0;
  }
}


static void* my_malloc(UINT_t size)
{
  UVAR_t x, y, b;
  POS_LOCKFLAGS;
  
  if ((size == 0) || (size > MEMSIZE_BIG))
    return NULL;

  POS_SCHED_LOCK;
  if (size <= MEMSIZE_SMALL)
  {
    for (y = 0; y < ATABSIZE_SMALL; y++)
    {
      b = ~atabSmall_g[y];
      if (b != 0)
      {
        x = POS_FINDBIT(b);
        atabSmall_g[y] |= 1 << x;
        POS_SCHED_UNLOCK;
        return (void*) memSmall_g[x + (y * MVAR_BITS)];
      }
    }
  }
  for (y = 0; y < ATABSIZE_BIG; y++)
  {
    b = ~atabBig_g[y];
    if (b != 0)
    {
      x = POS_FINDBIT(b);
      atabBig_g[y] |= 1 << x;
      POS_SCHED_UNLOCK;
      return (void*) memBig_g[x + (y * MVAR_BITS)];
    }
  }
  POS_SCHED_UNLOCK;
  return NULL;  
}


static void my_free(void *p)
{
  UVAR_t x, y;
  POS_LOCKFLAGS;
  
  POS_SCHED_LOCK;
  if ((p >= (void*)memSmall_g[0]) &&
      (p <= (void*)memSmall_g[MEMBLOCKS_SMALL]))
  {
    for (x = 0; x < MEMBLOCKS_SMALL; x++)
    {
      if (p == (void*)memSmall_g[x])
      {
        y = x / MVAR_BITS;
        x &= MVAR_BITS - 1;
        atabSmall_g[y] &= ~(1 << x);
        POS_SCHED_UNLOCK;
        return;
      }
    }
  }
  if (p >= (void*)memBig_g[0])
  {
    for (x = 0; x < MEMBLOCKS_BIG; x++)
    {
      if (p == (void*)memBig_g[x])
      {
        y = x / MVAR_BITS;
        x &= MVAR_BITS - 1;
        atabBig_g[y] &= ~(1 << x);
        POS_SCHED_UNLOCK;
        return;
      }
    }
  }
  POS_SCHED_UNLOCK;
}

#endif



/*---------------------------------------------------------------------------
 * INITIALIZE THIS PORT
 *-------------------------------------------------------------------------*/

void p_pos_initArch(void)
{
  unsigned short *pvect;
  unsigned short seg, ofs;

#if (POSCFG_TASKSTACKTYPE == 1)
  mem_init();
#endif

  /* disable interrupts */
  POS_SCHED_LOCK;

  /* set pico/OS interrupt vector for software context switch */
  pvect = (unsigned short*) ((void*) MK_FP(0, OSINT * 4));
  *pvect++ = (unsigned short) FP_OFF(_pos_softCtxSw); 
  *pvect   = (unsigned short) FP_SEG(_pos_softCtxSw);

  /* enable interrupts */
  POS_SCHED_UNLOCK;
}


void p_installInterrupts(void)
{
  unsigned short *pvect;
  unsigned short seg, ofs;

  /* disable interrupts */
  POS_SCHED_LOCK;

  /* copy original DOS timer interrupt vector */
  pvect = (unsigned short*) ((void*) MK_FP(0, TMRINT * 4));
  ofs = *pvect++;
  seg = *pvect;
  pvect = (unsigned short*) ((void*) MK_FP(0, DOSTMRINT * 4));
  *pvect++ = ofs;
  *pvect   = seg;

  /* set pico]OS timer interrupt vector (18 ticks per second) */
  pvect = (unsigned short*) ((void*) MK_FP(0, TMRINT * 4));
  *pvect++ = (unsigned short) FP_OFF(_timerIrq); 
  *pvect   = (unsigned short) FP_SEG(_timerIrq);

#ifdef POSNANO
  /* copy original DOS keyboard interrupt vector */
  pvect = (unsigned short*) ((void*) MK_FP(0, KEYBINT * 4));
  ofs = *pvect++;
  seg = *pvect;
  pvect = (unsigned short*) ((void*) MK_FP(0, DOSKEYBINT * 4));
  *pvect++ = ofs;
  *pvect   = seg;

  /* set pico]OS keyboard interrupt vector */
  pvect = (unsigned short*) ((void*) MK_FP(0, KEYBINT * 4));
  *pvect++ = (unsigned short) FP_OFF(_keyboardIrq); 
  *pvect   = (unsigned short) FP_SEG(_keyboardIrq);
#endif

  /* enable interrupts */
  POS_SCHED_UNLOCK;
}


/* bridge to software context switch handler (arch_a.asm) */
void p_pos_softContextSwitch(void)
{
#ifdef WATCOM
  _asm {"int 0x80"}; /* this will call _pos_softCtxSw() */
#else
  asm INT OSINT;  /* this will call _pos_softCtxSw() */
#endif
}



/*---------------------------------------------------------------------------
 * INIT TASK CONTEXT  (and allocate stack memory if supposed)
 *-------------------------------------------------------------------------*/

#if (POSCFG_TASKSTACKTYPE == 0)

void p_pos_initTask(POSTASK_t task, void *user,
                   POSTASKFUNC_t funcptr, void *funcarg)
{
  unsigned short var_ds, *st;

  st = (unsigned short*)(((char*)user)-1);  /* get stack pointer */

  /* get current DS */
#ifdef WATCOM
  _asm {"mov var_ds, ds" };
#else
  asm { mov var_ds, ds };
#endif

  /* setup the stack */
  *st-- = FP_SEG(funcarg);      /* function call with one argument */
  *st-- = FP_OFF(funcarg);         
#if (POSCFG_FEATURE_EXIT != 0)
  *st-- = FP_SEG(posTaskExit);  /* ptr to task exit function */
  *st-- = FP_OFF(posTaskExit);  /* (call posTaskExit when task func returns)*/
#else
  *st-- = FP_SEG(funcptr);      /* ptr to task entry function */
  *st-- = FP_OFF(funcptr);      /* (restart task when task func returns)*/
#endif
  *st-- = 0x0202;               /* SW = interrupts enabled */
  *st-- = FP_SEG(funcptr);      /* ptr to task entry function */
  *st-- = FP_OFF(funcptr);
  *st-- = 0; /* AX */
  *st-- = 0; /* CX */
  *st-- = 0; /* DX */
  *st-- = 0; /* BX */
  *st-- = 0; /* SP */
  *st-- = 0; /* BP */
  *st-- = 0; /* SI */
  *st-- = 0; /* DI */
  *st-- = var_ds;  /* _DS; */ /* current DS */
  *st   = 0; /* ES */
  task->stackptr = (void*) st;
}


#elif (POSCFG_TASKSTACKTYPE == 1)


VAR_t p_pos_initTask(POSTASK_t task, UINT_t stacksize,
                     POSTASKFUNC_t funcptr, void *funcarg)
{
  unsigned short var_ds, *st;

  /* get current DS */
#ifdef WATCOM
  _asm {"mov var_ds, ds" };
#else
  asm { mov var_ds, ds };
#endif
  
  /* allocate stack memory */
  st = (unsigned short*) my_malloc(stacksize);
  if (st == NULL)
    return -1;

  task->stackroot = st;
  st += (stacksize / sizeof(unsigned short)) - 1;

  /* setup the stack */
  *st-- = FP_SEG(funcarg);      /* function call with one argument */
  *st-- = FP_OFF(funcarg);         
#if (POSCFG_FEATURE_EXIT != 0)
  *st-- = FP_SEG(posTaskExit);  /* ptr to task exit function */
  *st-- = FP_OFF(posTaskExit);  /* (call posTaskExit when task func returns)*/
#else
  *st-- = FP_SEG(funcptr);      /* ptr to task entry function */
  *st-- = FP_OFF(funcptr);      /* (restart task when task func returns)*/
#endif
  *st-- = 0x0202;               /* SW = interrupts enabled */
  *st-- = FP_SEG(funcptr);      /* ptr to task entry function */
  *st-- = FP_OFF(funcptr);
  *st-- = 0; /* AX */
  *st-- = 0; /* CX */
  *st-- = 0; /* DX */
  *st-- = 0; /* BX */
  *st-- = 0; /* SP */
  *st-- = 0; /* BP */
  *st-- = 0; /* SI */
  *st-- = 0; /* DI */
  *st-- = var_ds;  /* _DS; */ /* current DS */
  *st   = 0; /* ES */

  task->stackptr = (void*) st;
  return 0;
}

void  p_pos_freeStack(POSTASK_t task)
{
  my_free(task->stackroot);
}


#elif (POSCFG_TASKSTACKTYPE == 2)


VAR_t p_pos_initTask(POSTASK_t task,
                     POSTASKFUNC_t funcptr, void *funcarg)
{
  unsigned short var_ds, *st;

  /* get current DS */
#ifdef WATCOM
  _asm {"mov var_ds, ds" };
#else
  asm { mov var_ds, ds };
#endif
  
  /* Get stack pointer.
   * This is very simple because the stack memory
   * (with fixed size) is in the task structure.
   */
  st = &task->stack[FIXED_STACK_SIZE-1];

  /* setup the stack */
  *st-- = FP_SEG(funcarg);      /* function call with one argument */
  *st-- = FP_OFF(funcarg);         
#if (POSCFG_FEATURE_EXIT != 0)
  *st-- = FP_SEG(posTaskExit);  /* ptr to task exit function */
  *st-- = FP_OFF(posTaskExit);  /* (call posTaskExit when task func returns)*/
#else
  *st-- = FP_SEG(funcptr);      /* ptr to task entry function */
  *st-- = FP_OFF(funcptr);      /* (restart task when task func returns)*/
#endif
  *st-- = 0x0202;               /* SW = interrupts enabled */
  *st-- = FP_SEG(funcptr);      /* ptr to task entry function */
  *st-- = FP_OFF(funcptr);
  *st-- = 0; /* AX */
  *st-- = 0; /* CX */
  *st-- = 0; /* DX */
  *st-- = 0; /* BX */
  *st-- = 0; /* SP */
  *st-- = 0; /* BP */
  *st-- = 0; /* SI */
  *st-- = 0; /* DI */
  *st-- = var_ds;  /* _DS; */ /* current DS */
  *st   = 0; /* ES */
  task->stackptr = (void*) st;
  
  return 0;
}

void  p_pos_freeStack(POSTASK_t task)
{
  /* this function is called but not needed */
  (void) task;
}

#endif

⌨️ 快捷键说明

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