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

📄 avrxfifo_documentation.txt

📁 一个基于AVR 单片机的操作系统,有组于了解操作系统在单片机上运行的内幕.
💻 TXT
字号:
Sept, 14, 2005

AvrXFifo requires AvrX 2.6f or newer.

AvrX 2.6f contains some significant changes to support AvrXFifos.  The changes
should be 100% backward compatible to previous 2.6 versions.  The change
primarily allows interrupt handler to directly call AvrXSetSemaphore().  Older
versions of AvrX probably will work, but an extra context will be temporarily
pushed onto the kernel stack during the Set Semaphore processing.

Files:
	AvrXFifo.h
	AvrXFifo.c

Notes on declaration & usage of AvrXFifo's:

	Maximum fifo size is 256 bytes.  Most practical systems only need a few
	bytes to buffer interrupt handlers or protocols (e.g. large enough for
	the biggest outgoing packet, for example).   If this limit is too small,
	see "Future Expansion" below.

	The user can declare and initialize Fifo's explicitly, in code, or use
	some handy #define MACROs to do the job.  To do this manually follow
	this template:

	Outside of your code (e.g. global data memory)

		uint8_t SomeBuffer[sizeof(AvrXFifo) + DesiredBufferSize];
		static const pAvrXFifo FifoName = (pAvrXFifo)SomeBuffer;

	Or use the macro

		AVRX_DECL_FIFO(FifoName, FifoSize);

	or if external

		extern uint8_t SomeBuffer[];
		static const pAvrXFifo FifoName = (pAvrXFifo)SomeBuffer;

	Or use the macro

		AVRX_EXT_FIFO(FifoName);

	In your code, initialize the fifo:

		FifoName->size = DesiredBufferSize;
		AvrXFlushFifo(FifoName);

	Or use the macro

		AVRX_INIT_FIFO(FifoName);

	To use the fifo:

	int retc = AvrXPutFifo(FifoName, data);	// Place data in fifo
	int foo = AvrXPullFifo(FifoName);	// Get data from fifo
	AvrXWaitPutFifo(FifoName, data);	// Place data in fifo, blocks if full
	int foo = AvrXWaitPullFifo(FifoName);	// Get data from fifo, blocks if empty
	int size = AvrXPeekFifo(FifoName);	// Check size of fifo
	AvrXFlushFifo(FifoName);		// Flush fifo & release producer.
	int foo = AvrXDelFifo(FifoName);	// Remove last item placed in fifo

	Return Values:
		FIFO_ERR (-1)	fifo full or empty and operation can't be completed
		FIFO_OK  (0)	operation successful
		unsigned int	Char data, zero extended for successful removal

	GCC produces poor code when comparing to literal 0 (there are reasons
	why this is correct).  GCC generates good AVR code when testing results
	for < 0. e.g.

	if ((c = AvrXPullFifo(FifoName)) < FIFO_OK)	// rather than ==
	    // empty...
	else
	    // Do something with c which is unsigned char data.

	Because the pointer to the Fifo is declared as a static const value, no
	actual storage is used.  The compiler is smart enough to just use the
	address of the byte buffer when referencing the fifo.  Optimal code is
	generated.


Macros:

	Macros hide the need to record the size for initialization, otherwise
	are identical to the explicit C code.  The only caveat is that the init
	macro needs to be in the same file as the declaration macro.  This is
	also good programming practice to keep declarations and initialization
	in one file.

Synchronization:

	AvrXFifo's have built in synchronization between producers (put) and
	consumers (pull).  Producers and consumers can be either tasks or
	interrupt handlers.  Interrupt handlers, of course, cannot use the
	blocking Fifo API.

	When blocked, the producer/consumer will be come unblocked when the
	opposite side either removes or adds a data item (respectively).  There
	is no mechanism to notify an interrupt handler that something has been
	added or removed from a fifo.  See the example of the buffered serial
	I/O to see how that is handled.	In short, it is up to the task end of
	the fifo to manage coordination with the interrupt handler.

Future expansion possibilities:

	By using the fifo code as a starting point some interesting things could
	be added:

	1. Fifos could be defined as word or even arbitrary data size buffers.
	The size could be declared as multiples of the data and new get/put
	routines defined that remove the data item.  This could be made generic
	by adding the element size to the fifo data structure, at the expense of
	more code for the simple case.

	2. Routine addresses could be added to the fifo structure as call-backs
	for interrupt handlers when the fifo fills or empties.  This would allow
	a fifo to be put between two interrupt handlers.  Say a serial to serial
	buffer.  Simple tasks between handlers could be written as entirely
	kernel context code avoiding the overhead of task switching.

	3. Fifo size could be expanded beyond 254 by changing the internal size,
	in and out from uint8_t to uint16_t and modifying the fifo code
	appropriately (internal temporary values).  Also, race conditions in
	loading pointers must be taken into account.  With byte pointers CPU
	reads are atomic and no critical sections are needed.

	The current byte size data was chosen as a compromise between small
	system code and decent sized buffers.

CAVEATS:
	The fifo code has not been tested with a buffer size of 256.  It should work.

	AvrXPeekFifo() has not been tested.

	There might be race conditions

⌨️ 快捷键说明

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