原创 MAGA系列AVR单片机的嵌入式操作

2008-7-7 22:32 2446 7 8 分类: MCU/ 嵌入式

AVRX Theory: 原理


 


Note: the file arvx.inc provides definitions for much of the following.


Control Blocks / Structures:
  TimerControlBlock:
    This is a six byte structure consisting of:
      *next - pointer to the next element in the TCB queue
      semaphore - task(s) owning this TCB (?)
      count - 16 bit number of timer ticks
     
  TimerMessageBlock
    Similar to the TCB, the TMB sends messages rather than a semaphore.  The
    structure appears to consist of the union of a MessageControlBlock and a
    TimerControlBlock.
   
  MessageControlBlock
    This is to message queues as the TCB is to timer queues.  The structure
    consists of four bytes:
      *next - pointer to the next element in the MCB queue
      semaphore - task(s) owning this MCB (?)
   
  PID
    The size of the Process ID varies depending on whether single-stepping is
    enabled, which adds two unsigned char values.  The standard PID is defined
    as:
      *next - pointer to the next PID in the chain
      flags/priority - unsigned char
      *ContextPointer - ?


  Mutex
    Mutex semaphores are a simple linked list of waiting processes.  The mutex
    may have the following values:


      SEM_PEND (0)     // Semaphore is reset waiting for a signal
      SEM_DONE (1)     // Semaphore has been triggered.
      SEM_WAIT (2)     // Any other value is the address of a processID


    The primary difference between a mutex and a semaphore is a mutex is owned
    by the process which locked it where a semaphore is not; a semaphore can
    be unlocked by another process.


  System Object
    A System Object consists of a link (16 bit pointer) and a semaphore and is
    followed by 0 or more bytes of data.
   


Macros:
  AVRX_GCC_TASKDEF(start, c_stack, priority)
  AVRX_GCC_TASK(start, c_stack, priority)
  AVRX_SIGINT(vector)


