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

📄 os_alarm.c

📁 ucos277很多朋友都在找,在这贡献出来了
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * @file
 * Alarms that trigger event flags once the alarm timer runs out.
 *
 * Copyright (c) 2002, 2003 Leon Woestenberg <leon.woestenberg@axon.tv>
 * Copyright (c) 2002, 2003 Axon Digital Design B.V. http://www.axon.tv
 * 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. Neither the names of Axon Digital Design B.V. nor Leon Woestenberg
 *    not the names of contributors may be used to endorse or promote
 *    products derived from this software without specific prior written
 *    permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY AXON DIGITAL DESIGN, LEON WOESTENBERG AND
 * CONTRIBUTORS ``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 INSTITUTE
 * OR CONTRIBUTORS 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. 
 *
 */

#define  OS_ALARM_GLOBALS
#include "includes.h"

#define DBG_LEVEL 0
#if DBG_LEVEL > 0
#  include "debug.h"
#else
#  define debug_printf
#endif

#if (OS_VERSION >= 251) && (OS_ALARM_EN > 0) && (OS_MAX_ALARMS > 0)

static void OSAlarmTime(OS_ALARM *alarm, INT32U time, INT8U *err);
 
/**
 * Initialize the alarms.
 *
 * Must be called after OSInit().
 *
 */
void OSAlarmInit(void)
{
#if OS_MAX_ALARMS == 1
  OSAlarmFreeList = (OS_ALARM *)&OSAlarmTbl[0];  /* Only ONE alarm!      */
  OSAlarmFreeList->OSAlarmType = OS_ALARM_TYPE_UNUSED;
  OSAlarmFreeList->OSAlarmNext = (OS_ALARM *)0;
  OSAlarmFreeList->OSAlarmTime = 0;
#  if (OS_ALARM_PERIODIC_EN > 0)
  OSAlarmFreeList->OSAlarmPeriod = 0;
#  endif    
#endif

#if OS_MAX_ALARMS >= 2
  INT8U i;
  OS_ALARM *alarm1;
  OS_ALARM *alarm2;
  alarm1 = &OSAlarmTbl[0];
  alarm2 = &OSAlarmTbl[1];
  for (i = 0; i < (OS_MAX_ALARMS - 1); i++) {
    alarm1->OSAlarmType = OS_ALARM_TYPE_UNUSED;
    alarm1->OSAlarmTime = 0;
#if (OS_ALARM_PERIODIC_EN > 0)
    alarm1->OSAlarmPeriod = 0;
#endif    
    alarm1->OSAlarmNext = (void *)alarm2;
    alarm1++;
    alarm2++;
  }
  alarm1->OSAlarmNext = (void *)0;
  OSAlarmFreeList = (OS_ALARM *)&OSAlarmTbl[0];
#endif
  OSAlarmActiveList = (OS_ALARM *)0;
}
 
/**
 * Create an alarm.
 *
 * @param flag_group The event flag group where flags will be set when the alarm triggers.
 * @param flags These flags are set in the flag_group when the alarm triggers.
 * @param opt Alarm options mask, 
 * - OS_ALARM_PERIODIC defines a periodic alarm, which once set, retriggers after each
 * period defined using OSAlarmSet(). Periodic alarms do not drift.
 * - OS_ALARM_ONESHOT defines a one-shot alarm, which triggers once.
 * @param err Pointer to error variable.
 * - OS_NO_ERR The alarm was succesfully created.
 * - OS_ERR_CREATE_ISR Called from within interrupt, which is not allowed.
 * - OS_ALARM_DEPLETED No free alarms are available.
 * - OS_ERR_INVALID_OPT A periodic alarm was attempted to be created while support for it was
 * not available (OS_ALARM_PERIODIC_EN = 0).
 *
 * @note May not be called from inside an ISR.
 *
 */
