QP is an event-driven, RTOS-like, active object framework for microcontrollers, such as mbed. The QP framework provides thread-safe execution of active objects (concurrent state machines) and support both manual and automatic coding of UML statecharts in readable, production-quality C or C++. Automatic code generation of QP code is supported by the free QM modeling tool.

Dependents:   qp_hangman qp_dpp qp_blinky

QP/C++ (Quantum Platform in C++) is a lightweight, open source active object (actor) framework for building responsive and modular real-time embedded applications as systems of asynchronous event-driven active objects (actors). The QP/C++ framework is a member of a larger family consisting of QP/C++, QP/C, and QP-nano frameworks, which are all strictly quality controlled, thoroughly documented, and available under GPLv3 with a special Exception for mbed (see http://www.state-machine.com/licensing/QP-mbed_GPL_Exception.txt).

The behavior of active objects is specified in QP/C++ by means of hierarchical state machines (UML statecharts). The framework supports manual coding of UML state machines in C++ as well as automatic code generation by means of the free QM modeling tool (http://www.state-machine.com/qm).

Please see the "QP/C++ Reference Manual" (http://www.state-machine.com/qpcpp) for more information.

Revision:
9:ca2e6010d9e2
Parent:
5:949864ba515c
--- a/qk_port.s	Mon Sep 26 03:27:09 2011 +0000
+++ b/qk_port.s	Tue Sep 04 22:20:52 2012 +0000
@@ -1,130 +1,135 @@
-;*****************************************************************************
-; Product: QK port to ARM Cortex-M0/M3, mbed ARM assembler, CMSIS-compliant
-; Last Updated for Version: 4.2.04
-; Date of the Last Update:  Sep 23, 2011
-;
-;                    Q u a n t u m     L e a P s
-;                    ---------------------------
-;                    innovating embedded systems
-;
-; Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
-;
-; This software may be distributed and modified under the terms of the GNU
-; General Public License version 2 (GPL) as published by the Free Software
-; Foundation and appearing in the file GPL.TXT included in the packaging of
-; this file. Please note that GPL Section 2[b] requires that all works based
-; on this software must also be made publicly available under the terms of
-; the GPL ("Copyleft").
-;
-; Alternatively, this software may be distributed and modified under the
-; terms of Quantum Leaps commercial licenses, which expressly supersede
-; the GPL and are specifically designed for licensees interested in
-; retaining the proprietary status of their code.
-;
-; Contact information:
-; Quantum Leaps Web site:  http://www.quantum-leaps.com
-; e-mail:                  info@quantum-leaps.com
-;*****************************************************************************
-    AREA QK, CODE, READONLY
-
-    EXPORT  QK_init
-    EXPORT  PendSV_Handler    ; CMSIS-compliant PendSV exception name
-    EXPORT  SVC_Handler       ; CMSIS-compliant SVC exception name
-
-    EXTERN  QK_schedule_      ; external references
-    EXTERN  QK_readySet_      ; external references
-
-
-;*****************************************************************************
-;
-; The QK_init function sets the priorities of PendSV and SVCall exceptions
-; to 0xFF and 0x00, respectively. The function internally disables
-; interrupts, but restores the original interrupt lock before exit.
-;
-;*****************************************************************************
-QK_init
-    MRS     r0,PRIMASK        ; store the state of the PRIMASK in r0
-    CPSID   i                 ; disable interrupts (set PRIMASK)
-
-    LDR     r1,=0xE000ED18    ; System Handler Priority Register
-    LDR     r2,[r1,#8]        ; load the System 12-15 Priority Register
-    MOVS    r3,#0xFF
-    LSLS    r3,r3,#16
-    ORRS    r2,r3             ; set PRI_14 (PendSV) to 0xFF
-    STR     r2,[r1,#8]        ; write the System 12-15 Priority Register
-    LDR     r2,[r1,#4]        ; load the System 8-11 Priority Register
-    LSLS    r3,r3,#8
-    BICS    r2,r3             ; set PRI_11 (SVCall) to 0x00
-    STR     r2,[r1,#4]        ; write the System 8-11 Priority Register
-
-    MSR     PRIMASK,r0        ; restore the original PRIMASK
-    BX      lr                ; return to the caller
-
-
-;*****************************************************************************
-;
-; The PendSV_Handler exception hanlder is used for handling asynchronous
-; preemptions in QK. The use of the PendSV exception is the recommended
-; and most efficient method for performing context switches with ARM Cortex.
-;
-; The PendSV exception should have the lowest priority in the whole system
-; (0xFF, see QK_init). All other exeptions and interrupts should have higher
-; priority. For example, for NVIC with 2 priority bits all interrupts and
-; exceptions must have numerical value of priority lower than 0xC0. In this
-; case the interrupt priority levels available to your applications are (in
-; the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
-;
-; Also, *all* ISRs in the QK application must trigger the PendSV exception
-; by calling the QK_ISR_EXIT() macro.
-;
-; Due to tail-chaining and its lowest priority, the PendSV exception will be
-; entered immediately after the exit from the *last* nested interrupt (or
-; exception). In QK, this is exactly the time when the QK scheduler needs to
-; check for the asynchronous preemptions.
-;
-;*****************************************************************************
-PendSV_Handler
-    CPSID   i                 ; disable interrupts at processor level
-    LDR     r0,=0xE000ED04    ; load the NVIC-ICSR register address
-    MOVS    r1,#0x01
-    LSLS    r1,r1,#27         ; make up a mask with only the PENDSVCLR bit set
-    STR     r1,[r0]           ; remove the pending status of PendSV
-    LDR     r0,=QK_readySet_  ; load the address of QK_readySet_
-    LDRB    r0,[r0]           ; load the first byte of QK_readySet_
-    CMP     r0,#0             ; is QK_readySet_ == 0 ?
-    BEQ.N   iret              ; if QK_readySet_ == 0, branch to iret
-
-                              ; at this point r1 contains (1 << 27)
-    LSRS    r1,r1,#3          ; make up a task xPSR with only the T bit set
-    LDR     r0,=schedule      ; load the address of sched wrapper (new PC)
-    PUSH    {r0-r1}           ; push xPSR,PC
-    SUB     sp,sp,#(6*4)      ; don't care for lr,r12,r3,r2,r1,r0
-    BX      lr                ; interrupt return to the scheduler
-
-iret
-    CPSIE   i                 ; enable interrupts at processor level
-    BX      lr                ; interrupt return to the task
-
-schedule
-    BL      QK_schedule_      ; call the QK scheduler
-    CPSIE   i                 ; enable interrupts to allow SVCall exception
-    SVC     0                 ; SV exception returns to the preempted task
-
-
-;*****************************************************************************
-;
-; The SVC_Handler exception handler is used for returning back to the
-; interrupted context (task or interrupt). The SVC exception should have
-; the lowest priority in the whole system (see QK_init). The SVCall
-; exception simply removes its own interrupt stack frame from the stack and
-; returns to the preempted task using the interrupt stack frame that must be
-; at the top of the stack.
-;
-;*****************************************************************************
-SVC_Handler
-    ADD     sp,sp,#(8*4)      ; remove one interrupt frame from the stack
-    BX      lr                ; return to the preempted task
-
-    ALIGN                     ; make sure proper alignment
-    END
-    
\ No newline at end of file
+;*****************************************************************************
+; Product: QK port to ARM Cortex-M0/M3, mbed ARM assembler, CMSIS-compliant
+; Last Updated for Version: 4.5.02
+; Date of the Last Update:  Sep 04, 2012
+;
+;                    Q u a n t u m     L e a P s
+;                    ---------------------------
+;                    innovating embedded systems
+;
+; Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
+;
+; This program is open source software: you can redistribute it and/or
+; modify it under the terms of the GNU General Public License as published
+; by the Free Software Foundation, either version 2 of the License, or
+; (at your option) any later version.
+;
+; Alternatively, this program may be distributed and modified under the
+; terms of Quantum Leaps commercial licenses, which expressly supersede
+; the GNU General Public License and are specifically designed for
+; licensees interested in retaining the proprietary status of their code.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this program. If not, see <http://www.gnu.org/licenses/>.
+;
+; Contact information:
+; Quantum Leaps Web sites: http://www.quantum-leaps.com
+;                          http://www.state-machine.com
+; e-mail:                  info@quantum-leaps.com
+;*****************************************************************************
+    AREA QK, CODE, READONLY
+    PRESERVE8
+
+    EXPORT  QK_init
+    EXPORT  PendSV_Handler    ; CMSIS-compliant PendSV exception name
+    EXPORT  SVC_Handler       ; CMSIS-compliant SVC exception name
+
+    EXTERN  QK_schedPrio_     ; external reference
+    EXTERN  QK_sched_         ; external reference
+
+
+;*****************************************************************************
+;
+; The QK_init function sets the priorities of PendSV and SVCall exceptions
+; to 0xFF and 0x00, respectively. The function internally disables
+; interrupts, but restores the original interrupt lock before exit.
+;
+;*****************************************************************************
+QK_init
+    MRS     r0,PRIMASK        ; store the state of the PRIMASK in r0
+    CPSID   i                 ; disable interrupts (set PRIMASK)
+
+    LDR     r1,=0xE000ED18    ; System Handler Priority Register
+    LDR     r2,[r1,#8]        ; load the System 12-15 Priority Register
+    MOVS    r3,#0xFF
+    LSLS    r3,r3,#16
+    ORRS    r2,r3             ; set PRI_14 (PendSV) to 0xFF
+    STR     r2,[r1,#8]        ; write the System 12-15 Priority Register
+    LDR     r2,[r1,#4]        ; load the System 8-11 Priority Register
+    LSLS    r3,r3,#8
+    BICS    r2,r3             ; set PRI_11 (SVCall) to 0x00
+    STR     r2,[r1,#4]        ; write the System 8-11 Priority Register
+
+    MSR     PRIMASK,r0        ; restore the original PRIMASK
+    BX      lr                ; return to the caller
+
+
+;*****************************************************************************
+;
+; The PendSV_Handler exception hanlder is used for handling asynchronous
+; preemptions in QK. The use of the PendSV exception is the recommended
+; and most efficient method for performing context switches with ARM Cortex.
+;
+; The PendSV exception should have the lowest priority in the whole system
+; (0xFF, see QK_init). All other exeptions and interrupts should have higher
+; priority. For example, for NVIC with 2 priority bits all interrupts and
+; exceptions must have numerical value of priority lower than 0xC0. In this
+; case the interrupt priority levels available to your applications are (in
+; the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
+;
+; Also, *all* ISRs in the QK application must trigger the PendSV exception
+; by calling the QK_ISR_EXIT() macro.
+;
+; Due to tail-chaining and its lowest priority, the PendSV exception will be
+; entered immediately after the exit from the *last* nested interrupt (or
+; exception). In QK, this is exactly the time when the QK scheduler needs to
+; check for the asynchronous preemptions.
+;
+;*****************************************************************************
+PendSV_Handler
+    CPSID   i                 ; disable interrupts at processor level
+    BL      QK_schedPrio_     ; check if we have preemption
+    CMP     r0,#0             ; is prio == 0 ?
+    BNE.N   scheduler         ; if prio != 0, branch to scheduler
+
+    CPSIE   i                 ; enable interrupts at processor level
+    MOVS    r0,#0x6
+    MVNS    r0,r0             ; r0:=~0x6=0xFFFFFFF9
+    BX      r0                ; exception-return to the task
+
+scheduler
+    MOVS    r3,#1
+    LSLS    r3,r3,#24         ; r3:=(1 << 24), set the T bit  (new xpsr)
+    LDR     r2,=QK_sched_     ; address of the QK scheduler   (new pc)
+    LDR     r1,=svc_ret       ; return address after the call (new lr)
+    PUSH    {r1-r3}           ; push xpsr,pc,lr
+    SUB     sp,sp,#(4*4)      ; don't care for r12,r3,r2,r1
+    PUSH    {r0}              ; push the prio argument        (new r0)
+    MOVS    r0,#0x6
+    MVNS    r0,r0             ; r0:=~0x6=0xFFFFFFF9
+    BX      r0                ; exception-return to the scheduler
+
+svc_ret
+    CPSIE   i                 ; enable interrupts to allow SVCall exception
+    SVC     0                 ; SV exception returns to the preempted task
+
+
+;*****************************************************************************
+;
+; The SVC_Handler exception handler is used for returning back to the
+; interrupted task. The SVCall exception simply removes its own interrupt
+; stack frame from the stack and returns to the preempted task using the
+; interrupt stack frame that must be at the top of the stack.
+;
+;*****************************************************************************
+SVC_Handler
+    ADD     sp,sp,#(8*4)      ; remove one interrupt frame from the stack
+    BX      lr                ; return to the preempted task
+
+    ALIGN                     ; make sure the END is properly aligned
+    END