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.

Committer:
QL
Date:
Tue Sep 04 22:20:52 2012 +0000
Revision:
9:ca2e6010d9e2
Parent:
5:949864ba515c
QP/C++ 4.5.02 compatible with QM 2.2.xx

Who changed what in which revision?

UserRevisionLine numberNew contents of line
QL 9:ca2e6010d9e2 1 ;*****************************************************************************
QL 9:ca2e6010d9e2 2 ; Product: QK port to ARM Cortex-M0/M3, mbed ARM assembler, CMSIS-compliant
QL 9:ca2e6010d9e2 3 ; Last Updated for Version: 4.5.02
QL 9:ca2e6010d9e2 4 ; Date of the Last Update: Sep 04, 2012
QL 9:ca2e6010d9e2 5 ;
QL 9:ca2e6010d9e2 6 ; Q u a n t u m L e a P s
QL 9:ca2e6010d9e2 7 ; ---------------------------
QL 9:ca2e6010d9e2 8 ; innovating embedded systems
QL 9:ca2e6010d9e2 9 ;
QL 9:ca2e6010d9e2 10 ; Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
QL 9:ca2e6010d9e2 11 ;
QL 9:ca2e6010d9e2 12 ; This program is open source software: you can redistribute it and/or
QL 9:ca2e6010d9e2 13 ; modify it under the terms of the GNU General Public License as published
QL 9:ca2e6010d9e2 14 ; by the Free Software Foundation, either version 2 of the License, or
QL 9:ca2e6010d9e2 15 ; (at your option) any later version.
QL 9:ca2e6010d9e2 16 ;
QL 9:ca2e6010d9e2 17 ; Alternatively, this program may be distributed and modified under the
QL 9:ca2e6010d9e2 18 ; terms of Quantum Leaps commercial licenses, which expressly supersede
QL 9:ca2e6010d9e2 19 ; the GNU General Public License and are specifically designed for
QL 9:ca2e6010d9e2 20 ; licensees interested in retaining the proprietary status of their code.
QL 9:ca2e6010d9e2 21 ;
QL 9:ca2e6010d9e2 22 ; This program is distributed in the hope that it will be useful,
QL 9:ca2e6010d9e2 23 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
QL 9:ca2e6010d9e2 24 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
QL 9:ca2e6010d9e2 25 ; GNU General Public License for more details.
QL 9:ca2e6010d9e2 26 ;
QL 9:ca2e6010d9e2 27 ; You should have received a copy of the GNU General Public License
QL 9:ca2e6010d9e2 28 ; along with this program. If not, see <http://www.gnu.org/licenses/>.
QL 9:ca2e6010d9e2 29 ;
QL 9:ca2e6010d9e2 30 ; Contact information:
QL 9:ca2e6010d9e2 31 ; Quantum Leaps Web sites: http://www.quantum-leaps.com
QL 9:ca2e6010d9e2 32 ; http://www.state-machine.com
QL 9:ca2e6010d9e2 33 ; e-mail: info@quantum-leaps.com
QL 9:ca2e6010d9e2 34 ;*****************************************************************************
QL 9:ca2e6010d9e2 35 AREA QK, CODE, READONLY
QL 9:ca2e6010d9e2 36 PRESERVE8
QL 9:ca2e6010d9e2 37
QL 9:ca2e6010d9e2 38 EXPORT QK_init
QL 9:ca2e6010d9e2 39 EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception name
QL 9:ca2e6010d9e2 40 EXPORT SVC_Handler ; CMSIS-compliant SVC exception name
QL 9:ca2e6010d9e2 41
QL 9:ca2e6010d9e2 42 EXTERN QK_schedPrio_ ; external reference
QL 9:ca2e6010d9e2 43 EXTERN QK_sched_ ; external reference
QL 9:ca2e6010d9e2 44
QL 9:ca2e6010d9e2 45
QL 9:ca2e6010d9e2 46 ;*****************************************************************************
QL 9:ca2e6010d9e2 47 ;
QL 9:ca2e6010d9e2 48 ; The QK_init function sets the priorities of PendSV and SVCall exceptions
QL 9:ca2e6010d9e2 49 ; to 0xFF and 0x00, respectively. The function internally disables
QL 9:ca2e6010d9e2 50 ; interrupts, but restores the original interrupt lock before exit.
QL 9:ca2e6010d9e2 51 ;
QL 9:ca2e6010d9e2 52 ;*****************************************************************************
QL 9:ca2e6010d9e2 53 QK_init
QL 9:ca2e6010d9e2 54 MRS r0,PRIMASK ; store the state of the PRIMASK in r0
QL 9:ca2e6010d9e2 55 CPSID i ; disable interrupts (set PRIMASK)
QL 9:ca2e6010d9e2 56
QL 9:ca2e6010d9e2 57 LDR r1,=0xE000ED18 ; System Handler Priority Register
QL 9:ca2e6010d9e2 58 LDR r2,[r1,#8] ; load the System 12-15 Priority Register
QL 9:ca2e6010d9e2 59 MOVS r3,#0xFF
QL 9:ca2e6010d9e2 60 LSLS r3,r3,#16
QL 9:ca2e6010d9e2 61 ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
QL 9:ca2e6010d9e2 62 STR r2,[r1,#8] ; write the System 12-15 Priority Register
QL 9:ca2e6010d9e2 63 LDR r2,[r1,#4] ; load the System 8-11 Priority Register
QL 9:ca2e6010d9e2 64 LSLS r3,r3,#8
QL 9:ca2e6010d9e2 65 BICS r2,r3 ; set PRI_11 (SVCall) to 0x00
QL 9:ca2e6010d9e2 66 STR r2,[r1,#4] ; write the System 8-11 Priority Register
QL 9:ca2e6010d9e2 67
QL 9:ca2e6010d9e2 68 MSR PRIMASK,r0 ; restore the original PRIMASK
QL 9:ca2e6010d9e2 69 BX lr ; return to the caller
QL 9:ca2e6010d9e2 70
QL 9:ca2e6010d9e2 71
QL 9:ca2e6010d9e2 72 ;*****************************************************************************
QL 9:ca2e6010d9e2 73 ;
QL 9:ca2e6010d9e2 74 ; The PendSV_Handler exception hanlder is used for handling asynchronous
QL 9:ca2e6010d9e2 75 ; preemptions in QK. The use of the PendSV exception is the recommended
QL 9:ca2e6010d9e2 76 ; and most efficient method for performing context switches with ARM Cortex.
QL 9:ca2e6010d9e2 77 ;
QL 9:ca2e6010d9e2 78 ; The PendSV exception should have the lowest priority in the whole system
QL 9:ca2e6010d9e2 79 ; (0xFF, see QK_init). All other exeptions and interrupts should have higher
QL 9:ca2e6010d9e2 80 ; priority. For example, for NVIC with 2 priority bits all interrupts and
QL 9:ca2e6010d9e2 81 ; exceptions must have numerical value of priority lower than 0xC0. In this
QL 9:ca2e6010d9e2 82 ; case the interrupt priority levels available to your applications are (in
QL 9:ca2e6010d9e2 83 ; the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
QL 9:ca2e6010d9e2 84 ;
QL 9:ca2e6010d9e2 85 ; Also, *all* ISRs in the QK application must trigger the PendSV exception
QL 9:ca2e6010d9e2 86 ; by calling the QK_ISR_EXIT() macro.
QL 9:ca2e6010d9e2 87 ;
QL 9:ca2e6010d9e2 88 ; Due to tail-chaining and its lowest priority, the PendSV exception will be
QL 9:ca2e6010d9e2 89 ; entered immediately after the exit from the *last* nested interrupt (or
QL 9:ca2e6010d9e2 90 ; exception). In QK, this is exactly the time when the QK scheduler needs to
QL 9:ca2e6010d9e2 91 ; check for the asynchronous preemptions.
QL 9:ca2e6010d9e2 92 ;
QL 9:ca2e6010d9e2 93 ;*****************************************************************************
QL 9:ca2e6010d9e2 94 PendSV_Handler
QL 9:ca2e6010d9e2 95 CPSID i ; disable interrupts at processor level
QL 9:ca2e6010d9e2 96 BL QK_schedPrio_ ; check if we have preemption
QL 9:ca2e6010d9e2 97 CMP r0,#0 ; is prio == 0 ?
QL 9:ca2e6010d9e2 98 BNE.N scheduler ; if prio != 0, branch to scheduler
QL 9:ca2e6010d9e2 99
QL 9:ca2e6010d9e2 100 CPSIE i ; enable interrupts at processor level
QL 9:ca2e6010d9e2 101 MOVS r0,#0x6
QL 9:ca2e6010d9e2 102 MVNS r0,r0 ; r0:=~0x6=0xFFFFFFF9
QL 9:ca2e6010d9e2 103 BX r0 ; exception-return to the task
QL 9:ca2e6010d9e2 104
QL 9:ca2e6010d9e2 105 scheduler
QL 9:ca2e6010d9e2 106 MOVS r3,#1
QL 9:ca2e6010d9e2 107 LSLS r3,r3,#24 ; r3:=(1 << 24), set the T bit (new xpsr)
QL 9:ca2e6010d9e2 108 LDR r2,=QK_sched_ ; address of the QK scheduler (new pc)
QL 9:ca2e6010d9e2 109 LDR r1,=svc_ret ; return address after the call (new lr)
QL 9:ca2e6010d9e2 110 PUSH {r1-r3} ; push xpsr,pc,lr
QL 9:ca2e6010d9e2 111 SUB sp,sp,#(4*4) ; don't care for r12,r3,r2,r1
QL 9:ca2e6010d9e2 112 PUSH {r0} ; push the prio argument (new r0)
QL 9:ca2e6010d9e2 113 MOVS r0,#0x6
QL 9:ca2e6010d9e2 114 MVNS r0,r0 ; r0:=~0x6=0xFFFFFFF9
QL 9:ca2e6010d9e2 115 BX r0 ; exception-return to the scheduler
QL 9:ca2e6010d9e2 116
QL 9:ca2e6010d9e2 117 svc_ret
QL 9:ca2e6010d9e2 118 CPSIE i ; enable interrupts to allow SVCall exception
QL 9:ca2e6010d9e2 119 SVC 0 ; SV exception returns to the preempted task
QL 9:ca2e6010d9e2 120
QL 9:ca2e6010d9e2 121
QL 9:ca2e6010d9e2 122 ;*****************************************************************************
QL 9:ca2e6010d9e2 123 ;
QL 9:ca2e6010d9e2 124 ; The SVC_Handler exception handler is used for returning back to the
QL 9:ca2e6010d9e2 125 ; interrupted task. The SVCall exception simply removes its own interrupt
QL 9:ca2e6010d9e2 126 ; stack frame from the stack and returns to the preempted task using the
QL 9:ca2e6010d9e2 127 ; interrupt stack frame that must be at the top of the stack.
QL 9:ca2e6010d9e2 128 ;
QL 9:ca2e6010d9e2 129 ;*****************************************************************************
QL 9:ca2e6010d9e2 130 SVC_Handler
QL 9:ca2e6010d9e2 131 ADD sp,sp,#(8*4) ; remove one interrupt frame from the stack
QL 9:ca2e6010d9e2 132 BX lr ; return to the preempted task
QL 9:ca2e6010d9e2 133
QL 9:ca2e6010d9e2 134 ALIGN ; make sure the END is properly aligned
QL 9:ca2e6010d9e2 135 END