APIs:


  TASKS:
 
  * AvrXInitTask (avrx_tasking.s)
      Format: AvrXinitTask(&taskTCB);
      This API will simply initialize a given task by saving the registers on
      the appropriate stack and initializing all registers to be used to zero.


  * AvrXRunTask (avrx_tasking.s)
      Format: AvrRunTask(&taskTCB);
      This API will start a task by first calling the AvrXInitTask followed by
      calling AvrXResume.  Either this or AvrXInitTask must be called by main()
      to get things going.
     
  * AvrXSuspend (avrx_suspend.s)
      Format: AvrXSuspend(&taskPID);
      This API marks a PID for suspension and attempts to remove it from the
      run queue.


  * AvrXResume (avrx_tasking.s)
      Format: AvrXResume(&taskPID);
      This API gets a task ready to run again by inserting the PID into the
      run queue. 


  * AvrXTaskExit (avrx_terminate.s)
      Format: AvrXTaskExit;
      This API should be called when a task is complete and will no longer
      run.  It acts like the "return" in a normal function.  Ideally, the task
      should be idle (not waiting on any semiphores) before this is called.
     
  * AvrXTerminate (avrx_terminate.s)
      Format: AvrXTerminate(&taskPID);
      Similar to the AvrXTaskExit function except that this one is used to
      kill another task.
     
  * AvrXHalt (avrx_halt.s)
      Format: AvrXHalt;
      This API effectively halts the processor by disabling interrupts and
      then doing a "branch self".


     
  SEMAPHORES:
 
  * AvrXSetSemaphore (avrx_semaphores.s)
      Format: AvrXSetSemaphore(&mutex);
      This API will set a semaphore if it is not already set.
 
  * AvrXIntSetSemaphore (avrx_semaphores.s)
      Format: AvrXIntSetSemaphore(&mutex);
      Same as AvrXSetSemaphore above except that this one assumes that code
      has already switched to the system stack (such as an interrupt handler).
     
  * AvrXWaitSemaphore (avrx_semaphores.s)
      Format: AvrXWaitSemaphore(&mutex);
      This API will cause a task to queue up for a semaphore, implementing a
      Mutual Exclusion Semaphore (mutex).  If used for simple signaling
      purposes then only one task should wait on the semaphore.


  * AvrXTestSemaphore (avrx_testsmaphore.s)
      Format: AvrXTestSemaphore(&mutex);
      A non-blocking call to check the state of a semaphore.  Returns one of
      the following: SEM_PEND, SEM_DONE or SEM_WAIT.


  * AvrXIntTestSemaphore (avrx_testsmaphore.s)
      Format: AvrXIntTestSemaphore(&mutex);
      Same as the AvrXTestSemaphore except that it assumes that code has
      already switched to the system stack.
 
  * AvrXResetSemaphore (avrx_resetsemaphore.s)
      Format: AvrXResetSemaphore(&mutex);
      This API forces a semaphore to the SEM_PEND state.
     


  TIMERS:
 
  * AvrXStartTimer (avrx_timequeue.s)
      Format: AvrXStartTimer(&TCB, unsigned);
      This non-blocking API will add the TCB into the timer queue using the
      second parameter as the wait time (number of timer ticks).
     
  * AvrXDelay (avrx_timequeue.s)
      Format: AvrXDelay(&TCB, unsigned);
      This is a blocking version of AvrXStartTimer and has the same parameters.
      It is implemented by calling AvrXStartTimer followed by AvrXWaitTimer.


  * AvrXTimerHandler (avrx_timequeue.s)
      Format: AvrXTimerHandler();
      This is an ISR that must be called within a _Prolog/_Epilog section.  Be
      careful; most registers are trashed by the call.


  * AvrXCancelTimer (avrx_canceltimer.s)
      Format: AvrXCancelTimer(&TCB);
      This API will dequeue a TCB from the TCB chain.  Returns a pointer to
      the removed timer or a 0 on failure.


  * AvrXWaitTimer (avrx_semaphores.s)
      Format: AvrXWaitTimer(&TCB);
      This blocking API call will wait on a timer to expire.


  * AvrXTestTimer (avrx_testsemaphore.s)
      Format: AvrXTestTimer(&TCB);
      This non-blocking API call tests the state of a timer.  Returns one of
      SEM_WAIT, SEM_PEND or SEM_DONE.
     
  * AvrXStartTimerMessage (avrx_starttimermessage.s)
      Format: AvrXStartTimerMessage(&TMB, unsigned, &MessageQueue);
      This API will start a timer that sends a message when a timeout occurs.
      One case where this might be useful is where you want to time out an
      input message.  Start a timer that sends a message to the same message
      queue and then wait on the queue.  When something shows up it will either
      be the expected message or a timeout message.


  * AvrXCancelTimerMessage (avrx_canceltimermessage.s)
      Format: AvrXCancelTimerMessage(&TMB, &MessageQueue);
      This API will remove a timer messgae that has been started but is no
      longer needed.


  MESSAGE QUEUES:
 
  * AvrXSendMessage (avrx_message.s)
      Format: AvrXSendMessage(&MessageQueue, &MCB);
      This non-blocking API will place the MCB message on the MessageQueue.


  * AvrXIntSendMessage (avrx_message.s)
      Format: AvrXIntSendMessage(&MessageQueue, &MCB);
      This is the same as the previous API except that it is run at the
      interrupt level, which means that it must be called from within a
      _Epilog/_Prolog wrapper.


  * AvrXWaitMessage (avrx_message.s)
      Format: AvrXWaitMessage(&MessageQueue);
      This blocking API is similar to the previous API except that it will
      wait until a message becomes available before returning it.


  * AvrXRecvMessage (avrx_recvmessage.s)
      Format: AvrXRecvMessage(&MessageQueue);
      Returns the first item from MessageQueue or a zero if the queue is empty.


  * AvrXAckMessage (avrx_semaphores.s)
      Format: AvrXAckMessage(&MCB);
      This allows handshaking to be done through message queues.  The sequence
      would be AvrXSendMessage -> AvrXWaitMessage -> AvrXAckMessage ->
      AvrXWaitMessageAck.


  * AvrXTestMessageAck (avrx_testsmaphore.s)
      Format: AvrXTestMessageAck(&MCB);
      Returns the current state of the MCB (SEM_WAIT, SEM_PEND or SEM_DONE).


  * AvrXWaitMessageAck (avrx_semaphores.s)
      Format: AvrXWaitMessageAck(&MCB);
      A blocking API that will wait for a particular MCB to be returned.


  SYSTEM OBJECTS:
  * AvrXSetObjectSemaphore (avrx_semaphores.s)
      Format: AvrXSetObjectSemaphore(&mutex);
      Similar to AvrXSetSemaphore except that it applies to System Objects.
     
  * AvrXIntSetObjectSemaphore (avrx_semaphores.s)
      Format: AvrXIntSetObjectSemaphore(&mutex);
      Same as above except that it assumes the code is running at the
      interrupt level.


  * AvrXWaitObjectSemaphore (avrx_semaphores.s)
      Format: AvrXWaitObjectSemaphore(&mutex);
      A blocking API which waits on the semaphore in a System Object until it
      becomes SEM_DONE.
     
  * AvrXResetObjectSemaphore (avrx_resetsemaphore.s)
      Format: AvrXResetObjectSemaphore(&mutex);
      Forces the semaphore to the SEM_PEND state.


  * AvrXTestObjectSemaphore (avrx_testsemaphore.s)
      Format: AvrXTestObjectSemaphore(&mutex);
      A non-blocking API that returns the state of the semaphore


  DEBUG:
 
  * AvrXStepNext (avrx_singlestep.s)
      Format: AvrXStepNext();
      Unsuspends a task, adds it to the run queue, then resuspends the
      task.


  * AvrXSingleStepNext (avrx_singlestep.s)
      Format: AvrXSingleStepNext();
      Marks a suspended task for single step support Jams it on the front of
      the run queue.  Returns error if task is not suspended.
 
  OTHER:
 
    IntProlog (avrx_tasking.s)
      Format: IntProlog();
      Pushes entire register context onto the stack, returning a frame pointer
      to the saved context.  If running in user mode upon entry (SysLevel ==
      0xFF) then switches the stack to the kernel and stores the frame pointer
      in the current processes PID.
     
    Epilog (avrx_tasking.s)
      Format: Epilog();
      Restore previous context (kernel or user).  If task has SingleStep flag
      set, then generate an interrupt before returning to the task.
     
    AvrXSetKernelStack (avrx_tasking.s)
      Format: AvrXSetKernelStack(&stack);
      Sets AvrX Stack to "newstack" or, if NULL then to the current stack
           
    AvrXChangePriority (avrx_priority.s)

      Format: AvrXChangePriority(&PID, unsigned);
      Sets the priority of a process to the second parameter.  Returnes the
      original setting.
     
    AvrXPriority (avrx_priority.s)
      Format: AvrXPriority(&PID);
      Returns the current priority of the PID.
     
    AvrXSelf (avrx_priority.s)
      Format AvrXSelf();
      Returns the PID of calling process
     
    BeginCritical (avrx.h)
      Format: BeginCritical;
      This is a simple #define for the asm "cli" command to turn off
      interrupts.
     
    EndCritical (avrx.h)
      Format: EndCritical;
      This is a simple #define for the asm "sei" command to enable interrupts.


  SERIAL:
 
    InitSerialIO (serialio.s)
      Format: InitSerialIO(baud_rate_value);
      Initializes the USART and sets up the baud rate generator
   
    PrintString (serialio.s)
      Format: PrintString(&FlashString);
      Prints the string to the USART; returns a pointer to the next character
      after the NULL.


    PushChar (serialio.s)
      Format: PushChar();
      Set a flag so that the next call to GetChar just returns. In effect
      pushing the last returned charactor to be retrieved by the next routine.


    Other obvious serial commands:
      GetChar();
      PutCR();
      PutSpace();
      PutChar(char);
     

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1294193 2009-11-23 14:56

讲的真清楚,谢谢楼主

用户160165 2008-7-7 23:43

顶...好东西,呵呵
相关推荐阅读
用户931629 2008-09-20 22:46
用过AVR还会用51吗?
  对于做过AVR的大、小虾来说,比51,PIC的8位机爽多了,对与搞8位机的人来说,是福音啊,如果你是想做单片机的,AVR是你最好的选择,我以前是用51的,但是在用过AVR以后我是不会再用51了,太...
用户931629 2008-07-09 23:02
AVR单片机工程实例——全自动血凝仪检测系统
...
用户931629 2008-07-09 22:28
PK吹牛
PK吹牛    中国目前吹牛的人太多了,尤其是高校的所谓"专家",几乎是吹牛"专家",打着学校的旗号招摇撞骗的实在不少,科研经费到是那个多啊,可是做的事或意义是那个少啊!    我非常赞赏和敬重那些有...
我要评论
1
7
关闭 站长推荐上一条 /3 下一条