📄 irq.c
字号:
/***************************************************************************
* This code and information is provided "as is" without warranty of any *
* kind, either expressed or implied, including but not limited to the *
* implied warranties of merchantability and/or fitness for a particular *
* purpose. *
* *
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
***************************************************************************/
//**************************************************************************
// DESCRIPTION: 71M652x POWER METER - implement a dual-priority monitor.
// This implements two priorities: preemptible, and non-preemptible.
// Since there's only two, priority inversion is impossible.
// Since the code runs to completion, hangs are impossible
// Since there's only one locking flag, and thus one order
// to get it, deadlocks are impossible.
// Therefore, it's the guts of a very reliable exokernel.
// Critical regions have to be kept brief, though! 100 microseconds
// is a recommended maximum.
//
// We use this scheme instead of the more typical scheme that
// just disables a single device's interrupt, because the single
// device scheme can cause priority inversion. E.g. a serial
// interrupt may be disabled in the main loop. Another device's (a timer...)
// interrupt preempts the CPU because its interrupt is not locked.
// The preempting interrupt may be lower priority... and cause
// the serial interrupt to be delayed so much that data is lost.
//
// AUTHOR: RGV
//
// HISTORY: See end of file.
//**************************************************************************
// File: irq.
//
#include "options.h"
#include "irq.h"
/*** External functions used by this module ***/
// None.
/*** External variables used within this module ***/
// None.
/*** Public functions declared within this module ***/
// See irq.h
/*** Public variables declared within this module ***/
// None.
/*** Private functions declared within this module ***/
// None.
/*** Private variables declared within this module ***/
// This uses less space than a system that places
// the interrupt state on the stack.
// It's almost as fast, when reentrant variables are used (as they
// often must be).
bool irq_state = TRUE; // the "outer" state of a nested set of states.
uint8_t nest_cnt = 0; // counts nesting of interrupt-disable calls
// This routine should be called at the start of a critical region.
// It disables the interrupt state, and can be called
// from nested subroutine calls.
#pragma save
#pragma NOAREGS
void irq_disable (void) small reentrant
{
// local variable of a reentrant fn is mutex-safe
register uint8_t ea_temp;
ea_temp = EA; // copy the interrupt state
IE &= ~EA_; // disable all interrupts
// The increment is done while interrupts are disabled,
// and is therefore reentrant and mutex-safe, even though it uses
// a global variable.
if (nest_cnt++ == 0) // if at the outer call, save the state
{
irq_state = ea_temp;
}
// otherwise, the interrupt state is managed- discard it.
}
#pragma restore
// This routine should be called at the end of a critical region.
// It restore the interrupt state, and can be called
// from nested subroutine calls.
#pragma save
#pragma NOAREGS
void irq_enable (void) small reentrant
{
// The decrement is done while interrupts are disabled,
// and is therefore reentrant and mutex-safe.
if (--nest_cnt == 0) // if at the outer call, restore the state
{
if (irq_state) // restore the saved interrupt state
IE |= EA_;
}
// otherwise, the interrupt state is nested, and should
// remain disabled.
}
#pragma restore
void irq_init (void)
{
EA = FALSE; // assure that interrupts start disabled
irq_state = TRUE; // and will resume as enabled
nest_cnt = 1; // from an unbalanced first call of irq_enable ()
}
/***************************************************************************
* $Log: irq.c,v $
* Revision 1.5 2006/09/09 01:15:19 gmikef
* *** empty log message ***
*
* Revision 1.4 2006/01/16 20:11:32 tvander
* Clean Keil build, all versions
*
* Revision 1.2 2005/11/02 21:32:01 gmikef
* Made IE changes tracible.
*
* Revision 1.1 2005/10/08 04:41:32 tvander
* Fixed priority inversion.
* Rewrote watchdog to work in brownout, but of course it doesn't work.
* Watchdog can now be defeated by clearing watchdog option to 0.
* Reorganized watt hour modules (at last!).
* Disabled reading of STATUS in 6521_cli because the CE's status is always SAG.
* Tested with 6521_CLI; measurements seem to work.
* Fixed other builds.
*
*
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
* this program is fully protected by the United States copyright *
* laws and is the property of Teridian Semiconductor Corporation. *
***************************************************************************/
// events.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -