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.
qk_port.s@0:064c79e7311a, 2011-02-09 (annotated)
- 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?
User | Revision | Line number | New 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 |