OS_ALARM *OSAlarmCreate(OS_FLAG_GRP *flag_group, OS_FLAGS flags, INT8U opt, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                         /* Allocate storage for CPU status register        */
    OS_CPU_SR    cpu_sr;
#endif
  OS_ALARM *alarm;
#if ((OS_ARG_CHK_EN > 0) && (OS_ALARM_PERIODIC_EN == 0))
  if (opt & OS_ALARM_PERIODIC)
  {
    /* failure, cannot create a period alarm if period alarms are disabled */
    *err = OS_ERR_INVALID_OPT;
    return ((OS_ALARM *)0);
  }
#endif
  if (OSIntNesting > 0) {                         /* See if called from ISR ...                      */
    *err = OS_ERR_CREATE_ISR;                   /* ... can't CREATE from an ISR                    */
    return ((OS_ALARM *)0);
  }
  OS_ENTER_CRITICAL();
  alarm = OSAlarmFreeList;                          /* Get next free alarm                        */

  if (alarm != (OS_ALARM *)0) {                 /* See if we have alarms available      */
    /* Adjust free list */
    OSAlarmFreeList = (OS_ALARM *)OSAlarmFreeList->OSAlarmNext;
    /* initialize alarm */
    alarm->OSAlarmType = OS_ALARM_TYPE_IDLE;  /* Set to alarm type                    */
    alarm->OSAlarmFlagGrp = flag_group;                    /* event flag group to trigger on alarm */
    alarm->OSAlarmFlags = flags;
#if (OS_ALARM_PERIODIC_EN > 0)
    /* this indicates it is a period alarm type for OSAlarmSet() */
    alarm->OSAlarmPeriod = (opt & OS_ALARM_PERIODIC);
#endif
    alarm->OSAlarmNext = (void *)0;           /* Clear list */
    OS_EXIT_CRITICAL();
    *err = OS_NO_ERR;
  /* free alarms list is empty */
  } else {
    OS_EXIT_CRITICAL();
    *err = OS_ALARM_DEPLETED;
  }
  return (alarm);                                  /* Return pointer to alarm              */
}

/**
 * Delete an alarm
 *
 * @param alarm The (idle) alarm to be deleted.
 * @param err Pointer to error variable
 *
 * @note May not be called from inside an ISR.
 * @note The alarm must be disabled. If the alarm is active, use OSAlarmDisable() first.
 * @see OSAlarmDisable()
 */
void OSAlarmDel(OS_ALARM *alarm, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                         /* Allocate storage for CPU status register        */
    OS_CPU_SR    cpu_sr;
#endif
  OS_ENTER_CRITICAL();
#if (OS_ARG_CHK_EN > 0)
  /* is this a non-idle alarm? */
  if (alarm->OSAlarmType != OS_ALARM_TYPE_IDLE)
  {
    OS_EXIT_CRITICAL();
    *err = OS_ERR_ALARM_TYPE;
    return; 
  }
#endif /* OS_ARG_CHK_EN */
  /* free alarm */
  alarm->OSAlarmType = OS_ALARM_TYPE_UNUSED;
  /* put OSAlarm at head of freelist */
  alarm->OSAlarmNext = (void *)OSAlarmFreeList;
  OSAlarmFreeList = alarm;
  OS_EXIT_CRITICAL();
  *err = OS_NO_ERR;
  return; 
}

/**
 * Disable an active alarm
 *
 * @param alarm The (active) alarm to be disabled.
 * @param err Pointer to error variable
 * - OS_ERR_ALARM_TYPE is returned if the alarm was not active. This is not necessarily an
 * error, as a one-shot alarm could have become non-active when it was triggered.
 * - OS_NO_ERR The alarm is disabled.
 *
 * @see OSAlarmSet() to set and enable the alarm again.
 */
void OSAlarmDisable(OS_ALARM *alarm, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3                         /* Allocate storage for CPU status register        */
    OS_CPU_SR    cpu_sr;
#endif
  OS_ENTER_CRITICAL();
  /* alarm not active, or no active alarms in list? */
  if ((alarm->OSAlarmType != OS_ALARM_TYPE_ACTIVE) || (OSAlarmActiveList == (OS_ALARM *)0))
  {
    OS_EXIT_CRITICAL();
    /* the alarm was not active */
    /* this is not necessarily an error, as the alarm could have triggered
       before the caller was notified through OSFlagGrp. */
    *err = OS_ERR_ALARM_TYPE;
    return; 
  }
  /* alarm is head of active list? */
  else if (OSAlarmActiveList == alarm)
  {
    /* remove from active list */
    OSAlarmActiveList = alarm->OSAlarmNext;
  }
  /* multiple alarms on active list */
  else
  {
    OS_ALARM *pred = OSAlarmActiveList;
    /* find predecessor of this alarm */
    while ((pred != (OS_ALARM *)0) && (pred->OSAlarmNext != alarm))
    {
      /* proceed to next in active list */
      pred = pred->OSAlarmNext;
    }
    /* alarm is not present in alarm active list? */
    if (pred == (OS_ALARM *)0)
    {
      OS_EXIT_CRITICAL();
      /* failure, this alarm was not found in OSAlarmActiveList */
      *err = OS_ERR_ALARM_TYPE;
      return; 

⌨️ 快捷键说明

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