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

📄 test.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.
 *
 */


/**
 * @file    test.c
 * @brief   pico]OS test program
 * @author  Dennis Kuschel
 *
 * This file is originally from the pico]OS realtime operating system
 * (http://picoos.sourceforge.net).
 *
 * CVS-ID $Id: test.c,v 1.3 2004/03/13 19:11:25 dkuschel Exp $
 */

#ifndef _NORTLIB
#include <stdio.h>
#endif
#include <picoos.h>


/* FUNCTION PROTOTYPES */
static POSTASK_t    startTask(POSTASKFUNC_t fp, void *arg, UVAR_t prio);
static void         task1(void* arg);
static void         task_printer(void *arg);
static void         task_poll(void *arg);
static void         task_flag(void *arg);
static void         task_timer(void* arg);
static void         task_mutex(void *arg);
static void         print(const char *string);


/* GLOBAL VARIABLES */
static POSTASK_t     printertask_g;
static POSFLAG_t     flags_g;
static POSSEMA_t     timersem_g;
static POSMUTEX_t    mutex_g;
static POSSEMA_t     sema_g;


/* STRING PRINT MACRO */
#ifndef _NORTLIB
#ifndef PRINTSTR
#define PRINTSTR(str)  printf("%s", str)
#endif
#endif


/*=========================================================================*/
#if (POSCFG_TASKSTACKTYPE == 0)
#define STACKMEMSIZE  0x6000
static unsigned short stack_g[STACKMEMSIZE/sizeof(unsigned short)];
static int stkmemp_g = 0;
static void *allocstack(int size);
/* Allocate stack memory. This function is architecture specific.
   This code is for a stack that grows from top down to bottom
   at a 16 bit machine, e.g. a 80x86 processor in real mode. */
static void *allocstack(int size)
{
  unsigned short *stp;
  stkmemp_g += size & ~1;
  stp = &stack_g[stkmemp_g/sizeof(unsigned short) -1];
  return (void*) stp;
}
#endif
/*-------------------------------------------------------------------------*/
static POSTASK_t startTask(POSTASKFUNC_t fp, void *arg, UVAR_t prio)
{
#if (POSCFG_TASKSTACKTYPE == 0)
  return posTaskCreate(fp, arg, prio, allocstack(0x0600));
#elif (POSCFG_TASKSTACKTYPE == 1)
  return posTaskCreate(fp, arg, prio, 0x0600);
#elif (POSCFG_TASKSTACKTYPE == 2)
  return posTaskCreate(fp, arg, prio);
#endif
}
/*=========================================================================*/


static void task_printer(void *arg)
{
  char *buf;

  (void) arg;

  for (;;)
  {
    /* get message */
    buf = posMessageGet();

    /* print content to screen */
    PRINTSTR(buf);

    /* free message buffer */
    posMessageFree(buf);
  }
}

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

static void print(const char *string)
{
  char *d, *s = (char*) string;
  char *buf;

  /* allocate message buffer */
  buf = posMessageAlloc();

  /* copy string into message buffer */
  for (d = buf; *s != 0; d++, s++)
  {
    *d = *s;
  }
  *d = 0;

  /* send message to printer task */
  posMessageSend(buf, printertask_g);
}

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

static void softint_handler(UVAR_t param)
{
  posFlagSet(flags_g, param);
}

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

static void task_poll(void *arg)
{
  char  *text = (char*) arg;
  JIF_t  now, exptime;

  now = jiffies;

  for (;;)
  {
    /* do busy waiting for 1/2 second */
    exptime = now + (HZ / 2);
    do
    {
      now = jiffies;
    }
    while (!POS_TIMEAFTER(now, exptime));

    /* print text every 1/2 second */
    print(text);
  }
}

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

static void task_softint(void *arg)
{
  UVAR_t intno = (UVAR_t) arg;
  JIF_t  now, exptime;
  UVAR_t c;

  c = 0;
  now = jiffies;

  for (;;)
  {
    /* do busy waiting for 1 2/3 seconds */
    exptime = now + HZ + (2*HZ / 3);
    do
    {
      now = jiffies;
    }
    while (!POS_TIMEAFTER(now, exptime));

    /* rise software interrupt every 1.67 seconds */
    posSoftInt(intno, 6);

    c++;
    if (c == 2)
    {
      posTaskYield();
    }
    if (c == 3)
    {
      posTaskSleep(1);
      c = 0;
    }
  }
}

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

static void task_flag(void *arg)
{
  char  buf[5];
  VAR_t f;

  (void) arg;

  buf[0] = '>';
  buf[1] = 'F';
  buf[3] = ' ';
  buf[4] = '\0';

  for (;;)
  {
    /* wait for flag event and get flag number */
    f = posFlagGet(flags_g, POSFLAG_MODE_GETSINGLE);

    /* print flag number */
    buf[2] = '0' + (char) f;
    print(buf);
  }
}

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

static void task_timer(void* arg)
{
  (void) arg;

  for (;;)
  {
    /* wait for semaphore to be signalled */
    posSemaGet(timersem_g);

    /* Set flag. The flag number will be printed out by the flag task. */
    posFlagSet(flags_g, 3);
  }
}

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

