📄 avrx_notes.txt
字号:
Notes to myself:
----------------------------------------------------------------------------------------
Post 9/13/05
Look into preserving I flag across more routines.
Port more facilities to C for debugging pleasure (messages? AvrXReschedule?)
Move critical AvrX data structures to C files for debugging pleasure:
AvrXKernelData
AvrXTimerQueue
-----------------------------------------------------------------------------------------
9/13/05 - Update AvrX for avr-gcc 3.4.3, implement generic fifo support, incorporate
IAR EWB 4.10 changes, add more example code (serial i/o, complex interrupt
handler i/f with timeout.
1. Modified avrx_semaphore.s::AvrXSetSemaphore()
a) to preserve the state of the I flag
b) to NOT reschedule if either no change in the current running task, or in
the kernel context (i.e. interrupt handler): This allows AvrXIntSetSemaphore() to
go away as seperate code. This should be 100% backward compatible.
2. Modified avrx_tasking.s::QueuePid() to preserve the state of the I flag. This along with
the previous change facilitate better control of writing interrupt handlers as the interrupts
are not "enabled" magically when AvrX calls are made. This change required an additional stack
push (two total).
3. Modified AvrX.H to use __attribute__((noreturn)) for tasks as the code is
as good as NAKED, and the frame pointer is correctly set up. AvrX Still uses
NAKED for interrupt handlers since the do "return" and having a frame pointer
is meaningless given that the stack is swapped *after* the frame is set up.
4. Added new AvrX Function: variable length fifo with synchonization. AvrXFifo is written in C
and has it's own header file. The resulting object module, however, is carried in avrx.a
5. Added new directory "AvrXIO" that contains:
a) Simple and buffered I/O drivers (single source code base for all
AVR processor USARTS) It can't be a library and must be compiled
for the particular target
b) Added All C Code "AvrXFifo.c" and "AvrXFifo.h", byte oriented variable
length FIFO with synchronization for tasks to task and task to interrupt
handler.
5. Incorporated changes made by steve_krepelka@yahoo.com 3/15/2005. From his original
notes:
31-March-2005
Made changes to compile using ATMega16 and ATMega128 chips with IAR EWAVR 3.20C
or 4.10B and AStudio 4.11. Added IAR workspace and project files.
(DONE) avrx.h
- Corrected a typo in AvrXKernelData structure name
- Corrected AvrXKernelData structure to remove unsigned from AvrXCStack definition
- Modified declaration of TaskControlBlock and swapped the 'const' and 'FLASH' keywords
- Changed the AVRX_EXTERNTASK() macro to use NAKEDFUNC() macro
(DONE) avrx_tasking.s
- Changed AvrXSetKernelStack to save the CStack into AvrXKernelData (IAR
compiler only), also changed IntProlog to save and restore the
CStack when entering kernel mode (IAR compiler only)
(NOT DONE)avrx.xlb
- Commented out "fetch-mod serialio avrx" line so that serialio module
would not be added to library (not used in our project).
(NOT DONE)serialio.s
- Added code to re-define registers for ATmega8, ATmega16, ATmega32,
ATmega64, and ATmega128 parts
(DONE) avrx.inc
- Replaced Lable with Label
- Changed # define _DATASECTION RSEG DATA:DATA to
# define _DATASECTION RSEG AVRXDATA:DATA
(DONE) monitor.s
- added _EXTERN(AvrXTerminate)
(DONE) avrx_suspend.s
- removed _EXTERN(RunQueue) and _EXTERN(Running)
- added _EXTERN(AvrXKernelData)
(DONE) avrx_singlestep.s
- removed _EXTERN(RunQueue)
- added _EXTERN(AvrXKernelData)
(DONE) avrx_eeprom.s
- changed EEARL+1 to EEARH
(NOT DONE)avrx-signal.h
- updated to add missing vectors and renamed incorrect entries
- as a general rule, always check defines in this file when compiling
to a new chip (this implementation does not cover everything)
- tested to work with ATmega8, ATmega16, ATmega32, ATmega64, ATmega128
(NOT DONE)avrx_iar_vect.s
- added support for new vectors
- as a general rule, always check interrupts in this file when compiling
to a new chip (this implementation does not cover everything)
- tested to work with ATmega8, ATmega16, ATmega32, ATmega64, ATmega128
(DONE) avrx_reschedule.s
- this file was never compiled into AvrX, now it is
- added _EXTERN(_QueuePid)
- added _EXTERN(_Epilog)
- added _EXTERN(IntProlog)
- added _EXTERN(_RemoveObject)
- added _EXTERN(AvrXKernelData)
- corrected f1 label in AvrXIntReschedule()
- corrected AvrXYield label
(DONE) ioavr.h
- removed this file, included with IAR compiler
(N.A.) makefile
- not needed with IAR Embedded Workbench
(N.A.) avrx.xlb
- not needed with IAR Embedded Workbench
Note: To use with IAR Embedded workbench you will need to change filename
extensions to recognize .s assembler files.
-------------------------------------------------------------------------------
6/20/02 - all suggestions, below, implemented as of 5/30/02 Actual performance
testing not done, but responding to an interrupt from IDLE should be about twice
as fast and SetSemaphore should be double to triple the speed when no or a lower
priority task has been queue (relative to the caller).
-------
AvrXSetSemaphore
AvrXIntSetSemaphore works because "Running" isn't changed until Epilog.
So setting a semaphore and queueing a pid doesn't affect the state until
the running task is interrupted. So, a further optimization would be:
rcall AvrXIntSetSemapore
BeginCritical
lds tmp0, Running+NextL ; 16 cycles if no taskswap.
lds tmp1, Running+NextH
lds tmp2, RunQueue+NextL
lds tmp3, RunQueue+NextH
cp tmp0, tmp2
cpc tmp1, tmp3
breq exit
rcall IntProlog
rjmp _Epilog
exit:
EndCriticalReturn
A better way would be to have some sort of flag set by QueuePid, as it "knows"
when something has changed the head of a queue.
In general, checking for task swap (e.g. top of queue changed) before doing actual
task swap...
This could be a general re-write of AvrX -> General scheduler in C. Just use
regular C constructs and swap contexts as needed. This would probably be pretty
fast at the expense of more task stack space needed.
Epilog/Prolog/IdleTask
Have a bit somewhere that says we are in IDLE state and skip saving context
for first entry into kernel or restoring context for 1->0 transistion.
Tasking, in general:
Critical kernel data (Running, RunQUeue, Syslevel, AvrXC_stack (IAR only)
could be a struct and all routines re-written to use that data via a pointer.
This would make for more instructions to load/reload, but faster because LDD
is only 2 cycles vs 3 for LDS.
ldi Zl, lo8(_kernel)
ldi zh, hi8(_kernel)
ldd
...
cp
...
I have an experimental version of Avrx_tasking that uses this technique (not tested)
and it looks like a push.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -