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:
Wed Feb 09 14:46:03 2011 +0000
Revision:
0:064c79e7311a
Child:
5:949864ba515c
4.1.06a

Who changed what in which revision?

UserRevisionLine numberNew contents of line
QL 0:064c79e7311a 1 ;*****************************************************************************
QL 0:064c79e7311a 2 ; Product: QK port to ARM Cortex-M0/M3, mbed ARM assembler, CMSIS-compliant
QL 0:064c79e7311a 3 ; Last Updated for Version: 4.1.06
QL 0:064c79e7311a 4 ; Date of the Last Update: Feb 07, 2011
QL 0:064c79e7311a 5 ;
QL 0:064c79e7311a 6 ; Q u a n t u m L e a P s
QL 0:064c79e7311a 7 ; ---------------------------
QL 0:064c79e7311a 8 ; innovating embedded systems
QL 0:064c79e7311a 9 ;
QL 0:064c79e7311a 10 ; Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved.
QL 0:064c79e7311a 11 ;
QL 0:064c79e7311a 12 ; This software may be distributed and modified under the terms of the GNU
QL 0:064c79e7311a 13 ; General Public License version 2 (GPL) as published by the Free Software
QL 0:064c79e7311a 14 ; Foundation and appearing in the file GPL.TXT included in the packaging of
QL 0:064c79e7311a 15 ; this file. Please note that GPL Section 2[b] requires that all works based
QL 0:064c79e7311a 16 ; on this software must also be made publicly available under the terms of
QL 0:064c79e7311a 17 ; the GPL ("Copyleft").
QL 0:064c79e7311a 18 ;
QL 0:064c79e7311a 19 ; Alternatively, this software may be distributed and modified under the
QL 0:064c79e7311a 20 ; terms of Quantum Leaps commercial licenses, which expressly supersede
QL 0:064c79e7311a 21 ; the GPL and are specifically designed for licensees interested in
QL 0:064c79e7311a 22 ; retaining the proprietary status of their code.
QL 0:064c79e7311a 23 ;
QL 0:064c79e7311a 24 ; Contact information:
QL 0:064c79e7311a 25 ; Quantum Leaps Web site: http://www.quantum-leaps.com
QL 0:064c79e7311a 26 ; e-mail: info@quantum-leaps.com
QL 0:064c79e7311a 27 ;*****************************************************************************
QL 0:064c79e7311a 28 AREA QK, CODE, READONLY
QL 0:064c79e7311a 29
QL 0:064c79e7311a 30 EXPORT QK_init
QL 0:064c79e7311a 31 EXPORT PendSV_Handler ; CMSIS-compliant PendSV exception name
QL 0:064c79e7311a 32 EXPORT SVC_Handler ; CMSIS-compliant SVC exception name
QL 0:064c79e7311a 33
QL 0:064c79e7311a 34 EXTERN QK_schedule_ ; external references
QL 0:064c79e7311a 35 EXTERN QK_readySet_ ; external references
QL 0:064c79e7311a 36
QL 0:064c79e7311a 37
QL 0:064c79e7311a 38 ;*****************************************************************************
QL 0:064c79e7311a 39 ;
QL 0:064c79e7311a 40 ; The QK_init function sets the priorities of SVCall and PendSV exceptions
QL 0:064c79e7311a 41 ; to the lowest level possible (0xFF). The function internally disables
QL 0:064c79e7311a 42 ; interrupts, but restores the original interrupt lock before exit.
QL 0:064c79e7311a 43 ;
QL 0:064c79e7311a 44 ;*****************************************************************************
QL 0:064c79e7311a 45 QK_init
QL 0:064c79e7311a 46 MRS r0,PRIMASK ; store the state of the PRIMASK in r0
QL 0:064c79e7311a 47 CPSID i ; disable interrupts (set PRIMASK)
QL 0:064c79e7311a 48
QL 0:064c79e7311a 49 LDR r1,=0xE000ED18 ; System Handler Priority Register
QL 0:064c79e7311a 50 LDR r2,[r1,#8] ; load the System 12-15 Priority Register
QL 0:064c79e7311a 51 MOVS r3,#0xFF
QL 0:064c79e7311a 52 LSLS r3,r3,#16
QL 0:064c79e7311a 53 ORRS r2,r3 ; set PRI_14 (PendSV) to 0xFF
QL 0:064c79e7311a 54 STR r2,[r1,#8] ; write the System 12-15 Priority Register
QL 0:064c79e7311a 55 LDR r2,[r1,#4] ; load the System 8-11 Priority Register
QL 0:064c79e7311a 56 LSLS r3,r3,#8
QL 0:064c79e7311a 57 ORRS r2,r3 ; set PRI_11 (SVCall) to 0xFF
QL 0:064c79e7311a 58 STR r2,[r1,#4] ; write the System 8-11 Priority Register
QL 0:064c79e7311a 59
QL 0:064c79e7311a 60 MSR PRIMASK,r0 ; restore the original PRIMASK
QL 0:064c79e7311a 61 BX lr ; return to the caller
QL 0:064c79e7311a 62
QL 0:064c79e7311a 63
QL 0:064c79e7311a 64 ;*****************************************************************************
QL 0:064c79e7311a 65 ;
QL 0:064c79e7311a 66 ; The PendSV_Handler exception hanlder is used for handling asynchronous
QL 0:064c79e7311a 67 ; preemptions in QK. The use of the PendSV exception is the recommended
QL 0:064c79e7311a 68 ; and most efficient method for performing context switches with ARM Cortex.
QL 0:064c79e7311a 69 ;
QL 0:064c79e7311a 70 ; The PendSV exception should have the lowest priority in the whole system
QL 0:064c79e7311a 71 ; (0xFF, see QK_init). All other exeptions and interrupts should have higher
QL 0:064c79e7311a 72 ; priority. For example, for NVIC with 2 priority bits all interrupts and
QL 0:064c79e7311a 73 ; exceptions must have numerical value of priority lower than 0xC0. In this
QL 0:064c79e7311a 74 ; case the interrupt priority levels available to your applications are (in
QL 0:064c79e7311a 75 ; the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00.
QL 0:064c79e7311a 76 ;
QL 0:064c79e7311a 77 ; Also, *all* ISRs in the QK application must trigger the PendSV exception
QL 0:064c79e7311a 78 ; by calling the QK_ISR_EXIT() macro.
QL 0:064c79e7311a 79 ;
QL 0:064c79e7311a 80 ; Due to tail-chaining and its lowest priority, the PendSV exception will be
QL 0:064c79e7311a 81 ; entered immediately after the exit from the *last* nested interrupt (or
QL 0:064c79e7311a 82 ; exception). In QK, this is exactly the time when the QK scheduler needs to
QL 0:064c79e7311a 83 ; check for the asynchronous preemptions.
QL 0:064c79e7311a 84 ;
QL 0:064c79e7311a 85 ;*****************************************************************************
QL 0:064c79e7311a 86 PendSV_Handler
QL 0:064c79e7311a 87 CPSID i ; disable interrupts at processor level
QL 0:064c79e7311a 88 LDR r0,=QK_readySet_ ; load the address of QK_readySet_
QL 0:064c79e7311a 89 LDRB r0,[r0] ; load the first byte of QK_readySet_
QL 0:064c79e7311a 90 CMP r0,#0 ; is QK_readySet_ == 0 ?
QL 0:064c79e7311a 91 BEQ.N iret ; if QK_readySet_ == 0, branch to iret
QL 0:064c79e7311a 92
QL 0:064c79e7311a 93 MOVS r1,#0x01
QL 0:064c79e7311a 94 LSLS r1,r1,#24 ; make up a task xPSR with only the T bit set
QL 0:064c79e7311a 95 LDR r0,=schedule ; load the address of sched wrapper (new PC)
QL 0:064c79e7311a 96 PUSH {r0-r1} ; push xPSR,PC
QL 0:064c79e7311a 97 SUB sp,sp,#(6*4) ; don't care for lr,r12,r3,r2,r1,r0
QL 0:064c79e7311a 98 BX lr ; interrupt return to the scheduler
QL 0:064c79e7311a 99
QL 0:064c79e7311a 100 iret
QL 0:064c79e7311a 101 CPSIE i ; enable interrupts at processor level
QL 0:064c79e7311a 102 BX lr ; interrupt return to the task
QL 0:064c79e7311a 103
QL 0:064c79e7311a 104 schedule
QL 0:064c79e7311a 105 BL QK_schedule_ ; call the QK scheduler
QL 0:064c79e7311a 106 CPSIE i ; enable interrupts to allow SVCall exception
QL 0:064c79e7311a 107 SVC 0 ; SV exception returns to the preempted task
QL 0:064c79e7311a 108
QL 0:064c79e7311a 109
QL 0:064c79e7311a 110 ;*****************************************************************************
QL 0:064c79e7311a 111 ;
QL 0:064c79e7311a 112 ; The SVC_Handler exception handler is used for returning back to the
QL 0:064c79e7311a 113 ; interrupted context (task or interrupt). The SVC exception should have
QL 0:064c79e7311a 114 ; the lowest priority in the whole system (see QK_init). The SVCall
QL 0:064c79e7311a 115 ; exception simply removes its own interrupt stack frame from the stack and
QL 0:064c79e7311a 116 ; returns to the preempted task using the interrupt stack frame that must be
QL 0:064c79e7311a 117 ; at the top of the stack.
QL 0:064c79e7311a 118 ;
QL 0:064c79e7311a 119 ;*****************************************************************************
QL 0:064c79e7311a 120 SVC_Handler
QL 0:064c79e7311a 121 ADD sp,sp,#(8*4) ; remove one interrupt frame from the stack
QL 0:064c79e7311a 122 BX lr ; return to the preempted task
QL 0:064c79e7311a 123
QL 0:064c79e7311a 124 ALIGN ; make sure proper alignment
QL 0:064c79e7311a 125 END
QL 0:064c79e7311a 126