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.
Diff: qk_port.s
- 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