static void task_mutex(void *arg)
{
  static INT_t cntr = 0;
  char  *text = (char*) arg;

  for (;;)
  {  
    /* try to get mutex and lock */
    posMutexLock(mutex_g);

    cntr++;

    /* sleep one second */
    posTaskSleep(HZ);

    /* print text */
    print(text);

    cntr--;
    if (cntr != 0)
      print("MUTEX-ERROR");

    /* unlock mutex again */
    posMutexUnlock(mutex_g);
  }
}

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

static void task_semas(void *arg)
{
  static INT_t cntr = 0;
  char  buf[5];

  buf[1] = 'S';
  buf[2] = (char) ((int)arg);
  buf[3] = ' ';
  buf[4] = '\0';

  (void) arg;

  for (;;)
  {  
    /* try to get semaphore */
    posSemaGet(sema_g);

    cntr++;

    /* sleep one second */
    posTaskSleep(HZ);

    /* print information, how many tasks are in this function */
    buf[0] = '0' + (char) cntr;
    print(buf);
    if ((cntr < 1) || (cntr > 2))
    {
      print("SEMAPHORE-ERROR");
    }

    cntr--;

    /* release semaphore again */
    posSemaSignal(sema_g);
  }
}


/*=========================================================================*/


static void task1(void *arg)
{
  POSTASK_t  self;
  POSTIMER_t timer;
  VAR_t      curprio;

  (void) arg;

  /* get handle and priority of current task */
  self    = posTaskGetCurrent();
  curprio = posTaskGetPriority(self);

  /* try to increase current priority */
  posTaskSetPriority(self, curprio + 1);
  curprio = posTaskGetPriority(self);

  /* start the printer task */
  printertask_g = startTask(task_printer, NULL, curprio + 1);

  /* print first message */
  print("HELLO WORLD!\n");

  /* start three tasks that do busy waiting */
  startTask(task_poll, " P1 ", curprio - 1);
  posTaskSleep(HZ/8);
  startTask(task_poll, " P2 ", curprio - 1);
  posTaskSleep(HZ/8);
  startTask(task_poll, " P3 ", curprio - 1);

  /* register software interrupt handler */
  posSoftIntSetHandler(4, softint_handler);

  /* start a task that rises software interrupts */
  startTask(task_softint, (void*) 4, curprio - 1);

  /* allocate a flag object */
  flags_g = posFlagCreate();
  if (flags_g == NULL)
    print("\nCan not allocate a flag object\n");

  /* start flag task */
  startTask(task_flag, NULL, curprio + 2);

  /* allocate a semaphore object */
  timersem_g = posSemaCreate(0);
  if (timersem_g == NULL)
    print("\nCan not allocate a semaphore\n");

  /* start timer task */
  startTask(task_timer, NULL, curprio + 2);

  /* allocate a timer object and set the timer up */
  timer = posTimerCreate();
  if (timer == NULL)
    print("\nCan not allocate a timer\n");
  posTimerSet(timer, timersem_g, 2*HZ, 2*HZ);

  /* Start the timer. The timer triggers every 2 seconds. */
  posTimerStart(timer);

  /* allocate a mutex object for mutex test */
  mutex_g = posMutexCreate();
  if (mutex_g == NULL)
    print("\nCan not allocate a mutex\n");

  /* start three mutex tasks */
  startTask(task_mutex, ":M1 ", curprio+1);
  startTask(task_mutex, ":M2 ", curprio+1);
  startTask(task_mutex, ":M3 ", curprio+1);

  /* allocate semaphore object for semaphore test,
     allow 2 tasks to get the semaphore */
  sema_g = posSemaCreate(2);
  if (sema_g == NULL)
    print("\nCan not allocate a semaphore\n");

  /* start three semaphore tasks */
  posTaskSleep(HZ/6);
  startTask(task_semas, (void*) (int) '1', curprio+2);
  posTaskSleep(HZ/6);
  startTask(task_semas, (void*) (int) '2', curprio+2);
  posTaskSleep(HZ/6);
  startTask(task_semas, (void*) (int) '3', curprio+2);

  /* Our main loop. We will set the flag number 2 every 3 seconds. */
  for (;;)
  {
    /* suspend this task for 3 seconds */
    posTaskSleep(3*HZ);

    /* set flag number 2 */
    posFlagSet(flags_g, 2);
  }
}


/*=========================================================================*/


int main(void)
{
  PRINTSTR("\n" POS_STARTUPSTRING "\n\n");

  /* start multitasking and execute first task (task1) */
#if (POSCFG_TASKSTACKTYPE == 0)
  posInit(task1, NULL, 1, allocstack(0x0600), allocstack(0x0200));
#elif (POSCFG_TASKSTACKTYPE == 1)
  posInit(task1, NULL, 1, 0x0600, 0x0200);
#elif (POSCFG_TASKSTACKTYPE == 2)
  posInit(task1, NULL, 1);
#endif

  /* we will never get here */
  return 0;
}

⌨️ 快捷键说明

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