This commit is contained in:
MMS 2024-02-08 21:09:29 -05:00
parent db53ac24c1
commit ac99a2774a
1560 changed files with 177 additions and 850905 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "3rd_party"]
path = 3rd_party
url = https://github.com/QuantumLeaps/3rd_party.git
[submodule "examples"]
path = examples
url = https://github.com/QuantumLeaps/qpcpp-examples

@ -1 +1 @@
Subproject commit 2b7bb752b7f137dc12138e8461c65994c899e831
Subproject commit 025100adc4853702cd6ce6fa733b206c6a70ee8a

1
examples Submodule

@ -0,0 +1 @@
Subproject commit 9b8141914cce0d7320b1407c0c4c2448f046c271

View File

@ -1,146 +0,0 @@
> **NOTE**
This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers.
# About QP Examples for ARM Cortex-M (arm-cm)
This directory provides QP examples for ARM Cortex-M based MCUs.
These examples are intended to be used "as-is", or [adapted](#adapting-the-examples) for any ARM Cortex-M MCU that is not directly supported.
<p align="center">
<img src="qp_arm-cm.jpg"/>
</p>
> **NOTE**
The most simplifying factor is that the QP-ports to Cortex-M don't need to change at all (the correct port is selected automatically based on the standard preprocessor macros provided by the compiler).
# Example Applications
This directory contains two types of example applications:
- `blinky_<embedded-board>` demonstrates a [simple "blinky" application](https://www.state-machine.com/qpc/tut_blinky.html) with only one Active Object that periodically blinks an on-board LED. The "blinky" example is intentionally minimal and demonstrates only the QV and QK kernels (QXK is not demonstrated). Also, this example does not demonstrate the [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html).
- `dpp_<embedded-board>` demonstrates a more complete ["DPP" application (Dining Philosophers Problem)](https://www.state-machine.com/qpc/tut_dpp.html), with multiple, communicating Active Objects. The "dpp" example demonstrates all three built-in kernels (QV, QK, and QXK). Also, this example demonstrates the [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html).
# Supported Compilers
The following compilers/toolchains for ARM Cortex-M are supported and demonstrated:
- ARM-KEIL toolchain
- GNU-ARM toolchain
- IAR-ARM toolchain
## Build Configurations
- Debug
- Release
- Spy (only in the "DPP" examples)
# Adapting the Examples
With dozens of silicon vendors offering ARM Cortex-M MCUs, each providing hundreds if not thousands of MCU variants, it is *impossible* to offer direct support for each and every such MCU. But this is also not necessary because the already provided examples can be adapted relatively easily. The most important simplifying fact is that the [QP-ports to Cortex-M](https://www.state-machine.com/qpc/arm-cm.html) don't need to change at all.
This is how you might go about an MCU that is not directly supported in the `qpc/examples/arm-cm`:
- choose example that most closely matches your particular MCU. For instance, suppose that you're interested in NXP MKE02Z64VLC2, which is based on the Cortex-M0+ core, the closest are the examples for NUCLEO-C031C6 (also based on M0+)
- choose the kernel you'd like to use. For example, assuming that you like QK, you are interested in the qk subdirectory.
- choose the compiler you'd like to use. For example, assuming that you like GNU-ARM, you are interested in the gnu subdirectory
- build the chosen example project. Again, it **doesn't matter** at this stage that it is not exactly your final hardware. Your objective is testing your QP installation and the compiler installation. You are also getting familiar with QP. These goals are worth but a few minutes of your time.
- at this point, it is highly recommend that you just buy one of the supported ARM Cortex-M boards, which are carefully chosen to be very inexpensive. With your own board, you'd be able to run and debug the QP application at your desk, which is priceless because as you surely remember: *In embedded systems NOTING works until EVERYTHING works*.
- only *after* you get started with a working example, you can try to modify it for your own board. This typically requires only changes to the BSP (Board Support Package), which is provided in the `bsp.c` file.
# Code Organization
The following listing shows a typical organization of the example code:
```
examples\arm-cm\dpp_nucleo-c031c6
|
+---qk // preemptive QK kernel
| +---gnu // GNU-ARM toolchain
| | \---targetConfigs
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | dpp-qk.uvprojx // uVision project
| \---iar // IAR EWARM
| dpp-qk.eww // IAR EW-ARM workspace
|
\---qv // cooperative QK kernel
| +---gnu // GNU-ARM toolchain
| | \---targetConfigs
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | dpp-qv.uvprojx // uVision project
| \---iar // IAR EWARM
| dpp-qv.eww // IAR EW-ARM workspace
|
+---qxk // preemptive, dual-mode QXK kernel
| +---gnu // GNU-ARM toolchain
| | \---targetConfigs
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | dpp-qxk.uvprojx // uVision project
| \---iar // IAR EWARM
| dpp-qxk.eww // IAR EW-ARM workspace
|
```
# Building the example
### GNU/ARM
- open terminal window
- change to the desired directory (either `examples\arm-cm\dpp_nucleo-c031c6\qk\gnu`, `examples\arm-cm\dpp_nucleo-c031c6\qv\gnu`, or `examples\arm-cm\dpp_nucleo-c031c6\qxk\gnu`)
- to build the default Debug configuration, type:
```
make
```
> **NOTE**
The `make` utility for Windows is provided in the QTools collection for Windows.
- to build the Release configuration, type:
```
make CONF=rel
```
- to build the Spy configuration, type:
```
make CONF=spy
```
### ARM/KEIL MDK
- Open the provided KEIL uVision project (either `dpp-qk.uvprojx`, `dpp-qv.uvprojx`, or `dpp-qxk.uvprojx`)
in Keil uVision IDE. Build/Debug/Download to the board from the IDE.
- Change the build configuration in the "Project Target" drop-down menu.
### IAR EWARM
- Open the provided IAR EWARM workspace (either `dpp-qk.eww`, `dpp-qv.eww`, or `dpp-qxk.eww`)
in IAR EWARM IDE. Build/Debug/Download to the board from the IDE.
- Change the build configuration in the "Project Configuration" drop-down menu.
# Tracing with QP/Spy
When the board is flashed with the Spy build configuration, it produces the QP/Spy software tracing output to the built-in virtual COM port of the TivaC LauchPad board. The trace is binary rather than ASCII, and therefore requires a special host-based application called QSPY.
> **NOTE** QSPY host application is available in the QTools collection.
To launch the QSPY host application:
- open terminal window
- type:
```
qspy -c COM5
```
where "COM5" is an example virtual COM port enumerated by the board. You need to check the specific COM port number on your host computer using the Device Manager application, Ports (COM and LPT) section.
The following screen shot shows a typical output from QSPY:
<p align="center">
<img src="./qspy-output.png"/><br>
<b>Typical QSPY output produced by the Spy build configuration</b>
</p>

View File

@ -1,81 +0,0 @@
> **NOTE**
This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers.
# Blinky on EK-TM4C123GXL
This example implements the simple [Blinky application](https://www.state-machine.com/qpcpp/tut_blinky.html) on the EK-TM4C123GLX board (ARM Cortex-M4F). The example blinks the LED
on the EK-TM4C123GXL board at 1Hz (0.5 seconds on, 0.5 seconds off).
<p align="center">
<img src="./ek-tm4c123gxl.jpg"/><br>
<b>EK-TM4C123GXL (TivaC LaunchPad)</b>
</p>
## Features Demonstrated
- cooperative QV kernel
+ with ARM-KEIL toolchain
+ with GNU-ARM toolchain
+ with IAR-ARM toolchain
- preemptive run-to-completion QK kernel
+ with ARM-KEIL toolchain
+ with GNU-ARM toolchain
+ with IAR-ARM toolchain
## Build Configurations
- Debug
- Release
- Spy - NOT supported for the simple Blinky example
# Code Organization
```
examples\arm-cm\blinky_ek-tm4c123gxl
|
+---qk // preemptive QK kernel
| +---gnu // GNU-ARM toolchain
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | blinky-qk.uvprojx // uVision project
| \---iar // IAR EWARM
| blinky-qk.eww // IAR EW-ARM workspace
|
\---qv // cooperative QK kernel
| +---gnu // GNU-ARM toolchain
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | blinky-qv.uvprojx // uVision project
| \---iar // IAR EWARM
| blinky-qv.eww // IAR EW-ARM workspace
```
# Building the example
### GNU/ARM
- open terminal window
- change to the desired directory (either `examples\arm-cm\blinky_ek-tm4c123gxl\qk\gnu`
or `examples\arm-cm\blinky_ek-tm4c123gxl\qv\gnu`)
- to build the default Debug configuration, type:
```
make
```
> **NOTE**
The `make` utility for Windows is provided in the QTools collection for Windows.
- to build the Release configuration, type:
```
make CONF=rel
```
### ARM/KEIL MDK
- Open the provided KEIL uVision project (either `blinky-qk.uvprojx` or `blinky-qv.uvprojx`)
in Keil uVision IDE. Build/Debug/Download to the board from the IDE.
- Change the build configuration in the "Project Target" drop-down menu.
### IAR EWARM
- Open the provided IAR EWARM workspace (either `blinky-qk.eww` or `blinky-qv.eww`)
in IAR EWARM IDE. Build/Debug/Download to the board from the IDE.
- Change the build configuration in the "Project Configuration" drop-down menu.

View File

@ -1,123 +0,0 @@
//============================================================================
// QP/C++ Real-Time Embedded Framework (RTEF)
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
//
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
//
// This software is dual-licensed under the terms of the open source GNU
// General Public License version 3 (or any later version), or alternatively,
// under the terms of one of the closed source Quantum Leaps commercial
// licenses.
//
// The terms of the open source GNU General Public License version 3
// can be found at: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @date Last updated on: 2022-08-25
//! @version Last updated Zephyr 3.1.99 and @ref qpcpp_7_1_0
//!
//! @file
//! @brief Blinky example
//!
#include "qpcpp.hpp"
#include "bsp.hpp"
#include "blinky.hpp"
// unnamed namespace for local definitions with internal linkage
namespace {
//Q_DEFINE_THIS_FILE
} // unnamed namespace
namespace APP {
//............................................................................
class Blinky : public QP::QActive {
private:
QP::QTimeEvt m_timeEvt;
public:
Blinky();
static Blinky inst;
protected:
Q_STATE_DECL(initial);
Q_STATE_DECL(off);
Q_STATE_DECL(on);
};
// local objects --------------------------------------------------------------
Blinky Blinky::inst;
// global objects ------------------------------------------------------------
QP::QActive * const AO_Blinky = &Blinky::inst; // opaque pointer
//............................................................................
Blinky::Blinky()
: QP::QActive(&initial),
m_timeEvt(this, TIMEOUT_SIG, 0U)
{
// empty
}
// HSM definition ------------------------------------------------------------
Q_STATE_DEF(Blinky, initial) {
(void)e; // unused parameter
// arm the time event to expire in half a second and every half second
m_timeEvt.armX(BSP::TICKS_PER_SEC/2U, BSP::TICKS_PER_SEC/2U);
return tran(&off);
}
//............................................................................
Q_STATE_DEF(Blinky, off) {
QP::QState status;
switch (e->sig) {
case Q_ENTRY_SIG: {
BSP::ledOff();
status = Q_RET_HANDLED;
break;
}
case TIMEOUT_SIG: {
status = tran(&on);
break;
}
default: {
status = super(&top);
break;
}
}
return status;
}
//............................................................................
Q_STATE_DEF(Blinky, on) {
QP::QState status;
switch (e->sig) {
case Q_ENTRY_SIG: {
BSP::ledOn();
status = Q_RET_HANDLED;
break;
}
case TIMEOUT_SIG: {
status = tran(&off);
break;
}
default: {
status = super(&top);
break;
}
}
return status;
}
} // namespace APP

View File

@ -1,53 +0,0 @@
//============================================================================
// Blinky example
// Last Updated for Version: 7.3.0
// Date of the Last Update: 2023-08-24
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#ifndef BLINKY_HPP_
#define BLINKY_HPP_
namespace APP {
enum AppSignals : QP::QSignal {
DUMMY_SIG = QP::Q_USER_SIG,
MAX_PUB_SIG, // the last published signal
TIMEOUT_SIG,
MAX_SIG // the last signal
};
// opaque pointer to the Blinky AO
extern QP::QActive * const AO_Blinky;
} // namespace APP
#endif // BLINKY_HPP_

View File

@ -1,50 +0,0 @@
//============================================================================
// Blinky example
// Last Updated for Version: 7.3.0
// Date of the Last Update: 2023-08-24
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#ifndef BSP_HPP_
#define BSP_HPP_
namespace BSP {
constexpr std::uint32_t TICKS_PER_SEC {1000U};
void init();
void start();
void terminate(std::int16_t const result);
void ledOn(void);
void ledOff(void);
} // namespace BSP
#endif // BSP_HPP_

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1,44 +0,0 @@
//============================================================================
// APP example
// Last updated for version 7.3.0
// Last updated on 2023-08-09
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <www.state-machine.com>
//
// 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "blinky.hpp" // DPP Application interface
#include "bsp.hpp" // Board Support Package
//............................................................................
int main() {
QP::QF::init(); // initialize the framework
BSP::init(); // initialize the BSP
BSP::start(); // start the AOs/Threads
return QP::QF::run(); // run the QF application
}

View File

@ -1,61 +0,0 @@
About this Example
==================
This example demonstrates how to use the uVision IDE together with
the MDK-ARM toolchain.
***
NOTE: This example requires installing the following Software Pack
in the Keil uVision: Keil::TM4C_DFP.
***
uVision Project File
====================
The MDK-ARM uVision project file provided with this example uses
relative paths to the QP/C framework location (includes, port, and
libraries. These relative paths must be modified when the project
is moved to different relative location.
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the
command-line options for the ARM assembler (see the Asm tab in
the "Options for Target" dialog box in uVision). Specifically,
you should define symbols: Stack_Size=xxx Heap_Size=yyy, where
xxx represents a numerical value of stack size and yyy the
numerical value of the heap size (for most embedded projects
yyy should be 0, as the using the heap is not recommended).
***
NOTE:
C++ programs seem not to tolerate heap size of 0. Therefore it is
recommended to set the Heap_Size symbol to a minimal value of 16.
***
Startup Code
============
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s
The file startup_TM4C123GH6PM.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,23 +0,0 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
;
; Adapted by Quantum Leaps:
; added STACK as the first section in RW_STACK
; *************************************************************
LR_IROM1 0x00000000 0x00040000 { ; load region size_region
ER_IROM1 0x00000000 0x00040000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_STACK 0x20000000 { ; <== Quantum Leaps
* (STACK, +First)
}
RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048!
.ANY (+RW +ZI)
}
}

View File

@ -1,252 +0,0 @@
//============================================================================
// Blinky example, EK-TM4C123GXL board, QK kernel
// Last updated for: @ref qpcpp_7_3_0
// Last updated on 2023-08-24
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "blinky.hpp" // Blinky Application interface
#include "bsp.hpp" // Board Support Package
#include "TM4C123GH6PM.h" // the device specific header (TI)
#include "rom.h" // the built-in ROM functions (TI)
#include "sysctl.h" // system control driver (TI)
#include "gpio.h" // GPIO driver (TI)
// add other drivers if necessary...
#ifdef Q_SPY
#error Simple Blinky Application does not provide Spy build configuration
#endif
namespace { // unnamed local namespace
//Q_DEFINE_THIS_FILE
} // unnamed local namespace
// Local-scope defines -------------------------------------------------------
#define LED_RED (1U << 1U)
#define LED_GREEN (1U << 3U)
#define LED_BLUE (1U << 2U)
#define BTN_SW1 (1U << 4U)
#define BTN_SW2 (1U << 0U)
//============================================================================
// Error handler and ISRs...
extern "C" {
Q_NORETURN Q_onError(char const * const module, int_t const id) {
// NOTE: this implementation of the assertion handler is intended only
// for debugging and MUST be changed for deployment of the application
// (assuming that you ship your production code with assertions enabled).
Q_UNUSED_PAR(module);
Q_UNUSED_PAR(id);
QS_ASSERTION(module, id, 10000U);
#ifndef NDEBUG
// light up all LEDs
GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU;
// for debugging, hang on in an endless loop...
for (;;) {
}
#endif
NVIC_SystemReset();
}
//............................................................................
void assert_failed(char const * const module, int_t const id); // prototype
void assert_failed(char const * const module, int_t const id) {
Q_onError(module, id);
}
// ISRs used in the application ==============================================
void SysTick_Handler(void); // prototype
void SysTick_Handler(void) {
QK_ISR_ENTRY(); // inform QK about entering an ISR
QP::QTimeEvt::TICK_X(0U, nullptr); // process time events at rate 0
QK_ISR_EXIT(); // inform QK about exiting an ISR
}
} // extern "C"
//============================================================================
namespace BSP {
void init() {
// Configure the MPU to prevent NULL-pointer dereferencing ...
MPU->RBAR = 0x0U // base address (NULL)
| MPU_RBAR_VALID_Msk // valid region
| (MPU_RBAR_REGION_Msk & 7U); // region #7
MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region
| (0x0U << MPU_RASR_AP_Pos) // no-access region
| MPU_RASR_ENABLE_Msk; // region enable
MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region
| MPU_CTRL_ENABLE_Msk; // enable the MPU
__ISB();
__DSB();
// enable the MemManage_Handler for MPU exception
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
// NOTE: SystemInit() has been already called from the startup code
// but SystemCoreClock needs to be updated
SystemCoreClockUpdate();
// NOTE: The VFP (hardware Floating Point) unit is configured by QV
// enable clock for to the peripherals used by this application...
SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF
SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF
__ISB();
__DSB();
// configure LEDs (digital output)
GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN);
GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN);
GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U;
// configure switches...
// unlock access to the SW2 pin because it is PROTECTED
GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2
// commit the write (cast const away)
*(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U;
GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input
GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable
GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable
*(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U;
GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2
}
//............................................................................
void start() {
// initialize event pools
static QF_MPOOL_EL(QP::QEvt) smlPoolSto[20];
QP::QF::poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// initialize publish-subscribe
static QP::QSubscrList subscrSto[APP::MAX_PUB_SIG];
QP::QActive::psInit(subscrSto, Q_DIM(subscrSto));
// instantiate and start AOs/threads...
static QP::QEvt const *blinkyQueueSto[10];
APP::AO_Blinky->start(
1U, // QP prio. of the AO
blinkyQueueSto, // event queue storage
Q_DIM(blinkyQueueSto), // queue length [events]
nullptr, 0U, // no stack storage
nullptr); // no initialization param
}
//............................................................................
void ledOn() {
GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU;
}
//............................................................................
void ledOff() {
GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U;
}
//............................................................................
void terminate(int16_t result) {
Q_UNUSED_PAR(result);
}
} // namespace BSP
//============================================================================
namespace QP {
// QF callbacks...
void QF::onStartup() {
// set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate
SysTick_Config(SystemCoreClock / BSP::TICKS_PER_SEC);
// assign all priority bits for preemption-prio. and none to sub-prio.
NVIC_SetPriorityGrouping(0U);
// set priorities of ALL ISRs used in the system, see NOTE1
NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U);
// ...
// enable IRQs...
}
//............................................................................
void QF::onCleanup() {
}
//............................................................................
void QK::onIdle() {
// toggle the User LED on and then off, see NOTE2
QF_INT_DISABLE();
GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on
GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off
QF_INT_ENABLE();
#ifdef NDEBUG
// Put the CPU and peripherals to the low-power mode.
// you might need to customize the clock management for your application,
// see the datasheet for your particular Cortex-M MCU.
__WFI(); // Wait-For-Interrupt
#endif
}
} // namespace QP
//============================================================================
// NOTE1:
// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest
// ISR priority that is disabled by the QF framework. The value is suitable
// for the NVIC_SetPriority() CMSIS function.
//
// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
// with the numerical values of priorities equal or higher than
// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs
// are "QF-aware".
//
// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
// level (i.e., with the numerical values of priorities less than
// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
// Such "QF-unaware" ISRs cannot call any QF services. The only mechanism
// by which a "QF-unaware" ISR can communicate with the QF framework is by
// triggering a "QF-aware" ISR, which can post/publish events.
//
// NOTE2:
// One of the LEDs is used to visualize the idle loop activity. The brightness
// of the LED is proportional to the frequency of the idle loop. Please note
// that the LED is toggled with interrupts locked, so no interrupt execution
// time contributes to the brightness of the User LED.
//

View File

@ -1,309 +0,0 @@
##############################################################################
# Product: Makefile for QP/C++ on EK-TM4C123GXL, QK kernel, GNU-ARM
# Last Updated for Version: 7.0.1
# Date of the Last Update: 2022-05-23
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005-2021 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 3 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# http://sourceforge.net/projects/qpc/files/Qtools/
#
#-----------------------------------------------------------------------------
# project name
#
PROJECT := blinky-qk
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environment var.)
ifeq ($(QPCPP),)
QPCPP := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/arm-cm/qk/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPCPP)/src/qf \
$(QPCPP)/src/qk \
$(QPCPP)/src/qs \
$(QP_PORT_DIR) \
$(QPCPP)/3rd_party/ek-tm4c123gxl \
$(QPCPP)/3rd_party/ek-tm4c123gxl/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR) \
-I$(QPCPP)/3rd_party/CMSIS/Include \
-I$(QPCPP)/3rd_party/ek-tm4c123gxl
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
system_TM4C123GH6PM.c \
startup_TM4C123GH6PM.c
# C++ source files
CPP_SRCS := \
blinky.cpp \
bsp.cpp \
main.cpp
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.cpp \
qep_msm.cpp \
qf_act.cpp \
qf_actq.cpp \
qf_defer.cpp \
qf_dyn.cpp \
qf_mem.cpp \
qf_ps.cpp \
qf_qact.cpp \
qf_qeq.cpp \
qf_qmact.cpp \
qf_time.cpp \
qk.cpp \
qk_port.cpp
QP_ASMS :=
QS_SRCS := \
qs.cpp \
qs_rx.cpp \
qs_fp.cpp
LIB_DIRS :=
LIBS :=
# defines
DEFINES := -DTARGET_IS_TM4C123_RB1
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m4
ARM_FPU := -mfpu=vfp
FLOAT_ABI := -mfloat-abi=softfp
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-g++
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically, you should not need to change anything below this line
# basic utilities (included in Qtools for Windows), see:
# http://sourceforge.net/projects/qpc/files/Qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M4F
#
# combine all the sources...
CPP_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
CPP_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CPP) $(CPPFLAGS) $(QPCPP)/src/qs/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -1,71 +0,0 @@
About this Example
==================
This example can be built in two different ways:
- from the command prompt with the provided Makefile.
- from the TI Code Composer Studio with the provided CCS project.
The Makefile
============
The provided Makefile should be easy to adapt for your own projects.
It contains three build configurations: Debug (default), Release, and
Spy.
Also, the Makefile has been specifically designed to work as an external
Makefile with the Eclipse CDT.
The various build configurations are built as follows:
make
make CONF=rel
make CONF=spy
make clean
make CONF=rel clean
make CONF=spy clean
***
NOTE:
The installation folder of the GNU-ARM toolset on YOUR machine needs
to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM.
As described in the comment for this symbol, the GNU-ARM toolset is taken
from: http://gnutoolchains.com/arm-eabi
It is highly recommended to use the same GNU-ARM distribution, especially
for ARM Cortex-M4F projects, due to the support for the hardware FPU
(float-abi=hard).
***
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the GCC linker
script (.ld file), which provides a template of the recommended GCC linker
script for QP applications.
Startup Code
============
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\ek-tm4c123gxl\gcc\startup_TM4C123GH6PM.c
The file startup_TM4C123GH6PM.c provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,139 +0,0 @@
/*****************************************************************************
* Product: Linker script for EK-TM4C123GXL, GNU-ARM linker
* Last Updated for Version: 5.9.8
* Date of the Last Update: 2017-09-13
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 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 3 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:
* Web : http://www.state-machine.com
* Email: info@state-machine.com
*****************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler) /* entry Point */
MEMORY { /* memory map of Tiva TM4C123GH6PM */
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS {
.isr_vector : { /* the vector table goes FIRST into ROM */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >ROM
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >ROM
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM
__exidx_end = .;
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}

View File

@ -1,33 +0,0 @@
::============================================================================
:: Batch file to program the flash of EK-TM4C123GXL
::
:: NOTE: requires the LMFlash programmer (included in QTools for Windows)
::
@echo off
setlocal
@echo Load a given binary file to the flash of EK-TM4C123GXL
@echo usage: flash binary-file
@echo example: flash dbg\blinky-qk.bin
::----------------------------------------------------------------------------
:: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can
:: be found on the PATH. You might need to adjust this symbol to the
:: location of the LMFlash utility on your machine
::
set LMFLASH=LMFlash.exe
if ["%~1"]==[""] (
@echo The binary file missing
@goto end
)
if not exist %~s1 (
@echo The binary file '%1' does not exist
@goto end
)
%LMFLASH% -q ek-tm4c123gxl -e -v -r %1
:end
endlocal

View File

@ -1,53 +0,0 @@
About this Example
==================
This example demonstrates how to use the IAR EWARM IDE to build
a QP application.
IAR Project File
----------------
The IAR EWARM project file provided with this example uses relative paths
to the QP/C framework location (includes, port, and libraries. These
relative paths must be modified when the project is moved to different
relative location.
Stack Size and Heap Size
------------------------
In this project, the size of the C stack and heap are determined in
the linker script blinky-qk.icf (see the next section).
Linker Script
-------------
The IAR linker script provides a template of the recommended linker script
for QP applications. This file needs to be customized to set the
application-specific sizes of the Stack and Heap. This file can be edited
from the IAR EWARM IDE via the Project Options/Linker settings.
Startup Code
------------
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s
The file startup_TM4C123GH6PM.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\blinky-qk.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -1,29 +0,0 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP };

View File

@ -1,61 +0,0 @@
About this Example
==================
This example demonstrates how to use the uVision IDE together with
the MDK-ARM toolchain.
***
NOTE: This example requires installing the following Software Pack
in the Keil uVision: Keil::TM4C_DFP.
***
uVision Project File
====================
The MDK-ARM uVision project file provided with this example uses
relative paths to the QP/C framework location (includes, port, and
libraries. These relative paths must be modified when the project
is moved to different relative location.
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the
command-line options for the ARM assembler (see the Asm tab in
the "Options for Target" dialog box in uVision). Specifically,
you should define symbols: Stack_Size=xxx Heap_Size=yyy, where
xxx represents a numerical value of stack size and yyy the
numerical value of the heap size (for most embedded projects
yyy should be 0, as the using the heap is not recommended).
***
NOTE:
C++ programs seem not to tolerate heap size of 0. Therefore it is
recommended to set the Heap_Size symbol to a minimal value of 16.
***
Startup Code
============
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s
The file startup_TM4C123GH6PM.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,23 +0,0 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
;
; Adapted by Quantum Leaps:
; added STACK as the first section in RW_STACK
; *************************************************************
LR_IROM1 0x00000000 0x00040000 { ; load region size_region
ER_IROM1 0x00000000 0x00040000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_STACK 0x20000000 { ; <== Quantum Leaps
* (STACK, +First)
}
RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048!
.ANY (+RW +ZI)
}
}

View File

@ -1,976 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
<SchemaVersion>1.0</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Extensions>
<cExt>*.c</cExt>
<aExt>*.s*; *.src; *.a*</aExt>
<oExt>*.obj; *.o</oExt>
<lExt>*.lib</lExt>
<tExt>*.txt; *.h; *.inc; *.md</tExt>
<pExt>*.plm</pExt>
<CppX>*.cpp</CppX>
<nMigrate>0</nMigrate>
</Extensions>
<DaveTm>
<dwLowDateTime>0</dwLowDateTime>
<dwHighDateTime>0</dwHighDateTime>
</DaveTm>
<Target>
<TargetName>blinky-dbg</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<TargetOption>
<CLKADS>12000000</CLKADS>
<OPTTT>
<gFlags>1</gFlags>
<BeepAtEnd>1</BeepAtEnd>
<RunSim>1</RunSim>
<RunTarget>0</RunTarget>
<RunAbUc>0</RunAbUc>
</OPTTT>
<OPTHX>
<HexSelection>1</HexSelection>
<FlashByte>65535</FlashByte>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
</OPTHX>
<OPTLEX>
<PageWidth>79</PageWidth>
<PageLength>66</PageLength>
<TabStop>8</TabStop>
<ListingPath>.\dbg\</ListingPath>
</OPTLEX>
<ListingPage>
<CreateCListing>1</CreateCListing>
<CreateAListing>1</CreateAListing>
<CreateLListing>1</CreateLListing>
<CreateIListing>0</CreateIListing>
<AsmCond>1</AsmCond>
<AsmSymb>1</AsmSymb>
<AsmXref>0</AsmXref>
<CCond>1</CCond>
<CCode>0</CCode>
<CListInc>0</CListInc>
<CSymb>0</CSymb>
<LinkerCodeListing>0</LinkerCodeListing>
</ListingPage>
<OPTXL>
<LMap>1</LMap>
<LComments>1</LComments>
<LGenerateSymbols>1</LGenerateSymbols>
<LLibSym>1</LLibSym>
<LLines>1</LLines>
<LLocSym>1</LLocSym>
<LPubSym>1</LPubSym>
<LXref>0</LXref>
<LExpSel>0</LExpSel>
</OPTXL>
<OPTFL>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget>
</OPTFL>
<CpuCode>4</CpuCode>
<DebugOpt>
<uSim>0</uSim>
<uTrg>1</uTrg>
<sLdApp>1</sLdApp>
<sGomain>1</sGomain>
<sRbreak>1</sRbreak>
<sRwatch>1</sRwatch>
<sRmem>1</sRmem>
<sRfunc>1</sRfunc>
<sRbox>1</sRbox>
<tLdApp>1</tLdApp>
<tGomain>0</tGomain>
<tRbreak>1</tRbreak>
<tRwatch>1</tRwatch>
<tRmem>1</tRmem>
<tRfunc>0</tRfunc>
<tRbox>1</tRbox>
<tRtrace>0</tRtrace>
<sRSysVw>1</sRSysVw>
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf>
<nTsel>19</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
<sDlgPa></sDlgPa>
<sIfile></sIfile>
<tDll></tDll>
<tDllPa></tDllPa>
<tDlgDll></tDlgDll>
<tDlgPa></tDlgPa>
<tIfile></tIfile>
<pMon>BIN\lmidk-agdi.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name>ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ`F
X0ÂiôîA</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
<Name>UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>lmidk-agdi</Key>
<Name>-U0E2006F4 -O4622 -S4 -FO61</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<MemoryWindow1>
<Mm>
<WinNumber>1</WinNumber>
<SubType>2</SubType>
<ItemText>0x20000200</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow1>
<MemoryWindow2>
<Mm>
<WinNumber>2</WinNumber>
<SubType>0</SubType>
<ItemText>0x400</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow2>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
<DebugFlag>
<trace>0</trace>
<periodic>0</periodic>
<aLwin>1</aLwin>
<aCover>0</aCover>
<aSer1>0</aSer1>
<aSer2>0</aSer2>
<aPa>0</aPa>
<viewmode>1</viewmode>
<vrSel>0</vrSel>
<aSym>0</aSym>
<aTbox>0</aTbox>
<AscS1>0</AscS1>
<AscS2>0</AscS2>
<AscS3>0</AscS3>
<aSer3>0</aSer3>
<eProf>0</eProf>
<aLa>0</aLa>
<aPa1>0</aPa1>
<AscS4>0</AscS4>
<aSer4>0</aSer4>
<StkLoc>0</StkLoc>
<TrcWin>0</TrcWin>
<newCpu>0</newCpu>
<uProt>0</uProt>
</DebugFlag>
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<bAutoGenD>0</bAutoGenD>
<LntExFlags>0</LntExFlags>
<pMisraName></pMisraName>
<pszMrule></pszMrule>
<pSingCmds></pSingCmds>
<pMultCmds></pMultCmds>
<pMisraNamep></pMisraNamep>
<pszMrulep></pszMrulep>
<pSingCmdsp></pSingCmdsp>
<pMultCmdsp></pMultCmdsp>
</TargetOption>
</Target>
<Target>
<TargetName>blinky-rel</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<TargetOption>
<CLKADS>12000000</CLKADS>
<OPTTT>
<gFlags>1</gFlags>
<BeepAtEnd>1</BeepAtEnd>
<RunSim>1</RunSim>
<RunTarget>0</RunTarget>
<RunAbUc>0</RunAbUc>
</OPTTT>
<OPTHX>
<HexSelection>1</HexSelection>
<FlashByte>65535</FlashByte>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
</OPTHX>
<OPTLEX>
<PageWidth>79</PageWidth>
<PageLength>66</PageLength>
<TabStop>8</TabStop>
<ListingPath>.\rel\</ListingPath>
</OPTLEX>
<ListingPage>
<CreateCListing>1</CreateCListing>
<CreateAListing>1</CreateAListing>
<CreateLListing>1</CreateLListing>
<CreateIListing>0</CreateIListing>
<AsmCond>1</AsmCond>
<AsmSymb>1</AsmSymb>
<AsmXref>0</AsmXref>
<CCond>1</CCond>
<CCode>0</CCode>
<CListInc>0</CListInc>
<CSymb>0</CSymb>
<LinkerCodeListing>0</LinkerCodeListing>
</ListingPage>
<OPTXL>
<LMap>1</LMap>
<LComments>1</LComments>
<LGenerateSymbols>1</LGenerateSymbols>
<LLibSym>1</LLibSym>
<LLines>1</LLines>
<LLocSym>1</LLocSym>
<LPubSym>1</LPubSym>
<LXref>0</LXref>
<LExpSel>0</LExpSel>
</OPTXL>
<OPTFL>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>0</IsCurrentTarget>
</OPTFL>
<CpuCode>4</CpuCode>
<DebugOpt>
<uSim>0</uSim>
<uTrg>1</uTrg>
<sLdApp>1</sLdApp>
<sGomain>1</sGomain>
<sRbreak>1</sRbreak>
<sRwatch>1</sRwatch>
<sRmem>1</sRmem>
<sRfunc>1</sRfunc>
<sRbox>1</sRbox>
<tLdApp>1</tLdApp>
<tGomain>0</tGomain>
<tRbreak>1</tRbreak>
<tRwatch>1</tRwatch>
<tRmem>1</tRmem>
<tRfunc>0</tRfunc>
<tRbox>1</tRbox>
<tRtrace>0</tRtrace>
<sRSysVw>1</sRSysVw>
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf>
<nTsel>19</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
<sDlgPa></sDlgPa>
<sIfile></sIfile>
<tDll></tDll>
<tDllPa></tDllPa>
<tDlgDll></tDlgDll>
<tDlgPa></tDlgPa>
<tIfile></tIfile>
<pMon>BIN\lmidk-agdi.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name>ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ`»
´­­ª¤ô </Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>lmidk-agdi</Key>
<Name>-U0E10259B -O4622 -S4 -FO61</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
<Name>-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<MemoryWindow1>
<Mm>
<WinNumber>1</WinNumber>
<SubType>2</SubType>
<ItemText>0x20000200</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow1>
<MemoryWindow2>
<Mm>
<WinNumber>2</WinNumber>
<SubType>0</SubType>
<ItemText>0x400</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow2>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
<DebugFlag>
<trace>0</trace>
<periodic>0</periodic>
<aLwin>1</aLwin>
<aCover>0</aCover>
<aSer1>0</aSer1>
<aSer2>0</aSer2>
<aPa>0</aPa>
<viewmode>1</viewmode>
<vrSel>0</vrSel>
<aSym>0</aSym>
<aTbox>0</aTbox>
<AscS1>0</AscS1>
<AscS2>0</AscS2>
<AscS3>0</AscS3>
<aSer3>0</aSer3>
<eProf>0</eProf>
<aLa>0</aLa>
<aPa1>0</aPa1>
<AscS4>0</AscS4>
<aSer4>0</aSer4>
<StkLoc>0</StkLoc>
<TrcWin>0</TrcWin>
<newCpu>0</newCpu>
<uProt>0</uProt>
</DebugFlag>
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<bAutoGenD>0</bAutoGenD>
<LntExFlags>0</LntExFlags>
<pMisraName></pMisraName>
<pszMrule></pszMrule>
<pSingCmds></pSingCmds>
<pMultCmds></pMultCmds>
<pMisraNamep></pMisraNamep>
<pszMrulep></pszMrulep>
<pSingCmdsp></pSingCmdsp>
<pMultCmdsp></pMultCmdsp>
</TargetOption>
</Target>
<Target>
<TargetName>blinky-spy</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<TargetOption>
<CLKADS>12000000</CLKADS>
<OPTTT>
<gFlags>1</gFlags>
<BeepAtEnd>1</BeepAtEnd>
<RunSim>1</RunSim>
<RunTarget>0</RunTarget>
<RunAbUc>0</RunAbUc>
</OPTTT>
<OPTHX>
<HexSelection>1</HexSelection>
<FlashByte>65535</FlashByte>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
</OPTHX>
<OPTLEX>
<PageWidth>79</PageWidth>
<PageLength>66</PageLength>
<TabStop>8</TabStop>
<ListingPath>.\spy\</ListingPath>
</OPTLEX>
<ListingPage>
<CreateCListing>1</CreateCListing>
<CreateAListing>1</CreateAListing>
<CreateLListing>1</CreateLListing>
<CreateIListing>0</CreateIListing>
<AsmCond>1</AsmCond>
<AsmSymb>1</AsmSymb>
<AsmXref>0</AsmXref>
<CCond>1</CCond>
<CCode>0</CCode>
<CListInc>0</CListInc>
<CSymb>0</CSymb>
<LinkerCodeListing>0</LinkerCodeListing>
</ListingPage>
<OPTXL>
<LMap>1</LMap>
<LComments>1</LComments>
<LGenerateSymbols>1</LGenerateSymbols>
<LLibSym>1</LLibSym>
<LLines>1</LLines>
<LLocSym>1</LLocSym>
<LPubSym>1</LPubSym>
<LXref>0</LXref>
<LExpSel>0</LExpSel>
</OPTXL>
<OPTFL>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>0</IsCurrentTarget>
</OPTFL>
<CpuCode>4</CpuCode>
<DebugOpt>
<uSim>0</uSim>
<uTrg>1</uTrg>
<sLdApp>1</sLdApp>
<sGomain>1</sGomain>
<sRbreak>1</sRbreak>
<sRwatch>1</sRwatch>
<sRmem>1</sRmem>
<sRfunc>1</sRfunc>
<sRbox>1</sRbox>
<tLdApp>1</tLdApp>
<tGomain>0</tGomain>
<tRbreak>1</tRbreak>
<tRwatch>1</tRwatch>
<tRmem>1</tRmem>
<tRfunc>0</tRfunc>
<tRbox>1</tRbox>
<tRtrace>0</tRtrace>
<sRSysVw>1</sRSysVw>
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf>
<nTsel>19</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
<sDlgPa></sDlgPa>
<sIfile></sIfile>
<tDll></tDll>
<tDllPa></tDllPa>
<tDlgDll></tDlgDll>
<tDlgPa></tDlgPa>
<tIfile></tIfile>
<pMon>BIN\lmidk-agdi.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
<Name>UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>lmidk-agdi</Key>
<Name>-U0E2006F4 -O4622 -S4 -FO61</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<MemoryWindow1>
<Mm>
<WinNumber>1</WinNumber>
<SubType>2</SubType>
<ItemText>0x20000200</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow1>
<MemoryWindow2>
<Mm>
<WinNumber>2</WinNumber>
<SubType>0</SubType>
<ItemText>0x400</ItemText>
<AccSizeX>0</AccSizeX>
</Mm>
</MemoryWindow2>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
<DebugFlag>
<trace>0</trace>
<periodic>0</periodic>
<aLwin>1</aLwin>
<aCover>0</aCover>
<aSer1>0</aSer1>
<aSer2>0</aSer2>
<aPa>0</aPa>
<viewmode>1</viewmode>
<vrSel>0</vrSel>
<aSym>0</aSym>
<aTbox>0</aTbox>
<AscS1>0</AscS1>
<AscS2>0</AscS2>
<AscS3>0</AscS3>
<aSer3>0</aSer3>
<eProf>0</eProf>
<aLa>0</aLa>
<aPa1>0</aPa1>
<AscS4>0</AscS4>
<aSer4>0</aSer4>
<StkLoc>0</StkLoc>
<TrcWin>0</TrcWin>
<newCpu>0</newCpu>
<uProt>0</uProt>
</DebugFlag>
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<bAutoGenD>0</bAutoGenD>
<LntExFlags>0</LntExFlags>
<pMisraName></pMisraName>
<pszMrule></pszMrule>
<pSingCmds></pSingCmds>
<pMultCmds></pMultCmds>
<pMisraNamep></pMisraNamep>
<pszMrulep></pszMrulep>
<pSingCmdsp></pSingCmdsp>
<pMultCmdsp></pMultCmdsp>
</TargetOption>
</Target>
<Group>
<GroupName>Applicatioin</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>1</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\bsp.cpp</PathWithFileName>
<FilenameWithoutPath>bsp.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>2</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\blinky.cpp</PathWithFileName>
<FilenameWithoutPath>blinky.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>3</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\main.cpp</PathWithFileName>
<FilenameWithoutPath>main.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>4</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\blinky.hpp</PathWithFileName>
<FilenameWithoutPath>blinky.hpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>5</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\bsp.hpp</PathWithFileName>
<FilenameWithoutPath>bsp.hpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>ek-tm4c123gxl</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c</PathWithFileName>
<FilenameWithoutPath>system_TM4C123GH6PM.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>7</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h</PathWithFileName>
<FilenameWithoutPath>TM4C123GH6PM.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>8</FileNumber>
<FileType>2</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s</PathWithFileName>
<FilenameWithoutPath>startup_TM4C123GH6PM.s</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>9</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h</PathWithFileName>
<FilenameWithoutPath>gpio.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>10</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h</PathWithFileName>
<FilenameWithoutPath>rom.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>11</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h</PathWithFileName>
<FilenameWithoutPath>sysctl.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>12</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h</PathWithFileName>
<FilenameWithoutPath>system_TM4C123GH6PM.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>QP</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>13</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qep_hsm.cpp</PathWithFileName>
<FilenameWithoutPath>qep_hsm.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>14</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qep_msm.cpp</PathWithFileName>
<FilenameWithoutPath>qep_msm.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>15</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_act.cpp</PathWithFileName>
<FilenameWithoutPath>qf_act.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>16</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_actq.cpp</PathWithFileName>
<FilenameWithoutPath>qf_actq.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>17</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_defer.cpp</PathWithFileName>
<FilenameWithoutPath>qf_defer.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_dyn.cpp</PathWithFileName>
<FilenameWithoutPath>qf_dyn.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>19</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_mem.cpp</PathWithFileName>
<FilenameWithoutPath>qf_mem.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_ps.cpp</PathWithFileName>
<FilenameWithoutPath>qf_ps.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_qact.cpp</PathWithFileName>
<FilenameWithoutPath>qf_qact.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_qeq.cpp</PathWithFileName>
<FilenameWithoutPath>qf_qeq.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_qmact.cpp</PathWithFileName>
<FilenameWithoutPath>qf_qmact.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>24</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qf\qf_time.cpp</PathWithFileName>
<FilenameWithoutPath>qf_time.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>25</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qv\qv.cpp</PathWithFileName>
<FilenameWithoutPath>qv.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>QP_port</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>26</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.cpp</PathWithFileName>
<FilenameWithoutPath>qv_port.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
<GroupName>QS</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>27</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qs\qs.cpp</PathWithFileName>
<FilenameWithoutPath>qs.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>28</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qs\qs_rx.cpp</PathWithFileName>
<FilenameWithoutPath>qs_rx.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>29</FileNumber>
<FileType>8</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\src\qs\qstamp.cpp</PathWithFileName>
<FilenameWithoutPath>qstamp.cpp</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
</ProjectOpt>

View File

@ -1,252 +0,0 @@
//============================================================================
// Blinky example, EK-TM4C123GXL board, QV kernel
// Last updated for: @ref qpcpp_7_3_0
// Last updated on 2023-08-24
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "blinky.hpp" // Blinky Application interface
#include "bsp.hpp" // Board Support Package
#include "TM4C123GH6PM.h" // the device specific header (TI)
#include "rom.h" // the built-in ROM functions (TI)
#include "sysctl.h" // system control driver (TI)
#include "gpio.h" // GPIO driver (TI)
// add other drivers if necessary...
#ifdef Q_SPY
#error Simple Blinky Application does not provide Spy build configuration
#endif
namespace { // unnamed local namespace
//Q_DEFINE_THIS_FILE
} // unnamed local namespace
// Local-scope defines -------------------------------------------------------
#define LED_RED (1U << 1U)
#define LED_GREEN (1U << 3U)
#define LED_BLUE (1U << 2U)
#define BTN_SW1 (1U << 4U)
#define BTN_SW2 (1U << 0U)
//============================================================================
// Error handler and ISRs...
extern "C" {
Q_NORETURN Q_onError(char const * const module, int_t const id) {
// for debugging and MUST be changed for deployment of the application
// (assuming that you ship your production code with assertions enabled).
Q_UNUSED_PAR(module);
Q_UNUSED_PAR(id);
QS_ASSERTION(module, id, 10000U);
#ifndef NDEBUG
// light up all LEDs
GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU;
// for debugging, hang on in an endless loop...
for (;;) {
}
#endif
NVIC_SystemReset();
}
//............................................................................
void assert_failed(char const * const module, int_t const id); // prototype
void assert_failed(char const * const module, int_t const id) {
Q_onError(module, id);
}
//............................................................................
void SysTick_Handler(void); // prototype
void SysTick_Handler(void) {
QP::QTimeEvt::TICK_X(0U, nullptr); // process time events at rate 0
}
} // extern "C"
//============================================================================
namespace BSP {
void init() {
// Configure the MPU to prevent NULL-pointer dereferencing ...
MPU->RBAR = 0x0U // base address (NULL)
| MPU_RBAR_VALID_Msk // valid region
| (MPU_RBAR_REGION_Msk & 7U); // region #7
MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region
| (0x0U << MPU_RASR_AP_Pos) // no-access region
| MPU_RASR_ENABLE_Msk; // region enable
MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region
| MPU_CTRL_ENABLE_Msk; // enable the MPU
__ISB();
__DSB();
// enable the MemManage_Handler for MPU exception
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
// NOTE: SystemInit() has been already called from the startup code
// but SystemCoreClock needs to be updated
SystemCoreClockUpdate();
// NOTE: The VFP (hardware Floating Point) unit is configured by QV
// enable clock for to the peripherals used by this application...
SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF
SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF
__ISB();
__DSB();
// configure LEDs (digital output)
GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN);
GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN);
GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U;
// configure switches...
// unlock access to the SW2 pin because it is PROTECTED
GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2
// commit the write (cast const away)
*(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U;
GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input
GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable
GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable
*(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U;
GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2
}
//............................................................................
void start() {
// initialize event pools
static QF_MPOOL_EL(QP::QEvt) smlPoolSto[200];
QP::QF::poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// initialize publish-subscribe
static QP::QSubscrList subscrSto[APP::MAX_PUB_SIG];
QP::QActive::psInit(subscrSto, Q_DIM(subscrSto));
// instantiate and start AOs/threads...
static QP::QEvt const *blinkyQueueSto[10];
APP::AO_Blinky->start(
1U, // QP prio. of the AO
blinkyQueueSto, // event queue storage
Q_DIM(blinkyQueueSto), // queue length [events]
nullptr, 0U, // no stack storage
nullptr); // no initialization param
}
//............................................................................
void ledOn() {
GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU;
}
//............................................................................
void ledOff() {
GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U;
}
//............................................................................
void terminate(int16_t result) {
Q_UNUSED_PAR(result);
}
} // namespace BSP
//============================================================================
namespace QP {
void QF::onStartup() {
// set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate
SysTick_Config(SystemCoreClock / BSP::TICKS_PER_SEC);
// assign all priority bits for preemption-prio. and none to sub-prio.
NVIC_SetPriorityGrouping(0U);
// set priorities of ALL ISRs used in the system, see NOTE1
NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI);
// ...
// enable IRQs...
}
//............................................................................
void QF::onCleanup() {
}
//............................................................................
void QV::onIdle() { // CATION: called with interrupts DISABLED, NOTE0
// toggle the User LED on and then off, see NOTE2
GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on
GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off
#ifdef NDEBUG
// Put the CPU and peripherals to the low-power mode.
// you might need to customize the clock management for your application,
// see the datasheet for your particular Cortex-M MCU.
//
QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts
#else
QF_INT_ENABLE(); // just enable interrupts
#endif
}
} // namespace QP
//============================================================================
// NOTE0:
// The QV::onIdle() callback is called with interrupts disabled, because the
// determination of the idle condition might change by any interrupt posting
// an event. QV::onIdle() must internally enable interrupts, ideally
// atomically with putting the CPU to the power-saving mode.
//
// NOTE1:
// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest
// ISR priority that is disabled by the QF framework. The value is suitable
// for the NVIC_SetPriority() CMSIS function.
//
// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
// with the numerical values of priorities equal or higher than
// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs
// are "QF-aware".
//
// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
// level (i.e., with the numerical values of priorities less than
// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
// Such "QF-unaware" ISRs cannot call any QF services. The only mechanism
// by which a "QF-unaware" ISR can communicate with the QF framework is by
// triggering a "QF-aware" ISR, which can post/publish events.
//
// NOTE2:
// One of the LEDs is used to visualize the idle loop activity. The brightness
// of the LED is proportional to the frequency of the idle loop. Please note
// that the LED is toggled with interrupts locked, so no interrupt execution
// time contributes to the brightness of the User LED.
//

View File

@ -1,309 +0,0 @@
##############################################################################
# Product: Makefile for QP/C++ on EK-TM4C123GXL, QV kernel, GNU-ARM
# Last Updated for Version: 7.0.1
# Date of the Last Update: 2022-05-23
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005-2021 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 3 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# http://sourceforge.net/projects/qpc/files/Qtools/
#
#-----------------------------------------------------------------------------
# project name
#
PROJECT := blinky-qv
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environment var.)
ifeq ($(QPCPP),)
QPCPP := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/arm-cm/qv/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPCPP)/src/qf \
$(QPCPP)/src/qv \
$(QPCPP)/src/qs \
$(QP_PORT_DIR) \
$(QPCPP)/3rd_party/ek-tm4c123gxl \
$(QPCPP)/3rd_party/ek-tm4c123gxl/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR) \
-I$(QPCPP)/3rd_party/CMSIS/Include \
-I$(QPCPP)/3rd_party/ek-tm4c123gxl
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
system_TM4C123GH6PM.c \
startup_TM4C123GH6PM.c
# C++ source files
CPP_SRCS := \
blinky.cpp \
bsp.cpp \
main.cpp
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.cpp \
qep_msm.cpp \
qf_act.cpp \
qf_actq.cpp \
qf_defer.cpp \
qf_dyn.cpp \
qf_mem.cpp \
qf_ps.cpp \
qf_qact.cpp \
qf_qeq.cpp \
qf_qmact.cpp \
qf_time.cpp \
qv.cpp \
qv_port.cpp
QP_ASMS :=
QS_SRCS := \
qs.cpp \
qs_rx.cpp \
qs_fp.cpp
LIB_DIRS :=
LIBS :=
# defines
DEFINES := -DTARGET_IS_TM4C123_RB1
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m4
ARM_FPU := -mfpu=vfp
FLOAT_ABI := -mfloat-abi=softfp
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-g++
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically, you should not need to change anything below this line
# basic utilities (included in Qtools for Windows), see:
# http://sourceforge.net/projects/qpc/files/Qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M4F
#
# combine all the sources...
CPP_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O3 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O3 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
CPP_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CPP) $(CPPFLAGS) $(QPCPP)/src/qs/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -1,71 +0,0 @@
About this Example
==================
This example can be built in two different ways:
- from the command prompt with the provided Makefile.
- from the TI Code Composer Studio with the provided CCS project.
The Makefile
============
The provided Makefile should be easy to adapt for your own projects.
It contains three build configurations: Debug (default), Release, and
Spy.
Also, the Makefile has been specifically designed to work as an external
Makefile with the Eclipse CDT.
The various build configurations are built as follows:
make
make CONF=rel
make CONF=spy
make clean
make CONF=rel clean
make CONF=spy clean
***
NOTE:
The installation folder of the GNU-ARM toolset on YOUR machine needs
to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM.
As described in the comment for this symbol, the GNU-ARM toolset is taken
from: http://gnutoolchains.com/arm-eabi
It is highly recommended to use the same GNU-ARM distribution, especially
for ARM Cortex-M4F projects, due to the support for the hardware FPU
(float-abi=hard).
***
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the GCC linker
script (.ld file), which provides a template of the recommended GCC linker
script for QP applications.
Startup Code
============
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\ek-tm4c123gxl\gcc\startup_TM4C123GH6PM.c
The file startup_TM4C123GH6PM.c provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,139 +0,0 @@
/*****************************************************************************
* Product: Linker script for EK-TM4C123GXL, GNU-ARM linker
* Last Updated for Version: 5.9.8
* Date of the Last Update: 2017-09-13
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 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 3 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:
* Web : http://www.state-machine.com
* Email: info@state-machine.com
*****************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler) /* entry Point */
MEMORY { /* memory map of Tiva TM4C123GH6PM */
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS {
.isr_vector : { /* the vector table goes FIRST into ROM */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >ROM
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >ROM
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM
__exidx_end = .;
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}

View File

@ -1,33 +0,0 @@
::============================================================================
:: Batch file to program the flash of EK-TM4C123GXL
::
:: NOTE: requires the LMFlash programmer (included in QTools for Windows)
::
@echo off
setlocal
@echo Load a given binary file to the flash of EK-TM4C123GXL
@echo usage: flash binary-file
@echo example: flash dbg\blinky-qk.bin
::----------------------------------------------------------------------------
:: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can
:: be found on the PATH. You might need to adjust this symbol to the
:: location of the LMFlash utility on your machine
::
set LMFLASH=LMFlash.exe
if ["%~1"]==[""] (
@echo The binary file missing
@goto end
)
if not exist %~s1 (
@echo The binary file '%1' does not exist
@goto end
)
%LMFLASH% -q ek-tm4c123gxl -e -v -r %1
:end
endlocal

View File

@ -1,53 +0,0 @@
About this Example
==================
This example demonstrates how to use the IAR EWARM IDE to build
a QP application.
IAR Project File
----------------
The IAR EWARM project file provided with this example uses relative paths
to the QP/C framework location (includes, port, and libraries. These
relative paths must be modified when the project is moved to different
relative location.
Stack Size and Heap Size
------------------------
In this project, the size of the C stack and heap are determined in
the linker script blinky-qk.icf (see the next section).
Linker Script
-------------
The IAR linker script provides a template of the recommended linker script
for QP applications. This file needs to be customized to set the
application-specific sizes of the Stack and Heap. This file can be edited
from the IAR EWARM IDE via the Project Options/Linker settings.
Startup Code
------------
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s
The file startup_TM4C123GH6PM.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\blinky-qv.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -1,29 +0,0 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP };

View File

@ -1,80 +0,0 @@
> **NOTE**
This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers.
# Blinky on NUCLEO-C031C6
This example demonstrates the [Blinky application](https://www.state-machine.com/qpcpp/tut_blinky.html) on the STM32 NUCLEO-C031C6 board (ARM Cortex-M0+).
<p align="center">
<img src="./stm32-nucleo-c031c6.jpg"/><br>
<b>STM32 NUCLEO-C031C6</b>
</p>
## Features Demonstrated
- cooperative QV kernel
+ with ARM-KEIL toolchain
+ with GNU-ARM toolchain
+ with IAR-ARM toolchain
- preemptive run-to-completion QK kernel
+ with ARM-KEIL toolchain
+ with GNU-ARM toolchain
+ with IAR-ARM toolchain
## Build Configurations
- Debug
- Release
- Spy - NOT supported for the simple Blinky example
# Code Organization
```
examples\arm-cm\blinky_nucleo-c031c6
|
+---qk // preemptive QK kernel
| +---gnu // GNU-ARM toolchain
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | blinky-qk.uvprojx // uVision project
| \---iar // IAR EWARM
| blinky-qk.eww // IAR EW-ARM workspace
|
\---qv // cooperative QK kernel
| +---gnu // GNU-ARM toolchain
| | Makefile // Makefile for GNU-ARM
| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG)
| | blinky-qv.uvprojx // uVision project
| \---iar // IAR EWARM
| blinky-qv.eww // IAR EW-ARM workspace
```
# Building the example
### GNU/ARM
- open terminal window
- change to the desired directory (either `examples\arm-cm\blinky_nucleo-c031c6\qk\gnu`
or `examples\arm-cm\blinky_nucleo-c031c6\qv\gnu`)
- to build the default Debug configuration, type:
```
make
```
> **NOTE**
The `make` utility for Windows is provided in the QTools collection for Windows.
- to build the Release configuration, type:
```
make CONF=rel
```
### ARM/KEIL MDK
- Open the provided KEIL uVision project (either `blinky-qk.uvprojx` or `blinky-qv.uvprojx`)
in Keil uVision IDE. Build/Debug/Download to the board from the IDE.
- Change the build configuration in the "Project Target" drop-down menu.
### IAR EWARM
- Open the provided IAR EWARM workspace (either `blinky-qk.eww` or `blinky-qv.eww`)
in IAR EWARM IDE. Build/Debug/Download to the board from the IDE.
- Change the build configuration in the "Project Configuration" drop-down menu.

View File

@ -1,123 +0,0 @@
//============================================================================
// QP/C++ Real-Time Embedded Framework (RTEF)
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
//
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
//
// This software is dual-licensed under the terms of the open source GNU
// General Public License version 3 (or any later version), or alternatively,
// under the terms of one of the closed source Quantum Leaps commercial
// licenses.
//
// The terms of the open source GNU General Public License version 3
// can be found at: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @date Last updated on: 2022-08-25
//! @version Last updated Zephyr 3.1.99 and @ref qpcpp_7_1_0
//!
//! @file
//! @brief Blinky example
//!
#include "qpcpp.hpp"
#include "bsp.hpp"
#include "blinky.hpp"
// unnamed namespace for local definitions with internal linkage
namespace {
//Q_DEFINE_THIS_FILE
} // unnamed namespace
namespace APP {
//............................................................................
class Blinky : public QP::QActive {
private:
QP::QTimeEvt m_timeEvt;
public:
Blinky();
static Blinky inst;
protected:
Q_STATE_DECL(initial);
Q_STATE_DECL(off);
Q_STATE_DECL(on);
};
// local objects --------------------------------------------------------------
Blinky Blinky::inst;
// global objects ------------------------------------------------------------
QP::QActive * const AO_Blinky = &Blinky::inst; // opaque pointer
//............................................................................
Blinky::Blinky()
: QP::QActive(&initial),
m_timeEvt(this, TIMEOUT_SIG, 0U)
{
// empty
}
// HSM definition ------------------------------------------------------------
Q_STATE_DEF(Blinky, initial) {
(void)e; // unused parameter
// arm the time event to expire in half a second and every half second
m_timeEvt.armX(BSP::TICKS_PER_SEC/2U, BSP::TICKS_PER_SEC/2U);
return tran(&off);
}
//............................................................................
Q_STATE_DEF(Blinky, off) {
QP::QState status;
switch (e->sig) {
case Q_ENTRY_SIG: {
BSP::ledOff();
status = Q_RET_HANDLED;
break;
}
case TIMEOUT_SIG: {
status = tran(&on);
break;
}
default: {
status = super(&top);
break;
}
}
return status;
}
//............................................................................
Q_STATE_DEF(Blinky, on) {
QP::QState status;
switch (e->sig) {
case Q_ENTRY_SIG: {
BSP::ledOn();
status = Q_RET_HANDLED;
break;
}
case TIMEOUT_SIG: {
status = tran(&off);
break;
}
default: {
status = super(&top);
break;
}
}
return status;
}
} // namespace APP

View File

@ -1,53 +0,0 @@
//============================================================================
// Blinky example
// Last Updated for Version: 7.3.0
// Date of the Last Update: 2023-08-24
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#ifndef BLINKY_HPP_
#define BLINKY_HPP_
namespace APP {
enum AppSignals : QP::QSignal {
DUMMY_SIG = QP::Q_USER_SIG,
MAX_PUB_SIG, // the last published signal
TIMEOUT_SIG,
MAX_SIG // the last signal
};
// opaque pointer to the Blinky AO
extern QP::QActive * const AO_Blinky;
} // namespace APP
#endif // BLINKY_HPP_

View File

@ -1,50 +0,0 @@
//============================================================================
// Blinky example
// Last Updated for Version: 7.3.0
// Date of the Last Update: 2023-08-24
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#ifndef BSP_HPP_
#define BSP_HPP_
namespace BSP {
constexpr std::uint32_t TICKS_PER_SEC {1000U};
void init();
void start();
void terminate(std::int16_t const result);
void ledOn(void);
void ledOff(void);
} // namespace BSP
#endif // BSP_HPP_

View File

@ -1,44 +0,0 @@
//============================================================================
// APP example
// Last updated for version 7.3.0
// Last updated on 2023-08-09
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <www.state-machine.com>
//
// 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "blinky.hpp" // DPP Application interface
#include "bsp.hpp" // Board Support Package
//............................................................................
int main() {
QP::QF::init(); // initialize the framework
BSP::init(); // initialize the BSP
BSP::start(); // start the AOs/Threads
return QP::QF::run(); // run the QF application
}

View File

@ -1,23 +0,0 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
;
; Adapted by Quantum Leaps:
; added STACK as the first section in RW_STACK
; *************************************************************
LR_IROM1 0x08000000 0x00008000 { ; load region size_region
ER_IROM1 0x08000000 0x00008000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_STACK 0x20000000 { ; STACK area
* (STACK, +First)
}
RW_IRAM1 +0 (0x00003000 - 2048) {
.ANY (+RW +ZI)
}
}

View File

@ -1,248 +0,0 @@
//============================================================================
// Blinky example, NUCLEO-C031C6 board, QK kernel
// Last updated for version 7.3.0
// Last updated on 2023-08-28
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <state-machine.com>
//
// 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "blinky.hpp" // Blinky Application interface
#include "bsp.hpp" // Board Support Package
#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used
// add other drivers if necessary...
#ifdef Q_SPY
#error Simple Blinky Application does not provide Spy build configuration
#endif
//============================================================================
namespace { // unnamed namespace for local stuff with internal linkage
Q_DEFINE_THIS_FILE
// Local-scope objects -------------------------------------------------------
constexpr std::uint32_t LD4_PIN {5U};
constexpr std::uint32_t B1_PIN {13U};
//Q_DEFINE_THIS_FILE
} // unnamed local namespace
//============================================================================
// Error handler and ISRs...
extern "C" {
Q_NORETURN Q_onError(char const * const module, int_t const id) {
// NOTE: this implementation of the assertion handler is intended only
// for debugging and MUST be changed for deployment of the application
// (assuming that you ship your production code with assertions enabled).
Q_UNUSED_PAR(module);
Q_UNUSED_PAR(id);
QS_ASSERTION(module, id, 10000U);
#ifndef NDEBUG
// light up the user LED
GPIOA->BSRR = (1U << LD4_PIN); // turn LED on
// for debugging, hang on in an endless loop...
for (;;) {
}
#endif
NVIC_SystemReset();
}
//............................................................................
void assert_failed(char const * const module, int_t const id); // prototype
void assert_failed(char const * const module, int_t const id) {
Q_onError(module, id);
}
// ISRs used in the application ==============================================
void SysTick_Handler(void); // prototype
void SysTick_Handler(void) {
QK_ISR_ENTRY(); // inform QK about entering an ISR
QP::QTimeEvt::TICK_X(0U, nullptr); // process time events at rate 0
QK_ISR_EXIT(); // inform QK about exiting an ISR
}
} // extern "C"
//============================================================================
namespace BSP {
void init() {
// Configure the MPU to prevent NULL-pointer dereferencing ...
MPU->RBAR = 0x0U // base address (NULL)
| MPU_RBAR_VALID_Msk // valid region
| (MPU_RBAR_REGION_Msk & 7U); // region #7
MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region
| (0x0U << MPU_RASR_AP_Pos) // no-access region
| MPU_RASR_ENABLE_Msk; // region enable
MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region
| MPU_CTRL_ENABLE_Msk; // enable the MPU
__ISB();
__DSB();
// NOTE: SystemInit() has been already called from the startup code
// but SystemCoreClock needs to be updated
SystemCoreClockUpdate();
// enable GPIOA clock port for the LED LD4
RCC->IOPENR |= (1U << 0U);
// set all used GPIOA pins as push-pull output, no pull-up, pull-down
GPIOA->MODER &= ~(3U << 2U*LD4_PIN);
GPIOA->MODER |= (1U << 2U*LD4_PIN);
GPIOA->OTYPER &= ~(1U << LD4_PIN);
GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN);
GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN);
GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN);
// enable GPIOC clock port for the Button B1
RCC->IOPENR |= (1U << 2U);
// configure Button B1 pin on GPIOC as input, no pull-up, pull-down
GPIOC->MODER &= ~(3U << 2U*B1_PIN);
GPIOC->PUPDR &= ~(3U << 2U*B1_PIN);
}
//............................................................................
void start() {
// initialize event pools
static QF_MPOOL_EL(QP::QEvt) smlPoolSto[20];
QP::QF::poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// initialize publish-subscribe
static QP::QSubscrList subscrSto[APP::MAX_PUB_SIG];
QP::QActive::psInit(subscrSto, Q_DIM(subscrSto));
// instantiate and start AOs/threads...
static QP::QEvt const *blinkyQueueSto[10];
APP::AO_Blinky->start(
1U, // QP prio. of the AO
blinkyQueueSto, // event queue storage
Q_DIM(blinkyQueueSto), // queue length [events]
nullptr, 0U, // no stack storage
nullptr); // no initialization param
}
//............................................................................
void ledOn() {
GPIOA->BSRR = (1U << LD4_PIN); // turn LED on
}
//............................................................................
void ledOff() {
GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off
}
//............................................................................
void terminate(int16_t result) {
Q_UNUSED_PAR(result);
}
} // namespace BSP
//============================================================================
namespace QP {
// QF callbacks...
void QF::onStartup() {
// set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate
SysTick_Config(SystemCoreClock / BSP::TICKS_PER_SEC);
// assign all priority bits for preemption-prio. and none to sub-prio.
// NOTE: this might have been changed by STM32Cube.
NVIC_SetPriorityGrouping(0U);
// set priorities of ALL ISRs used in the system, see NOTE1
NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U);
// ...
// enable IRQs...
}
//............................................................................
void QF::onCleanup() {
}
//............................................................................
void QK::onIdle() {
// toggle an LED on and then off (not enough LEDs, see NOTE02)
//QF_INT_DISABLE();
//GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on
//GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off
//QF_INT_ENABLE();
#ifdef NDEBUG
// Put the CPU and peripherals to the low-power mode.
// you might need to customize the clock management for your application,
// see the datasheet for your particular Cortex-M MCU.
//
// !!!CAUTION!!!
// The WFI instruction stops the CPU clock, which unfortunately disables
// the JTAG port, so the ST-Link debugger can no longer connect to the
// board. For that reason, the call to __WFI() has to be used with CAUTION.
//
// NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and
// reset the board, then connect with ST-Link Utilities and erase the part.
// The trick with BOOT(0) is it gets the part to run the System Loader
// instead of your broken code. When done disconnect BOOT0, and start over.
//
//__WFI(); // Wait-For-Interrupt
#endif
}
} // namespace QP
//============================================================================
// NOTE1:
// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest
// ISR priority that is disabled by the QF framework. The value is suitable
// for the NVIC_SetPriority() CMSIS function.
//
// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
// with the numerical values of priorities equal or higher than
// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs
// are "QF-aware".
//
// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
// level (i.e., with the numerical values of priorities less than
// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
// Such "QF-unaware" ISRs cannot call any QF services. The only mechanism
// by which a "QF-unaware" ISR can communicate with the QF framework is by
// triggering a "QF-aware" ISR, which can post/publish events.
//
// NOTE2:
// One of the LEDs is used to visualize the idle loop activity. The brightness
// of the LED is proportional to the frequency of invocations of the idle loop.
// Please note that the LED is toggled with interrupts locked, so no interrupt
// execution time contributes to the brightness of the User LED.
//

View File

@ -1,311 +0,0 @@
##############################################################################
# Product: Makefile for QP/C++ on NUCLEO-C031C6, QK kernel, GNU-ARM
# Last Updated for Version: 7.3.0
# Date of the Last Update: 2023-08-26
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005 Quantum Leaps, LLC. <state-machine.com>
#
# 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 3 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# https://github.com/QuantumLeaps/qtools
#-----------------------------------------------------------------------------
# project name
#
PROJECT := blinky-qk
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environment var.)
ifeq ($(QPCPP),)
QPCPP := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/arm-cm/qk/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPCPP)/src/qf \
$(QPCPP)/src/qk \
$(QPCPP)/src/qs \
$(QP_PORT_DIR) \
$(QPCPP)/3rd_party/nucleo-c031c6 \
$(QPCPP)/3rd_party/nucleo-c031c6/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR) \
-I$(QPCPP)/3rd_party/CMSIS/Include \
-I$(QPCPP)/3rd_party/nucleo-c031c6
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
system_stm32c0xx.c \
startup_stm32c031xx.c
# C++ source files
CPP_SRCS := \
blinky.cpp \
bsp.cpp \
main.cpp
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.cpp \
qep_msm.cpp \
qf_act.cpp \
qf_actq.cpp \
qf_defer.cpp \
qf_dyn.cpp \
qf_mem.cpp \
qf_ps.cpp \
qf_qact.cpp \
qf_qeq.cpp \
qf_qmact.cpp \
qf_time.cpp \
qk.cpp \
qk_port.cpp
QP_ASMS :=
QS_SRCS := \
qs.cpp \
qs_rx.cpp \
qs_fp.cpp
LIB_DIRS :=
LIBS :=
# defines
DEFINES := \
-DSTM32C031xx \
-DQK_USE_IRQ_NUM=31 \
-DQK_USE_IRQ_HANDLER=Reserved31_IRQHandler
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m0plus
ARM_FPU :=
FLOAT_ABI :=
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-g++
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically you should not need to change anything below this line
# basic utilities (included in QTools for Windows), see:
# https://www.state-machine.com/qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M
#
# combine all the sources...
CPP_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O2 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O2 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
CPP_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CPP) $(CPPFLAGS) $(QPCPP)/src/qs/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -1,139 +0,0 @@
/*****************************************************************************
* Product: Linker script for EK-TM4C123GXL, GNU-ARM linker
* Last Updated for Version: 5.9.8
* Date of the Last Update: 2017-09-13
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 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 3 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:
* Web : http://www.state-machine.com
* Email: info@state-machine.com
*****************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler) /* entry Point */
MEMORY { /* memory map of Tiva TM4C123GH6PM */
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS {
.isr_vector : { /* the vector table goes FIRST into ROM */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >ROM
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >ROM
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM
__exidx_end = .;
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\blinky-qk.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -1,165 +0,0 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF;
define symbol __ICFEDIT_region_IROM2_start__ = 0x0;
define symbol __ICFEDIT_region_IROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM1_start__ = 0x0;
define symbol __ICFEDIT_region_EROM1_end__ = 0x0;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0);
define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0);
define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0);
define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0);
define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0);
define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0);
define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0);
define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0);
define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0);
define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0);
if (use_IROM1)
{
define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__];
}
else
{
define region IROM1_region = [];
}
if (use_IROM2)
{
define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
}
else
{
define region IROM2_region = [];
}
define region IROM_region = IROM1_region | IROM2_region;
if (use_EROM1)
{
define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__];
}
else
{
define region EROM1_region = [];
}
if (use_EROM2)
{
define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__];
}
else
{
define region EROM2_region = [];
}
if (use_EROM3)
{
define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__];
}
else
{
define region EROM3_region = [];
}
define region EROM_region = EROM1_region | EROM2_region | EROM3_region;
if (use_IRAM1)
{
define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__];
}
else
{
define region IRAM1_region = [];
}
if (use_IRAM2)
{
define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__];
}
else
{
define region IRAM2_region = [];
}
define region IRAM_region = IRAM1_region | IRAM2_region;
if (use_ERAM1)
{
define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__];
}
else
{
define region ERAM1_region = [];
}
if (use_ERAM2)
{
define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__];
}
else
{
define region ERAM2_region = [];
}
if (use_ERAM3)
{
define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__];
}
else
{
define region ERAM3_region = [];
}
define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region;
initialize by copy { readwrite };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
// Required in a multi-threaded application
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
if (!isempty(IROM_region))
{
place in IROM_region { readonly };
}
if (!isempty(EROM_region))
{
place in EROM_region { readonly section application_specific_ro };
}
if (!isempty(IRAM_region))
{
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */
place in IRAM_region { readwrite, block PROC_STACK, block HEAP };
}
if (!isempty(ERAM_region))
{
place in ERAM_region { readwrite section application_specific_rw };
}

View File

@ -1,23 +0,0 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
;
; Adapted by Quantum Leaps:
; added STACK as the first section in RW_STACK
; *************************************************************
LR_IROM1 0x08000000 0x00008000 { ; load region size_region
ER_IROM1 0x08000000 0x00008000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_STACK 0x20000000 { ; STACK area
* (STACK, +First)
}
RW_IRAM1 +0 (0x00003000 - 2048) {
.ANY (+RW +ZI)
}
}

View File

@ -1,255 +0,0 @@
//============================================================================
// Blinky example, NUCLEO-C031C6 board, QV kernel
// Last updated for version 7.3.0
// Last updated on 2023-08-28
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <state-machine.com>
//
// 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "blinky.hpp" // Blinky Application interface
#include "bsp.hpp" // Board Support Package
#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used
// add other drivers if necessary...
#ifdef Q_SPY
#error Simple Blinky Application does not provide Spy build configuration
#endif
//============================================================================
namespace { // unnamed namespace for local stuff with internal linkage
Q_DEFINE_THIS_FILE
// Local-scope objects -------------------------------------------------------
constexpr std::uint32_t LD4_PIN {5U};
constexpr std::uint32_t B1_PIN {13U};
//Q_DEFINE_THIS_FILE
} // unnamed local namespace
//============================================================================
// Error handler and ISRs...
extern "C" {
Q_NORETURN Q_onError(char const * const module, int_t const id) {
// NOTE: this implementation of the assertion handler is intended only
// for debugging and MUST be changed for deployment of the application
// (assuming that you ship your production code with assertions enabled).
Q_UNUSED_PAR(module);
Q_UNUSED_PAR(id);
QS_ASSERTION(module, id, 10000U);
#ifndef NDEBUG
// light up the user LED
GPIOA->BSRR = (1U << LD4_PIN); // turn LED on
// for debugging, hang on in an endless loop...
for (;;) {
}
#endif
NVIC_SystemReset();
}
//............................................................................
void assert_failed(char const * const module, int_t const id); // prototype
void assert_failed(char const * const module, int_t const id) {
Q_onError(module, id);
}
// ISRs used in the application ==============================================
void SysTick_Handler(void); // prototype
void SysTick_Handler(void) {
QP::QTimeEvt::TICK_X(0U, nullptr); // process time events at rate 0
QV_ARM_ERRATUM_838869();
}
} // extern "C"
//============================================================================
namespace BSP {
void init() {
// Configure the MPU to prevent NULL-pointer dereferencing ...
MPU->RBAR = 0x0U // base address (NULL)
| MPU_RBAR_VALID_Msk // valid region
| (MPU_RBAR_REGION_Msk & 7U); // region #7
MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region
| (0x0U << MPU_RASR_AP_Pos) // no-access region
| MPU_RASR_ENABLE_Msk; // region enable
MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region
| MPU_CTRL_ENABLE_Msk; // enable the MPU
__ISB();
__DSB();
// NOTE: SystemInit() has been already called from the startup code
// but SystemCoreClock needs to be updated
SystemCoreClockUpdate();
// enable GPIOA clock port for the LED LD4
RCC->IOPENR |= (1U << 0U);
// set all used GPIOA pins as push-pull output, no pull-up, pull-down
GPIOA->MODER &= ~(3U << 2U*LD4_PIN);
GPIOA->MODER |= (1U << 2U*LD4_PIN);
GPIOA->OTYPER &= ~(1U << LD4_PIN);
GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN);
GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN);
GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN);
// enable GPIOC clock port for the Button B1
RCC->IOPENR |= (1U << 2U);
// configure Button B1 pin on GPIOC as input, no pull-up, pull-down
GPIOC->MODER &= ~(3U << 2U*B1_PIN);
GPIOC->PUPDR &= ~(3U << 2U*B1_PIN);
}
//............................................................................
void start() {
// initialize event pools
static QF_MPOOL_EL(QP::QEvt) smlPoolSto[20];
QP::QF::poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// initialize publish-subscribe
static QP::QSubscrList subscrSto[APP::MAX_PUB_SIG];
QP::QActive::psInit(subscrSto, Q_DIM(subscrSto));
// instantiate and start AOs/threads...
static QP::QEvt const *blinkyQueueSto[10];
APP::AO_Blinky->start(
1U, // QP prio. of the AO
blinkyQueueSto, // event queue storage
Q_DIM(blinkyQueueSto), // queue length [events]
nullptr, 0U, // no stack storage
nullptr); // no initialization param
}
//............................................................................
void ledOn() {
GPIOA->BSRR = (1U << LD4_PIN); // turn LED on
}
//............................................................................
void ledOff() {
GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off
}
//............................................................................
void terminate(int16_t result) {
Q_UNUSED_PAR(result);
}
} // namespace BSP
//============================================================================
namespace QP {
// QF callbacks...
void QF::onStartup() {
// set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate
SysTick_Config(SystemCoreClock / BSP::TICKS_PER_SEC);
// assign all priority bits for preemption-prio. and none to sub-prio.
// NOTE: this might have been changed by STM32Cube.
NVIC_SetPriorityGrouping(0U);
// set priorities of ALL ISRs used in the system, see NOTE1
NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U);
// ...
// enable IRQs...
}
//............................................................................
void QF::onCleanup() {
}
//............................................................................
void QV::onIdle() {
// toggle an LED on and then off (not enough LEDs, see NOTE02)
//GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on
//GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off
#ifdef NDEBUG
// Put the CPU and peripherals to the low-power mode.
// you might need to customize the clock management for your application,
// see the datasheet for your particular Cortex-M MCU.
//
// !!!CAUTION!!!
// QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU
// clock, which unfortunately disables the JTAG port, so the ST-Link
// debugger can no longer connect to the board. For that reason, the call
// to QV_CPU_SLEEP() has to be used with CAUTION.
//
// NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and
// reset the board, then connect with ST-Link Utilities and erase the part.
// The trick with BOOT(0) is it gets the part to run the System Loader
// instead of your broken code. When done disconnect BOOT0, and start over.
//
//QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts
QF_INT_ENABLE(); // for now, just enable interrupts
#else
QF_INT_ENABLE(); // just enable interrupts
#endif
}
} // namespace QP
//============================================================================
// NOTE0:
// The QV_onIdle() callback is called with interrupts disabled, because the
// determination of the idle condition might change by any interrupt posting
// an event. QV_onIdle() must internally enable interrupts, ideally
// atomically with putting the CPU to the power-saving mode.
//
// NOTE1:
// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest
// ISR priority that is disabled by the QF framework. The value is suitable
// for the NVIC_SetPriority() CMSIS function.
//
// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
// with the numerical values of priorities equal or higher than
// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any other QF/QV services.
// These ISRs are "QF-aware".
//
// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
// level (i.e., with the numerical values of priorities less than
// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
// Such "QF-unaware" ISRs cannot call ANY QF/QV services. The only mechanism
// by which a "QF-unaware" ISR can communicate with the QF framework is by
// triggering a "QF-aware" ISR, which can post/publish events.
//
// NOTE2:
// The User LED is used to visualize the idle loop activity. The brightness
// of the LED is proportional to the frequency of the idle loop.
// Please note that the LED is toggled with interrupts locked, so no interrupt
// execution time contributes to the brightness of the User LED.
//

View File

@ -1,309 +0,0 @@
##############################################################################
# Product: Makefile for QP/C++ on NUCLEO-C031C6, QV kernel, GNU-ARM
# Last Updated for Version: 7.3.0
# Date of the Last Update: 2023-05-26
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005 Quantum Leaps, LLC. <state-machine.com>
#
# 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 3 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# https://github.com/QuantumLeaps/qtools
#-----------------------------------------------------------------------------
# project name
#
PROJECT := blinky-qv
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environment var.)
ifeq ($(QPCPP),)
QPCPP := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/arm-cm/qv/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPCPP)/src/qf \
$(QPCPP)/src/qv \
$(QPCPP)/src/qs \
$(QP_PORT_DIR) \
$(QPCPP)/3rd_party/nucleo-c031c6 \
$(QPCPP)/3rd_party/nucleo-c031c6/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR) \
-I$(QPCPP)/3rd_party/CMSIS/Include \
-I$(QPCPP)/3rd_party/nucleo-c031c6
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
system_stm32c0xx.c \
startup_stm32c031xx.c
# C++ source files
CPP_SRCS := \
bsp.cpp \
main.cpp \
blinky.cpp
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.cpp \
qep_msm.cpp \
qf_act.cpp \
qf_actq.cpp \
qf_defer.cpp \
qf_dyn.cpp \
qf_mem.cpp \
qf_ps.cpp \
qf_qact.cpp \
qf_qeq.cpp \
qf_qmact.cpp \
qf_time.cpp \
qv.cpp \
qv_port.cpp
QP_ASMS :=
QS_SRCS := \
qs.cpp \
qs_rx.cpp \
qs_fp.cpp
LIB_DIRS :=
LIBS :=
# defines
DEFINES := \
-DSTM32C031xx
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m0plus
ARM_FPU :=
FLOAT_ABI :=
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-g++
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically you should not need to change anything below this line
# basic utilities (included in QTools for Windows), see:
# https://www.state-machine.com/qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M
#
# combine all the sources...
CPP_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O2 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O2 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
CPP_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CPP) $(CPPFLAGS) $(QPCPP)/src/qs/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -1,135 +0,0 @@
/*****************************************************************************
* Linker script for for STM32C031C6, GNU-ARM linker
*
* Q u a n t u m L e a P s
* ------------------------
* Modern Embedded Software
*
* Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
*
* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
*
* This software is dual-licensed under the terms of the open source GNU
* General Public License version 3 (or any later version), or alternatively,
* under the terms of one of the closed source Quantum Leaps commercial
* licenses.
*
* The terms of the open source GNU General Public License version 3
* can be found at: <www.gnu.org/licenses/gpl-3.0>
*
* The terms of the closed source Quantum Leaps commercial licenses
* can be found at: <www.state-machine.com/licensing>
*
* Redistributions in source code must retain this top-level comment block.
* Plagiarizing this software to sidestep the license obligations is illegal.
*
* Contact information:
* <www.state-machine.com/licensing>
* <info@state-machine.com>
*****************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler) /* entry Point */
MEMORY { /* memory map of STM32C031C6 */
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS {
.isr_vector : { /* the vector table goes FIRST into ROM */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >ROM
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >ROM
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM
__exidx_end = .;
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\blinky-qv.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -1,165 +0,0 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF;
define symbol __ICFEDIT_region_IROM2_start__ = 0x0;
define symbol __ICFEDIT_region_IROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM1_start__ = 0x0;
define symbol __ICFEDIT_region_EROM1_end__ = 0x0;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0);
define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0);
define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0);
define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0);
define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0);
define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0);
define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0);
define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0);
define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0);
define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0);
if (use_IROM1)
{
define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__];
}
else
{
define region IROM1_region = [];
}
if (use_IROM2)
{
define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
}
else
{
define region IROM2_region = [];
}
define region IROM_region = IROM1_region | IROM2_region;
if (use_EROM1)
{
define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__];
}
else
{
define region EROM1_region = [];
}
if (use_EROM2)
{
define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__];
}
else
{
define region EROM2_region = [];
}
if (use_EROM3)
{
define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__];
}
else
{
define region EROM3_region = [];
}
define region EROM_region = EROM1_region | EROM2_region | EROM3_region;
if (use_IRAM1)
{
define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__];
}
else
{
define region IRAM1_region = [];
}
if (use_IRAM2)
{
define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__];
}
else
{
define region IRAM2_region = [];
}
define region IRAM_region = IRAM1_region | IRAM2_region;
if (use_ERAM1)
{
define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__];
}
else
{
define region ERAM1_region = [];
}
if (use_ERAM2)
{
define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__];
}
else
{
define region ERAM2_region = [];
}
if (use_ERAM3)
{
define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__];
}
else
{
define region ERAM3_region = [];
}
define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region;
initialize by copy { readwrite };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
// Required in a multi-threaded application
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
if (!isempty(IROM_region))
{
place in IROM_region { readonly };
}
if (!isempty(EROM_region))
{
place in EROM_region { readonly section application_specific_ro };
}
if (!isempty(IRAM_region))
{
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */
place in IRAM_region { readwrite, block PROC_STACK, block HEAP };
}
if (!isempty(ERAM_region))
{
place in ERAM_region { readwrite section application_specific_rw };
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View File

@ -1,5 +0,0 @@
![STM32 EFM32-SLSTK3401A](../../../doxygen/images/bd_EFM32-SLSTK3401A.jpg)
Documentation for this example is available in the QP/C Manual at:
- https://www.state-machine.com/qpcpp/arm-cm_dpp_efm32-slstk3401a.html

View File

@ -1,59 +0,0 @@
//============================================================================
// Product: DPP example
// Last Updated for Version: 7.3.0
// Date of the Last Update: 2023-08-12
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <www.state-machine.com>
//
// 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#ifndef BSP_HPP_
#define BSP_HPP_
namespace BSP {
constexpr std::uint32_t TICKS_PER_SEC {100};
void init();
void start();
void displayPaused(std::uint8_t const paused);
void displayPhilStat(std::uint8_t const n, char const *stat);
void terminate(std::int16_t const result);
void randomSeed(std::uint32_t const seed); // random seed
std::uint32_t random(); // pseudo-random generator
// for testing...
void wait4SW1();
void ledOn();
void ledOff();
extern QP::QTicker *AO_Ticker0;
} // namespace BSP
#endif // BSP_HPP_

View File

@ -1,111 +0,0 @@
//$file${.::dpp.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//
// Model: dpp.qm
// File: ${.::dpp.hpp}
//
// This code has been generated by QM 5.3.0 <www.state-machine.com/qm>.
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This generated code is open source software: you can redistribute it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation.
//
// This code 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.
//
// NOTE:
// Alternatively, this generated code may be distributed 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.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//
//$endhead${.::dpp.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#ifndef DPP_HPP_
#define DPP_HPP_
//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace APP {
//${Shared::AppSignals} ......................................................
enum AppSignals : QP::QSignal {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a Philo eat
DONE_SIG, // published by Philo when done eating
PAUSE_SIG, // published by BSP to pause the application
SERVE_SIG, // published by BSP to serve re-start serving forks
TEST_SIG, // published by BSP to test the application
MAX_PUB_SIG, // the last published signal
TIMEOUT_SIG, // posted by time event to Philo
HUNGRY_SIG, // posted by hungry Philo to Table
MAX_SIG // the last signal
};
//${Shared::produce_sig_dict} ................................................
#ifdef Q_SPY
inline void produce_sig_dict() {
QS_SIG_DICTIONARY(EAT_SIG, nullptr);
QS_SIG_DICTIONARY(DONE_SIG, nullptr);
QS_SIG_DICTIONARY(PAUSE_SIG, nullptr);
QS_SIG_DICTIONARY(SERVE_SIG, nullptr);
QS_SIG_DICTIONARY(TEST_SIG, nullptr);
QS_SIG_DICTIONARY(TIMEOUT_SIG, nullptr);
QS_SIG_DICTIONARY(HUNGRY_SIG, nullptr);
}
#endif // def Q_SPY
//${Shared::N_PHILO} .........................................................
constexpr std::uint8_t N_PHILO {5};
//${Shared::TableEvt} ........................................................
class TableEvt : public QP::QEvt {
public:
std::uint8_t philoId;
public:
constexpr TableEvt(
QP::QSignal sig,
std::uint8_t id)
: QEvt(sig),
philoId(id)
{}
#ifdef QEVT_DYN_CTOR
TableEvt(std::uint8_t id)
: QEvt(QP::QEvt::DYNAMIC),
philoId(id)
{}
#endif // def QEVT_DYN_CTOR
}; // class TableEvt
//${Shared::AO_Philo[N_PHILO]} ...............................................
extern QP::QActive * const AO_Philo[N_PHILO];
//${Shared::AO_Table} ........................................................
extern QP::QActive * const AO_Table;
} // namespace APP
//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#ifdef QXK_HPP_
namespace APP {
extern QP::QXThread * const TH_XThread1;
extern QP::QXThread * const TH_XThread2;
extern QP::QXSemaphore TH_sema;
extern QP::QXMutex TH_mutex;
} // namespace APP
#endif // QXK_HPP_
#endif // DPP_HPP_

View File

@ -1,528 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="5.3.0" links="1">
<documentation>Dining Philosopher Problem example application</documentation>
<!--${qpcpp}-->
<framework name="qpcpp"/>
<!--${Shared}-->
<package name="Shared" stereotype="0x01" namespace="APP::">
<!--${Shared::AppSignals}-->
<attribute name="AppSignals" type="enum" visibility="0x04" properties="0x00">
<code>: QP::QSignal {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a Philo eat
DONE_SIG, // published by Philo when done eating
PAUSE_SIG, // published by BSP to pause the application
SERVE_SIG, // published by BSP to serve re-start serving forks
TEST_SIG, // published by BSP to test the application
MAX_PUB_SIG, // the last published signal
TIMEOUT_SIG, // posted by time event to Philo
HUNGRY_SIG, // posted by hungry Philo to Table
MAX_SIG // the last signal
};</code>
</attribute>
<!--${Shared::produce_sig_dict}-->
<operation name="produce_sig_dict?def Q_SPY" type="void" visibility="0x00" properties="0x02">
<code>QS_SIG_DICTIONARY(EAT_SIG, nullptr);
QS_SIG_DICTIONARY(DONE_SIG, nullptr);
QS_SIG_DICTIONARY(PAUSE_SIG, nullptr);
QS_SIG_DICTIONARY(SERVE_SIG, nullptr);
QS_SIG_DICTIONARY(TEST_SIG, nullptr);
QS_SIG_DICTIONARY(TIMEOUT_SIG, nullptr);
QS_SIG_DICTIONARY(HUNGRY_SIG, nullptr);</code>
</operation>
<!--${Shared::N_PHILO}-->
<attribute name="N_PHILO" type="constexpr std::uint8_t" visibility="0x04" properties="0x00">
<code>{5};</code>
</attribute>
<!--${Shared::TableEvt}-->
<class name="TableEvt" superclass="qpcpp::QEvt">
<!--${Shared::TableEvt::philoId}-->
<attribute name="philoId" type="std::uint8_t" visibility="0x00" properties="0x00"/>
<!--${Shared::TableEvt::TableEvt}-->
<operation name="TableEvt" type="constexpr" visibility="0x00" properties="0x02">
<!--${Shared::TableEvt::TableEvt::sig}-->
<parameter name="sig" type="QP::QSignal"/>
<!--${Shared::TableEvt::TableEvt::id}-->
<parameter name="id" type="std::uint8_t"/>
<code> : QEvt(sig),
philoId(id)</code>
</operation>
<!--${Shared::TableEvt::TableEvt}-->
<operation name="TableEvt?def QEVT_DYN_CTOR" type="" visibility="0x00" properties="0x02">
<!--${Shared::TableEvt::TableEvt::id}-->
<parameter name="id" type="std::uint8_t"/>
<code> : QEvt(QP::QEvt::DYNAMIC),
philoId(id)</code>
</operation>
</class>
<!--${Shared::AO_Philo[N_PHILO]}-->
<attribute name="AO_Philo[N_PHILO]" type="QP::QActive * const" visibility="0x00" properties="0x00">
<code>= {
&amp;Philo::inst[0],
&amp;Philo::inst[1],
&amp;Philo::inst[2],
&amp;Philo::inst[3],
&amp;Philo::inst[4]
};</code>
</attribute>
<!--${Shared::AO_Table}-->
<attribute name="AO_Table" type="QP::QActive * const" visibility="0x00" properties="0x00">
<code>= &amp;Table::inst;</code>
</attribute>
</package>
<!--${AOs}-->
<package name="AOs" stereotype="0x02" namespace="APP::">
<!--${AOs::Philo}-->
<class name="Philo" superclass="qpcpp::QActive">
<documentation>The Philo AO and the N_PHILO instances</documentation>
<!--${AOs::Philo::m_timeEvt}-->
<attribute name="m_timeEvt" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
<!--${AOs::Philo::m_id}-->
<attribute name="m_id" type="std::uint8_t" visibility="0x02" properties="0x00"/>
<!--${AOs::Philo::inst[N_PHILO]}-->
<attribute name="inst[N_PHILO]" type="Philo" visibility="0x00" properties="0x01"/>
<!--${AOs::Philo::Philo}-->
<operation name="Philo" type="" visibility="0x00" properties="0x00">
<code> : QActive(Q_STATE_CAST(&amp;initial)),
m_timeEvt(this, TIMEOUT_SIG, 0U),
m_id(0xFFU)</code>
</operation>
<!--${AOs::Philo::SM}-->
<statechart properties="0x02">
<!--${AOs::Philo::SM::initial}-->
<initial target="../1">
<action>Q_UNUSED_PAR(e);
m_id = static_cast&lt;std::uint8_t&gt;(this - &amp;inst[0]);
QS_OBJ_ARR_DICTIONARY(&amp;Philo::inst[m_id], m_id);
QS_OBJ_ARR_DICTIONARY(&amp;Philo::inst[m_id].m_timeEvt, m_id);
subscribe(EAT_SIG);
subscribe(TEST_SIG);</action>
<initial_glyph conn="2,4,5,1,20,7,-2">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<!--${AOs::Philo::SM::thinking}-->
<state name="thinking">
<entry>m_timeEvt.armX(think_time(), 0U);</entry>
<exit>m_timeEvt.disarm();</exit>
<!--${AOs::Philo::SM::thinking::TIMEOUT}-->
<tran trig="TIMEOUT" target="../../2">
<tran_glyph conn="2,16,3,1,20,14,-2">
<action box="0,-2,12,2"/>
</tran_glyph>
</tran>
<!--${AOs::Philo::SM::thinking::EAT, DONE}-->
<tran trig="EAT, DONE">
<action>// EAT or DONE must be for other Philos than this one
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoId != m_id);</action>
<tran_glyph conn="2,20,3,-1,14">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<!--${AOs::Philo::SM::thinking::TEST}-->
<tran trig="TEST">
<tran_glyph conn="2,24,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<state_glyph node="2,6,18,20">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<!--${AOs::Philo::SM::hungry}-->
<state name="hungry">
<entry>#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, m_id);
#else
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe-&gt;philoId = m_id;
#endif
AO_Table-&gt;POST(pe, this);</entry>
<!--${AOs::Philo::SM::hungry::EAT}-->
<tran trig="EAT">
<!--${AOs::Philo::SM::hungry::EAT::[e->philoId==m_id]}-->
<choice target="../../../3">
<guard brief="e-&gt;philoId == m_id">Q_EVT_CAST(TableEvt)-&gt;philoId == m_id</guard>
<choice_glyph conn="10,36,5,1,12,10,-2">
<action box="1,0,23,6"/>
</choice_glyph>
</choice>
<tran_glyph conn="2,36,3,-1,8">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<!--${AOs::Philo::SM::hungry::DONE}-->
<tran trig="DONE">
<action>// DONE must be for other Philos than this one
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoId != m_id);</action>
<tran_glyph conn="2,40,3,-1,14">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,28,18,14">
<entry box="1,2,5,2"/>
</state_glyph>
</state>
<!--${AOs::Philo::SM::eating}-->
<state name="eating">
<entry>m_timeEvt.armX(eat_time(), 0U);</entry>
<exit>m_timeEvt.disarm();
#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, m_id);
#else
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe-&gt;philoId = m_id;
#endif
QP::QActive::PUBLISH(pe, this);</exit>
<!--${AOs::Philo::SM::eating::TIMEOUT}-->
<tran trig="TIMEOUT" target="../../1">
<tran_glyph conn="2,54,3,1,22,-41,-4">
<action box="0,-2,13,2"/>
</tran_glyph>
</tran>
<!--${AOs::Philo::SM::eating::EAT, DONE}-->
<tran trig="EAT, DONE">
<action>// EAT or DONE must be for other Philos than this one
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoId != m_id);</action>
<tran_glyph conn="2,58,3,-1,14">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,44,18,18">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<state_diagram size="36,64"/>
</statechart>
</class>
<!--${AOs::Table}-->
<class name="Table" superclass="qpcpp::QActive">
<!--${AOs::Table::m_fork[N_PHILO]}-->
<attribute name="m_fork[N_PHILO]" type="std::uint8_t" visibility="0x02" properties="0x00"/>
<!--${AOs::Table::m_isHungry[N_PHILO]}-->
<attribute name="m_isHungry[N_PHILO]" type="bool" visibility="0x02" properties="0x00"/>
<!--${AOs::Table::inst}-->
<attribute name="inst" type="Table" visibility="0x00" properties="0x01"/>
<!--${AOs::Table::Table}-->
<operation name="Table" type="" visibility="0x00" properties="0x00">
<code> : QActive(Q_STATE_CAST(&amp;initial))
for (std::uint8_t n = 0U; n &lt; N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}</code>
</operation>
<!--${AOs::Table::SM}-->
<statechart properties="0x02">
<!--${AOs::Table::SM::initial}-->
<initial target="../1/2">
<action>Q_UNUSED_PAR(e);
QS_OBJ_DICTIONARY(&amp;Table::inst);
subscribe(DONE_SIG);
subscribe(PAUSE_SIG);
subscribe(SERVE_SIG);
subscribe(TEST_SIG);
for (std::uint8_t n = 0U; n &lt; N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
BSP::displayPhilStat(n, THINKING);
}</action>
<initial_glyph conn="2,4,5,1,46,20,-10">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<!--${AOs::Table::SM::active}-->
<state name="active">
<!--${AOs::Table::SM::active::TEST}-->
<tran trig="TEST">
<tran_glyph conn="2,12,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::EAT}-->
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="2,16,3,-1,14">
<action box="0,-2,10,4"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::serving}-->
<state name="serving">
<entry brief="give pending permissions to eat"> // give permissions to eat...
for (std::uint8_t n = 0U; n &lt; N_PHILO; ++n) {
if (m_isHungry[n]
&amp;&amp; (m_fork[left(n)] == FREE)
&amp;&amp; (m_fork[n] == FREE))
{
m_fork[left(n)] = USED;
m_fork[n] = USED;
#ifdef QEVT_DYN_CTOR
TableEvt const *te = Q_NEW(TableEvt, EAT_SIG, n);
#else
TableEvt *te = Q_NEW(TableEvt, EAT_SIG);
te-&gt;philoId = n;
#endif
QP::QActive::PUBLISH(te, this);
m_isHungry[n] = false;
BSP::displayPhilStat(n, EATING);
}
}</entry>
<!--${AOs::Table::SM::active::serving::HUNGRY}-->
<tran trig="HUNGRY">
<action>std::uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoId;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
BSP::displayPhilStat(n, HUNGRY);
std::uint8_t m = left(n);</action>
<!--${AOs::Table::SM::active::serving::HUNGRY::[bothfree]}-->
<choice>
<guard brief="both free">(m_fork[m] == FREE) &amp;&amp; (m_fork[n] == FREE)</guard>
<action>m_fork[m] = USED;
m_fork[n] = USED;
#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n);
#else
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoId = n;
#endif
QP::QActive::PUBLISH(pe, this);
BSP::displayPhilStat(n, EATING);</action>
<choice_glyph conn="20,28,5,-1,12">
<action box="1,0,10,2"/>
</choice_glyph>
</choice>
<!--${AOs::Table::SM::active::serving::HUNGRY::[else]}-->
<choice>
<guard>else</guard>
<action>m_isHungry[n] = true;</action>
<choice_glyph conn="20,28,4,-1,4,12">
<action box="1,4,6,2"/>
</choice_glyph>
</choice>
<tran_glyph conn="4,28,3,-1,16">
<action box="0,-2,8,2"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::serving::DONE}-->
<tran trig="DONE">
<action>std::uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoId;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
BSP::displayPhilStat(n, THINKING);
std::uint8_t m = left(n);
// both forks of Phil[n] must be used
Q_ASSERT((m_fork[n] == USED) &amp;&amp; (m_fork[m] == USED));
m_fork[m] = FREE;
m_fork[n] = FREE;
m = right(n); // check the right neighbor
if (m_isHungry[m] &amp;&amp; (m_fork[m] == FREE)) {
m_fork[n] = USED;
m_fork[m] = USED;
m_isHungry[m] = false;
#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m);
#else
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoId = m;
#endif
QP::QActive::PUBLISH(pe, this);
BSP::displayPhilStat(m, EATING);
}
m = left(n); // check the left neighbor
n = left(m); // left fork of the left neighbor
if (m_isHungry[m] &amp;&amp; (m_fork[n] == FREE)) {
m_fork[m] = USED;
m_fork[n] = USED;
m_isHungry[m] = false;
#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m);
#else
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoId = m;
#endif
QP::QActive::PUBLISH(pe, this);
BSP::displayPhilStat(m, EATING);
}</action>
<tran_glyph conn="4,36,3,-1,16">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::serving::EAT}-->
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="4,40,3,-1,16">
<action box="0,-2,12,4"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::serving::PAUSE}-->
<tran trig="PAUSE" target="../../3">
<tran_glyph conn="4,44,3,1,36,8,-2">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,20,34,26">
<entry box="1,2,27,2"/>
</state_glyph>
</state>
<!--${AOs::Table::SM::active::paused}-->
<state name="paused">
<entry>BSP::displayPaused(1U);</entry>
<exit>BSP::displayPaused(0U);</exit>
<!--${AOs::Table::SM::active::paused::SERVE}-->
<tran trig="SERVE" target="../../2">
<tran_glyph conn="4,62,3,1,38,-31,-4">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::paused::HUNGRY}-->
<tran trig="HUNGRY">
<action>std::uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoId;
// philo ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
m_isHungry[n] = true;
BSP::displayPhilStat(n, HUNGRY);</action>
<tran_glyph conn="4,66,3,-1,16">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<!--${AOs::Table::SM::active::paused::DONE}-->
<tran trig="DONE">
<action>std::uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoId;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!m_isHungry[n]));
BSP::displayPhilStat(n, THINKING);
std::uint8_t m = left(n);
// both forks of Phil[n] must be used
Q_ASSERT((m_fork[n] == USED) &amp;&amp; (m_fork[m] == USED));
m_fork[m] = FREE;
m_fork[n] = FREE;</action>
<tran_glyph conn="4,70,3,-1,16">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,48,34,24">
<entry box="1,2,18,4"/>
<exit box="1,6,18,4"/>
</state_glyph>
</state>
<state_glyph node="2,6,44,68"/>
</state>
<state_diagram size="50,76"/>
</statechart>
</class>
</package>
<!--${.}-->
<directory name=".">
<!--${.::dpp.hpp}-->
<file name="dpp.hpp">
<text>#ifndef DPP_HPP_
#define DPP_HPP_
$declare ${Shared}
#ifdef QXK_HPP_
namespace APP {
extern QP::QXThread * const TH_XThread1;
extern QP::QXThread * const TH_XThread2;
extern QP::QXSemaphore TH_sema;
extern QP::QXMutex TH_mutex;
} // namespace APP
#endif // QXK_HPP_
#endif // DPP_HPP_</text>
</file>
<!--${.::philo.cpp}-->
<file name="philo.cpp">
<text>#include &quot;qpcpp.hpp&quot; // QP/C++ real-time embedded framework
#include &quot;dpp.hpp&quot; // DPP Application interface
#include &quot;bsp.hpp&quot; // Board Support Package
//----------------------------------------------------------------------------
namespace { // unnamed namespace for local definitions with internal linkage
Q_DEFINE_THIS_FILE
// helper function to provide a randomized think time for Philos
static inline QP::QTimeEvtCtr think_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP::random() % BSP::TICKS_PER_SEC)
+ (BSP::TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
static inline QP::QTimeEvtCtr eat_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP::random() % BSP::TICKS_PER_SEC)
+ BSP::TICKS_PER_SEC);
}
} // unnamed namespace
//----------------------------------------------------------------------------
$declare ${AOs::Philo}
$define ${Shared::AO_Philo[N_PHILO]}
$define ${AOs::Philo}</text>
</file>
<!--${.::table.cpp}-->
<file name="table.cpp">
<text>#include &quot;qpcpp.hpp&quot; // QP/C++ real-time embedded framework
#include &quot;dpp.hpp&quot; // DPP Application interface
#include &quot;bsp.hpp&quot; // Board Support Package
$declare ${AOs::Table}
//----------------------------------------------------------------------------
// unnamed namespace for local definitions with internal linkage
namespace {
Q_DEFINE_THIS_FILE
// helper function to provide the RIGHT neighbour of a Philo[n]
static inline std::uint8_t right(std::uint8_t const n) {
return static_cast&lt;std::uint8_t&gt;((n + (APP::N_PHILO - 1U)) % APP::N_PHILO);
}
// helper function to provide the LEFT neighbour of a Philo[n]
static inline std::uint8_t left(std::uint8_t const n) {
return static_cast&lt;std::uint8_t&gt;((n + 1U) % APP::N_PHILO);
}
static constexpr std::uint8_t FREE {0U};
static constexpr std::uint8_t USED {1U};
static constexpr char const * const THINKING {&quot;thinking&quot;};
static constexpr char const * const HUNGRY {&quot;hungry &quot;};
static constexpr char const * const EATING {&quot;eating &quot;};
} // unnamed namespace
//----------------------------------------------------------------------------
$define ${Shared::AO_Table}
$define ${AOs::Table}</text>
</file>
</directory>
</model>

View File

@ -1,44 +0,0 @@
//============================================================================
// APP example
// Last updated for version 7.3.0
// Last updated on 2023-08-09
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <www.state-machine.com>
//
// 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 3 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 <www.gnu.org/licenses/>.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "dpp.hpp" // DPP Application interface
#include "bsp.hpp" // Board Support Package
//............................................................................
int main() {
QP::QF::init(); // initialize the framework and the underlying RT kernel
BSP::init(); // initialize the BSP
BSP::start(); // start the AOs/Threads
return QP::QF::run(); // run the QF application
}

View File

@ -1,264 +0,0 @@
//$file${.::philo.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//
// Model: dpp.qm
// File: ${.::philo.cpp}
//
// This code has been generated by QM 5.3.0 <www.state-machine.com/qm>.
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This generated code is open source software: you can redistribute it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation.
//
// This code 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.
//
// NOTE:
// Alternatively, this generated code may be distributed 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.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//
//$endhead${.::philo.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "dpp.hpp" // DPP Application interface
#include "bsp.hpp" // Board Support Package
//----------------------------------------------------------------------------
namespace { // unnamed namespace for local definitions with internal linkage
Q_DEFINE_THIS_FILE
// helper function to provide a randomized think time for Philos
static inline QP::QTimeEvtCtr think_time() {
return static_cast<QP::QTimeEvtCtr>((BSP::random() % BSP::TICKS_PER_SEC)
+ (BSP::TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
static inline QP::QTimeEvtCtr eat_time() {
return static_cast<QP::QTimeEvtCtr>((BSP::random() % BSP::TICKS_PER_SEC)
+ BSP::TICKS_PER_SEC);
}
} // unnamed namespace
//----------------------------------------------------------------------------
//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace APP {
//${AOs::Philo} ..............................................................
class Philo : public QP::QActive {
private:
QP::QTimeEvt m_timeEvt;
std::uint8_t m_id;
public:
static Philo inst[N_PHILO];
public:
Philo();
protected:
Q_STATE_DECL(initial);
Q_STATE_DECL(thinking);
Q_STATE_DECL(hungry);
Q_STATE_DECL(eating);
}; // class Philo
} // namespace APP
//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// Check for the minimum required QP version
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U))
#error qpcpp version 7.3.0 or higher required
#endif
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace APP {
//${Shared::AO_Philo[N_PHILO]} ...............................................
QP::QActive * const AO_Philo[N_PHILO] = {
&Philo::inst[0],
&Philo::inst[1],
&Philo::inst[2],
&Philo::inst[3],
&Philo::inst[4]
};
} // namespace APP
//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace APP {
//${AOs::Philo} ..............................................................
Philo Philo::inst[N_PHILO];
//${AOs::Philo::Philo} .......................................................
Philo::Philo()
: QActive(Q_STATE_CAST(&initial)),
m_timeEvt(this, TIMEOUT_SIG, 0U),
m_id(0xFFU)
{}
//${AOs::Philo::SM} ..........................................................
Q_STATE_DEF(Philo, initial) {
//${AOs::Philo::SM::initial}
Q_UNUSED_PAR(e);
m_id = static_cast<std::uint8_t>(this - &inst[0]);
QS_OBJ_ARR_DICTIONARY(&Philo::inst[m_id], m_id);
QS_OBJ_ARR_DICTIONARY(&Philo::inst[m_id].m_timeEvt, m_id);
subscribe(EAT_SIG);
subscribe(TEST_SIG);
QS_FUN_DICTIONARY(&Philo::thinking);
QS_FUN_DICTIONARY(&Philo::hungry);
QS_FUN_DICTIONARY(&Philo::eating);
return tran(&thinking);
}
//${AOs::Philo::SM::thinking} ................................................
Q_STATE_DEF(Philo, thinking) {
QP::QState status_;
switch (e->sig) {
//${AOs::Philo::SM::thinking}
case Q_ENTRY_SIG: {
m_timeEvt.armX(think_time(), 0U);
status_ = Q_RET_HANDLED;
break;
}
//${AOs::Philo::SM::thinking}
case Q_EXIT_SIG: {
m_timeEvt.disarm();
status_ = Q_RET_HANDLED;
break;
}
//${AOs::Philo::SM::thinking::TIMEOUT}
case TIMEOUT_SIG: {
status_ = tran(&hungry);
break;
}
//${AOs::Philo::SM::thinking::EAT, DONE}
case EAT_SIG: // intentionally fall through
case DONE_SIG: {
// EAT or DONE must be for other Philos than this one
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != m_id);
status_ = Q_RET_HANDLED;
break;
}
//${AOs::Philo::SM::thinking::TEST}
case TEST_SIG: {
status_ = Q_RET_HANDLED;
break;
}
default: {
status_ = super(&top);
break;
}
}
return status_;
}
//${AOs::Philo::SM::hungry} ..................................................
Q_STATE_DEF(Philo, hungry) {
QP::QState status_;
switch (e->sig) {
//${AOs::Philo::SM::hungry}
case Q_ENTRY_SIG: {
#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, m_id);
#else
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe->philoId = m_id;
#endif
AO_Table->POST(pe, this);
status_ = Q_RET_HANDLED;
break;
}
//${AOs::Philo::SM::hungry::EAT}
case EAT_SIG: {
//${AOs::Philo::SM::hungry::EAT::[e->philoId==m_id]}
if (Q_EVT_CAST(TableEvt)->philoId == m_id) {
status_ = tran(&eating);
}
else {
status_ = Q_RET_UNHANDLED;
}
break;
}
//${AOs::Philo::SM::hungry::DONE}
case DONE_SIG: {
// DONE must be for other Philos than this one
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != m_id);
status_ = Q_RET_HANDLED;
break;
}
default: {
status_ = super(&top);
break;
}
}
return status_;
}
//${AOs::Philo::SM::eating} ..................................................
Q_STATE_DEF(Philo, eating) {
QP::QState status_;
switch (e->sig) {
//${AOs::Philo::SM::eating}
case Q_ENTRY_SIG: {
m_timeEvt.armX(eat_time(), 0U);
status_ = Q_RET_HANDLED;
break;
}
//${AOs::Philo::SM::eating}
case Q_EXIT_SIG: {
m_timeEvt.disarm();
#ifdef QEVT_DYN_CTOR
TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, m_id);
#else
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe->philoId = m_id;
#endif
QP::QActive::PUBLISH(pe, this);
status_ = Q_RET_HANDLED;
break;
}
//${AOs::Philo::SM::eating::TIMEOUT}
case TIMEOUT_SIG: {
status_ = tran(&thinking);
break;
}
//${AOs::Philo::SM::eating::EAT, DONE}
case EAT_SIG: // intentionally fall through
case DONE_SIG: {
// EAT or DONE must be for other Philos than this one
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != m_id);
status_ = Q_RET_HANDLED;
break;
}
default: {
status_ = super(&top);
break;
}
}
return status_;
}
} // namespace APP
//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,50 +0,0 @@
About this Example
==================
This example demonstrates how to use the uVision IDE together with
the MDK-ARM toolchain.
uVision Project File
====================
The MDK-ARM uVision project file provided with this example uses
relative paths to the QP framework location (includes, port, and
libraries. These relative paths must be modified when the project
is moved to different relative location.
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the
command-line options for the ARM assembler (see the Asm tab in
the "Options for Target" dialog box in uVision). Specifically,
you should define symbols: Stack_Size=xxx Heap_Size=yyy, where
xxx represents a numerical value of stack size and yyy the
numerical value of the heap size (for most embedded projects
yyy should be 0, as the using the heap is not recommended).
Startup Code
============
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\efm32pg1b\arm\startup_efm32pg1b.s
The file startup_efm32pg1b.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,23 +0,0 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
;
; Modified by Quantum Leaps:
; added STACK as the first section in RW_STACK
; *************************************************************
LR_IROM1 0x00000000 0x00020000 { ; load region size_region
ER_IROM1 0x00000000 0x00020000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_STACK 0x20000000 { ; <== Quantum Leaps
* (STACK, +First)
}
RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048!
.ANY (+RW +ZI)
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,559 +0,0 @@
//============================================================================
// Product: DPP example, EFM32-SLSTK3401A board, QK kernel
// Last updated for version 7.3.2
// Last updated on 2023-12-13
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <state-machine.com>
//
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
//
// This software is dual-licensed under the terms of the open source GNU
// General Public License version 3 (or any later version), or alternatively,
// under the terms of one of the closed source Quantum Leaps commercial
// licenses.
//
// The terms of the open source GNU General Public License version 3
// can be found at: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "dpp.hpp" // DPP Application interface
#include "bsp.hpp" // Board Support Package
#include "em_device.h" // the device specific header (SiLabs)
#include "em_cmu.h" // Clock Management Unit (SiLabs)
#include "em_gpio.h" // GPIO (SiLabs)
#include "em_usart.h" // USART (SiLabs)
// add other drivers if necessary...
//============================================================================
namespace { // unnamed namespace for local stuff with internal linkage
Q_DEFINE_THIS_FILE
// Local-scope objects -------------------------------------------------------
constexpr GPIO_Port_TypeDef LED_PORT {gpioPortF};
constexpr std::uint32_t LED0_PIN {4U};
constexpr std::uint32_t LED1_PIN {5U};
constexpr GPIO_Port_TypeDef PB_PORT {gpioPortF};
constexpr std::uint32_t PB0_PIN {6U};
constexpr std::uint32_t PB1_PIN {7U};
static std::uint32_t l_rndSeed;
#ifdef Q_SPY
// QSpy source IDs
static QP::QSpyId const l_SysTick_Handler = { 0U };
static QP::QSpyId const l_GPIO_EVEN_IRQHandler = { 0U };
static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL));
static QP::QSTimeCtr QS_tickTime_;
static QP::QSTimeCtr QS_tickPeriod_;
enum AppRecords { // application-specific trace records
PHILO_STAT = QP::QS_USER,
PAUSED_STAT,
CONTEXT_SW,
};
#endif
} // unnamed namespace
//============================================================================
// Error handler and ISRs...
extern "C" {
Q_NORETURN Q_onError(char const * const module, int_t const id) {
// NOTE: this implementation of the error handler is intended only
// for debugging and MUST be changed for deployment of the application
// (assuming that you ship your production code with assertions enabled).
Q_UNUSED_PAR(module);
Q_UNUSED_PAR(id);
QS_ASSERTION(module, id, 10000U);
#ifndef NDEBUG
// light up both LEDs
GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN));
// for debugging, hang on in an endless loop...
for (;;) {
}
#else
NVIC_SystemReset();
for (;;) { // explicitly "no-return"
}
#endif
}
//............................................................................
void assert_failed(char const * const module, int_t const id); // prototype
void assert_failed(char const * const module, int_t const id) {
Q_onError(module, id);
}
// ISRs used in the application ==============================================
void SysTick_Handler(void); // prototype
void SysTick_Handler(void) {
QK_ISR_ENTRY(); // inform QK about entering an ISR
QP::QTimeEvt::TICK_X(0U, &l_SysTick_Handler); // time events at rate 0
// Perform the debouncing of buttons. The algorithm for debouncing
// adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
// and Michael Barr, page 71.
static struct {
std::uint32_t depressed;
std::uint32_t previous;
} buttons = { 0U, 0U };
std::uint32_t current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1
std::uint32_t tmp = buttons.depressed; // save the depressed buttons
buttons.depressed |= (buttons.previous & current); // set depressed
buttons.depressed &= (buttons.previous | current); // clear released
buttons.previous = current; // update the history
tmp ^= buttons.depressed; // changed debounced depressed
current = buttons.depressed;
if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed?
if ((current & (1U << PB0_PIN)) != 0U) { // is PB0 depressed?
static QP::QEvt const pauseEvt(APP::PAUSE_SIG);
QP::QActive::PUBLISH(&pauseEvt, &l_SysTick_Handler);
}
else { // the button is released
static QP::QEvt const serveEvt(APP::SERVE_SIG);
QP::QActive::PUBLISH(&serveEvt, &l_SysTick_Handler);
}
}
#ifdef Q_SPY
tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG
QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover
#endif
QK_ISR_EXIT(); // inform QK about exiting an ISR
}
//............................................................................
// interrupt handler for testing preemptions
void GPIO_EVEN_IRQHandler(void); // prototype
void GPIO_EVEN_IRQHandler(void) {
QK_ISR_ENTRY(); // inform QK about entering an ISR
static QP::QEvt const testEvt(APP::TEST_SIG);
APP::AO_Table->POST(&testEvt, &l_GPIO_EVEN_IRQHandler);
QK_ISR_EXIT(); // inform QK about exiting an ISR
}
//............................................................................
#ifdef Q_SPY
// ISR for receiving bytes from the QSPY Back-End
// NOTE: This ISR is "QF-unaware" meaning that it does not interact with
// the QF/QK and is not disabled. Such ISRs don't need to call
// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events.
void USART0_RX_IRQHandler(void); // prototype
void USART0_RX_IRQHandler(void) {
// while RX FIFO NOT empty
while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0U) {
std::uint8_t b = static_cast<uint8_t>(l_USART0->RXDATA);
QP::QS::rxPut(b);
}
QK_ARM_ERRATUM_838869();
}
#endif // Q_SPY
//............................................................................
#ifdef QF_ON_CONTEXT_SW
// NOTE: the context-switch callback is called with interrupts DISABLED
void QF_onContextSw(QP::QActive *prev, QP::QActive *next) {
QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section!
QS_OBJ(prev);
QS_OBJ(next);
QS_END_INCRIT()
}
#endif // QF_ON_CONTEXT_SW
} // extern "C"
//============================================================================
namespace BSP {
void init() {
// Configure the MPU to prevent NULL-pointer dereferencing ...
MPU->RBAR = 0x0U // base address (NULL)
| MPU_RBAR_VALID_Msk // valid region
| (MPU_RBAR_REGION_Msk & 7U); // region #7
MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region
| (0x0U << MPU_RASR_AP_Pos) // no-access region
| MPU_RASR_ENABLE_Msk; // region enable
MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region
| MPU_CTRL_ENABLE_Msk; // enable the MPU
__ISB();
__DSB();
// enable the MemManage_Handler for MPU exception
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
// NOTE: SystemInit() has been already called from the startup code
// but SystemCoreClock needs to be updated
SystemCoreClockUpdate();
// NOTE: The VFP (hardware Floating Point) unit is configured by QK
// enable clock for to the peripherals used by this application...
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
// configure the LEDs
GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0);
GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0);
GPIO_PinOutClear(LED_PORT, LED0_PIN);
GPIO_PinOutClear(LED_PORT, LED1_PIN);
// configure the Buttons
GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1);
GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1);
BSP::randomSeed(1234U);
// initialize the QS software tracing...
if (!QS_INIT(nullptr)) {
Q_ERROR();
}
// dictionaries...
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler);
QS_USR_DICTIONARY(PHILO_STAT);
QS_USR_DICTIONARY(PAUSED_STAT);
QS_USR_DICTIONARY(CONTEXT_SW);
QS_ONLY(APP::produce_sig_dict());
// setup the QS filters...
QS_GLB_FILTER(QP::QS_ALL_RECORDS); // all records
QS_GLB_FILTER(-QP::QS_QF_TICK); // exclude the clock tick
QS_LOC_FILTER(-(APP::N_PHILO + 3U)); // exclude prio. of AO_Ticker0
}
//............................................................................
void start() {
// initialize event pools
static QF_MPOOL_EL(APP::TableEvt) smlPoolSto[2*APP::N_PHILO];
QP::QF::poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// initialize publish-subscribe
static QP::QSubscrList subscrSto[APP::MAX_PUB_SIG];
QP::QActive::psInit(subscrSto, Q_DIM(subscrSto));
// start AOs/threads...
static QP::QEvt const *philoQueueSto[APP::N_PHILO][APP::N_PHILO];
for (std::uint8_t n = 0U; n < APP::N_PHILO; ++n) {
APP::AO_Philo[n]->start(
// NOTE: set the preemption-threshold of all Philos to
// the same level, so that they cannot preempt each other.
Q_PRIO(n + 3U, APP::N_PHILO + 2U), // QF-prio/pre-thre.
philoQueueSto[n], // event queue storage
Q_DIM(philoQueueSto[n]), // queue length [events]
nullptr, 0U); // no stack storage
}
static QP::QEvt const *tableQueueSto[APP::N_PHILO];
APP::AO_Table->start(
APP::N_PHILO + 7U, // QP prio. of the AO
tableQueueSto, // event queue storage
Q_DIM(tableQueueSto), // queue length [events]
nullptr, 0U); // no stack storage
}
//............................................................................
void displayPhilStat(std::uint8_t n, char const *stat) {
Q_UNUSED_PAR(n);
if (stat[0] == 'e') {
GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN);
}
else {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN);
}
// app-specific trace record...
QS_BEGIN_ID(PHILO_STAT, APP::AO_Table->getPrio())
QS_U8(1, n); // Philosopher number
QS_STR(stat); // Philosopher status
QS_END()
}
//............................................................................
void displayPaused(std::uint8_t const paused) {
if (paused != 0U) {
GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN);
}
else {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN);
}
// application-specific trace record
QS_BEGIN_ID(PAUSED_STAT, APP::AO_Table->getPrio())
QS_U8(1, paused); // Paused status
QS_END()
}
//............................................................................
void randomSeed(uint32_t const seed) {
l_rndSeed = seed;
}
//............................................................................
std::uint32_t random() { // a very cheap pseudo-random-number generator
// Some floating point code is to exercise the VFP...
float volatile x = 3.1415926F;
x = x + 2.7182818F;
QP::QSchedStatus lockStat = QP::QK::schedLock(APP::N_PHILO);
// "Super-Duper" Linear Congruential Generator (LCG)
// LCG(2^32, 3*7*11*13*23, 0, seed)
std::uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U);
l_rndSeed = rnd; // set for the next time
QP::QK::schedUnlock(lockStat);
return (rnd >> 8U);
}
//............................................................................
void ledOn() {
GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN);
}
//............................................................................
void ledOff() {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN);
}
//............................................................................
void terminate(int16_t result) {
Q_UNUSED_PAR(result);
}
} // namespace BSP
//============================================================================
//============================================================================
namespace QP {
// QF callbacks --------------------------------------------------------------
void QF::onStartup() {
// set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate
SysTick_Config(SystemCoreClock / BSP::TICKS_PER_SEC);
// assign all priority bits for preemption-prio. and none to sub-prio.
NVIC_SetPriorityGrouping(0U);
// set priorities of ALL ISRs used in the system, see NOTE1
NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt
NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U);
NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U);
// ...
// enable IRQs...
NVIC_EnableIRQ(GPIO_EVEN_IRQn);
#ifdef Q_SPY
NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX
#endif
}
//............................................................................
void QF::onCleanup() {
}
//............................................................................
void QK::onIdle() {
// toggle the User LED on and then off, see NOTE3
// QF_INT_DISABLE();
// GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN);
// GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN);
// QF_INT_ENABLE();
#ifdef Q_SPY
QF_INT_DISABLE();
QS::rxParse(); // parse all the received bytes
QF_INT_ENABLE();
if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty?
QF_INT_DISABLE();
std::uint16_t b = QS::getByte();
QF_INT_ENABLE();
if (b != QS_EOD) { // not End-Of-Data?
l_USART0->TXDATA = b; // put into the DR register
}
}
#elif defined NDEBUG
// Put the CPU and peripherals to the low-power mode.
// you might need to customize the clock management for your application,
// see the datasheet for your particular Cortex-M MCU.
//
__WFI(); // Wait-For-Interrupt
#endif
}
//============================================================================
// QS callbacks...
#ifdef Q_SPY
namespace QS {
//............................................................................
bool onStartup(void const *arg) {
Q_UNUSED_PAR(arg);
static std::uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel
initBuf(qsTxBuf, sizeof(qsTxBuf));
static std::uint8_t qsRxBuf[100]; // buffer for QS-RX channel
rxInitBuf(qsRxBuf, sizeof(qsRxBuf));
static USART_InitAsync_TypeDef init = {
usartEnable, // Enable RX/TX when init completed
0, // Use current clock for configuring baudrate
115200, // 115200 bits/s
usartOVS16, // 16x oversampling
usartDatabits8, // 8 databits
usartNoParity, // No parity
usartStopbits1, // 1 stopbit
0, // Do not disable majority vote
0, // Not USART PRS input mode
usartPrsRxCh0, // PRS channel 0
0, // Auto CS functionality enable/disable switch
0, // Auto CS Hold cycles
0 // Auto CS Setup cycles
};
// Enable peripheral clocks
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
// To avoid false start, configure output as high
GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin
GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin
// Enable DK RS232/UART switch
GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1);
CMU_ClockEnable(cmuClock_USART0, true);
// configure the UART for the desired baud rate, 8-N-1 operation
init.enable = usartDisable;
USART_InitAsync(l_USART0, &init);
// enable pins at correct UART/USART location.
l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 &
~(_USART_ROUTELOC0_TXLOC_MASK
| _USART_ROUTELOC0_RXLOC_MASK));
// Clear previous RX interrupts
USART_IntClear(l_USART0, USART_IF_RXDATAV);
NVIC_ClearPendingIRQ(USART0_RX_IRQn);
// Enable RX interrupts
USART_IntEnable(l_USART0, USART_IF_RXDATAV);
// NOTE: do not enable the UART0 interrupt in the NVIC yet.
// Wait till QF::onStartup()
// Finally enable the UART
USART_Enable(l_USART0, usartEnable);
QS_tickPeriod_ = SystemCoreClock / BSP::TICKS_PER_SEC;
QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero
return true; // return success
}
//............................................................................
void onCleanup() {
}
//............................................................................
QSTimeCtr onGetTime() { // NOTE: invoked with interrupts DISABLED
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set?
return QS_tickTime_ - (QSTimeCtr)SysTick->VAL;
}
else { // the rollover occurred, but the SysTick_ISR did not run yet
return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL;
}
}
//............................................................................
// NOTE:
// No critical section in QS::onFlush() to avoid nesting of critical sections
// in case QS::onFlush() is called from Q_onError().
void onFlush() {
for (;;) {
std::uint16_t b = getByte();
if (b != QS_EOD) {
while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) {
}
l_USART0->TXDATA = b;
}
else {
break;
}
}
}
//............................................................................
void onReset() {
NVIC_SystemReset();
}
//............................................................................
void onCommand(std::uint8_t cmdId, std::uint32_t param1,
std::uint32_t param2, std::uint32_t param3)
{
Q_UNUSED_PAR(cmdId);
Q_UNUSED_PAR(param1);
Q_UNUSED_PAR(param2);
Q_UNUSED_PAR(param3);
}
} // namespace QS
#endif // Q_SPY
//----------------------------------------------------------------------------
} // namespace QP
//============================================================================
// NOTE1:
// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest
// ISR priority that is disabled by the QF framework. The value is suitable
// for the NVIC_SetPriority() CMSIS function.
//
// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
// with the numerical values of priorities equal or higher than
// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/
// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are
// "QF-aware".
//
// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
// level (i.e., with the numerical values of priorities less than
// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they
// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism
// by which a "QF-unaware" ISR can communicate with the QF framework is by
// triggering a "QF-aware" ISR, which can post/publish events.
//
// NOTE2:
// The User LED is used to visualize the idle loop activity. The brightness
// of the LED is proportional to the frequency of the idle loop.
// Please note that the LED is toggled with interrupts locked, so no interrupt
// execution time contributes to the brightness of the User LED.

View File

@ -1,316 +0,0 @@
##############################################################################
# Product: Makefile for QP/C++ on EMF32-SLSTK3401A, QK kernel, GNU-ARM
# Last Updated for Version: 7.3.0
# Date of the Last Update: 2023-09-08
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005 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 3 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# https://github.com/QuantumLeaps/qtools/releases
#
#-----------------------------------------------------------------------------
# project name
#
PROJECT := dpp-qk
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environment var.)
ifeq ($(QPCPP),)
QPCPP := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/arm-cm/qk/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPCPP)/src/qf \
$(QPCPP)/src/qk \
$(QPCPP)/src/qs \
$(QP_PORT_DIR) \
$(QPCPP)/3rd_party/efm32pg1b \
$(QPCPP)/3rd_party/efm32pg1b/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR) \
-I$(QPCPP)/3rd_party/CMSIS/Include \
-I$(QPCPP)/3rd_party/efm32pg1b
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
startup_efm32pg1b.c \
system_efm32pg1b.c \
em_cmu.c \
em_emu.c \
em_gpio.c \
em_usart.c
# C++ source files
CPP_SRCS := \
bsp.cpp \
main.cpp \
philo.cpp \
table.cpp
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.cpp \
qep_msm.cpp \
qf_act.cpp \
qf_actq.cpp \
qf_defer.cpp \
qf_dyn.cpp \
qf_mem.cpp \
qf_ps.cpp \
qf_qact.cpp \
qf_qeq.cpp \
qf_qmact.cpp \
qf_time.cpp \
qk.cpp \
qk_port.cpp
QP_ASMS :=
QS_SRCS := \
qs.cpp \
qs_rx.cpp \
qs_fp.cpp
LIB_DIRS :=
LIBS :=
# defines
DEFINES := \
-DQP_CONFIG \
-DEFM32PG1B200F256GM48=1
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m4
ARM_FPU := -mfpu=vfp
FLOAT_ABI := -mfloat-abi=softfp
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-g++
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically, you should not need to change anything below this line
# basic utilities (included in Qtools for Windows), see:
# http://sourceforge.net/projects/qpc/files/Qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M
#
# combine all the sources...
CPP_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
CPP_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CPP) $(CPPFLAGS) $(QPCPP)/src/qs/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -1,71 +0,0 @@
About this Example
==================
This example can be built from the command prompt with the provided
Makefile. The example can also be imported as a Makefile-based
project into Eclipse-based IDEs.
The Makefile
============
The provided Makefile should be easy to adapt for your own projects.
It contains three build configurations: Debug (default), Release, and
Spy.
Also, the Makefile has been specifically designed to work as an external
Makefile with the Eclipse CDT.
The various build configurations are built as follows:
make
make CONF=rel
make CONF=spy
make clean
make CONF=rel clean
make CONF=spy clean
***
NOTE:
The installation folder of the GNU-ARM toolset on YOUR machine needs
to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM.
As described in the comment for this symbol, the GNU-ARM toolset is taken
from: http://gnutoolchains.com/arm-eabi
It is highly recommended to use the same GNU-ARM distribution, especially
for ARM Cortex-M4F projects, due to the support for the hardware FPU
(float-abi=hard).
***
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the GCC linker
script (.ld file), which provides a template of the recommended GCC linker
script for QP applications.
Startup Code
============
The startup code for the EFM32PG1B200F256GM48 MCU used in this project
is located in the "3rd_party" folder in the following location:
qpc\3rd_party\efm32pg1b\gnu\startup_efm32pg1b.c
The file startup_efm32pg1b.c provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,139 +0,0 @@
/*****************************************************************************
* Product: Linker script for EFM32-SLSTK3401A, GNU-ARM linker
* Last Updated for Version: 5.9.8
* Date of the Last Update: 2017-09-13
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 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 3 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:
* https://state-machine.com
* mailto:info@state-machine.com
*****************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler) /* entry Point */
MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS {
.isr_vector : { /* the vector table goes FIRST into ROM */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >ROM
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >ROM
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM
__exidx_end = .;
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}

View File

@ -1,49 +0,0 @@
::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board
::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html
::
setlocal
@echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin
::----------------------------------------------------------------------------
:: NOTE: Adjust the following symbol to the location of the
:: JLink utility on your machine
::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat
@goto end
)
if ["%~1"]==[""] (
@echo The binary file missing
@goto end
)
if not exist %~s1 (
@echo The binary file '%1' does not exist
@goto end
)
:: generate the Jlink command file depending on the first parameter %1
@echo si 1 >flash.jlink
@echo speed 4000 >>flash.jlink
@echo r >>flash.jlink
@echo h >>flash.jlink
@echo loadbin %1, 0 >>flash.jlink
@echo exit >>flash.jlink
@echo on
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
@echo off
@del flash.jlink
:end
endlocal

View File

@ -1,53 +0,0 @@
About this Example
==================
This example demonstrates how to use the IAR EWARM IDE to build
a QP application.
IAR Project File
----------------
The IAR EWARM project file provided with this example uses relative paths
to the QP/C framework location (includes, port, and libraries. These
relative paths must be modified when the project is moved to different
relative location.
Stack Size and Heap Size
------------------------
In this project, the size of the C stack and heap are determined in
the linker script blinky-qk.icf (see the next section).
Linker Script
-------------
The IAR linker script provides a template of the recommended linker script
for QP applications. This file needs to be customized to set the
application-specific sizes of the Stack and Heap. This file can be edited
from the IAR EWARM IDE via the Project Options/Linker settings.
Startup Code
============
The startup code for the EFM32PG1B200F256GM48 MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\efm32pg1b\iar\startup_efm32pg1b.s
The file startup_efm32pg1b.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\dpp-qk.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -1,29 +0,0 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP };

View File

@ -1,59 +0,0 @@
//============================================================================
// QP configuration file example
// Last updated for version: 7.3.0
// Last updated on: 2023-09-07
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
//
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
//
// This software is dual-licensed under the terms of the open source GNU
// General Public License version 3 (or any later version), or alternatively,
// under the terms of one of the closed source Quantum Leaps commercial
// licenses.
//
// The terms of the open source GNU General Public License version 3
// can be found at: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
#ifndef QP_CONFIG_HPP_
#define QP_CONFIG_HPP_
// NOTE:
// The QP configuration takes effect only when the macro QP_CONFIG
// is defined on the command-line to the compiler for all QP source files.
// use event constructors for dynamic events
#define QEVT_DYN_CTOR
// for QK kernel:
// use the FPUEH_IRQHandler() with IRQ number 33
// for the QXK return-from-preemption handler
#define QK_USE_IRQ_HANDLER FPUEH_IRQHandler
#define QK_USE_IRQ_NUM 33
// for QXK kernel:
// use the FPUEH_IRQHandler() with IRQ number 33
// for the QXK return-from-preemption handler
#define QXK_USE_IRQ_HANDLER FPUEH_IRQHandler
#define QXK_USE_IRQ_NUM 33
#ifdef Q_SPY
// for the Spy build configuration, enable the context-switch callback
#define QF_ON_CONTEXT_SW
#endif
#endif // QP_CONFIG_HPP_

View File

@ -1,50 +0,0 @@
About this Example
==================
This example demonstrates how to use the uVision IDE together with
the MDK-ARM toolchain.
uVision Project File
====================
The MDK-ARM uVision project file provided with this example uses
relative paths to the QP framework location (includes, port, and
libraries. These relative paths must be modified when the project
is moved to different relative location.
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the
command-line options for the ARM assembler (see the Asm tab in
the "Options for Target" dialog box in uVision). Specifically,
you should define symbols: Stack_Size=xxx Heap_Size=yyy, where
xxx represents a numerical value of stack size and yyy the
numerical value of the heap size (for most embedded projects
yyy should be 0, as the using the heap is not recommended).
Startup Code
============
The startup code for the TM4C123GH6PM MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\efm32pg1b\arm\startup_efm32pg1b.s
The file startup_efm32pg1b.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,23 +0,0 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
;
; Modified by Quantum Leaps:
; added STACK as the first section in RW_STACK
; *************************************************************
LR_IROM1 0x00000000 0x00020000 { ; load region size_region
ER_IROM1 0x00000000 0x00020000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_STACK 0x20000000 { ; <== Quantum Leaps
* (STACK, +First)
}
RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048!
.ANY (+RW +ZI)
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,555 +0,0 @@
//============================================================================
// Product: DPP example, EFM32-SLSTK3401A board, QV kernel
// Last updated for version 7.3.2
// Last updated on 2023-12-13
//
// Q u a n t u m L e a P s
// ------------------------
// Modern Embedded Software
//
// Copyright (C) 2005 Quantum Leaps, LLC. <state-machine.com>
//
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
//
// This software is dual-licensed under the terms of the open source GNU
// General Public License version 3 (or any later version), or alternatively,
// under the terms of one of the closed source Quantum Leaps commercial
// licenses.
//
// The terms of the open source GNU General Public License version 3
// can be found at: <www.gnu.org/licenses/gpl-3.0>
//
// The terms of the closed source Quantum Leaps commercial licenses
// can be found at: <www.state-machine.com/licensing>
//
// Redistributions in source code must retain this top-level comment block.
// Plagiarizing this software to sidestep the license obligations is illegal.
//
// Contact information:
// <www.state-machine.com/licensing>
// <info@state-machine.com>
//============================================================================
#include "qpcpp.hpp" // QP/C++ real-time embedded framework
#include "dpp.hpp" // DPP Application interface
#include "bsp.hpp" // Board Support Package
#include "em_device.h" // the device specific header (SiLabs)
#include "em_cmu.h" // Clock Management Unit (SiLabs)
#include "em_gpio.h" // GPIO (SiLabs)
#include "em_usart.h" // USART (SiLabs)
// add other drivers if necessary...
//============================================================================
namespace { // unnamed namespace for local stuff with internal linkage
Q_DEFINE_THIS_FILE
// Local-scope objects -------------------------------------------------------
constexpr GPIO_Port_TypeDef LED_PORT {gpioPortF};
constexpr std::uint32_t LED0_PIN {4U};
constexpr std::uint32_t LED1_PIN {5U};
constexpr GPIO_Port_TypeDef PB_PORT {gpioPortF};
constexpr std::uint32_t PB0_PIN {6U};
constexpr std::uint32_t PB1_PIN {7U};
static std::uint32_t l_rndSeed;
#ifdef Q_SPY
// QSpy source IDs
QP::QSpyId const l_SysTick_Handler = { 0U };
QP::QSpyId const l_GPIO_EVEN_IRQHandler = { 0U };
static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL));
static QP::QSTimeCtr QS_tickTime_;
static QP::QSTimeCtr QS_tickPeriod_;
enum AppRecords { // application-specific trace records
PHILO_STAT = QP::QS_USER,
PAUSED_STAT,
CONTEXT_SW,
};
#endif
} // unnamed namespace
//============================================================================
// Error handler and ISRs...
extern "C" {
Q_NORETURN Q_onError(char const * const module, int_t const id) {
// NOTE: this implementation of the error handler is intended only
// for debugging and MUST be changed for deployment of the application
// (assuming that you ship your production code with assertions enabled).
Q_UNUSED_PAR(module);
Q_UNUSED_PAR(id);
QS_ASSERTION(module, id, 10000U);
#ifndef NDEBUG
// light up both LEDs
GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN));
// for debugging, hang on in an endless loop...
for (;;) {
}
#else
NVIC_SystemReset();
for (;;) { // explicitly "no-return"
}
#endif
}
//............................................................................
void assert_failed(char const * const module, int_t const id); // prototype
void assert_failed(char const * const module, int_t const id) {
Q_onError(module, id);
}
// ISRs used in the application ==============================================
void SysTick_Handler(void); // prototype
void SysTick_Handler(void) {
QP::QTimeEvt::TICK_X(0U, &l_SysTick_Handler); // time events at rate 0
// Perform the debouncing of buttons. The algorithm for debouncing
// adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
// and Michael Barr, page 71.
static struct {
std::uint32_t depressed;
std::uint32_t previous;
} buttons = { 0U, 0U };
std::uint32_t current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1
std::uint32_t tmp = buttons.depressed; // save the depressed buttons
buttons.depressed |= (buttons.previous & current); // set depressed
buttons.depressed &= (buttons.previous | current); // clear released
buttons.previous = current; // update the history
tmp ^= buttons.depressed; // changed debounced depressed
current = buttons.depressed;
if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed?
if ((current & (1U << PB0_PIN)) != 0U) { // is PB0 depressed?
static QP::QEvt const pauseEvt(APP::PAUSE_SIG);
QP::QActive::PUBLISH(&pauseEvt, &l_SysTick_Handler);
}
else { // the button is released
static QP::QEvt const serveEvt(APP::SERVE_SIG);
QP::QActive::PUBLISH(&serveEvt, &l_SysTick_Handler);
}
}
#ifdef Q_SPY
tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG
QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover
#endif
QV_ARM_ERRATUM_838869();
}
//............................................................................
// interrupt handler for testing preemptions
void GPIO_EVEN_IRQHandler(void); // prototype
void GPIO_EVEN_IRQHandler(void) {
static QP::QEvt const testEvt(APP::TEST_SIG);
APP::AO_Table->POST(&testEvt, &l_GPIO_EVEN_IRQHandler);
QV_ARM_ERRATUM_838869();
}
//............................................................................
#ifdef Q_SPY
// ISR for receiving bytes from the QSPY Back-End
// NOTE: This ISR is "QF-unaware" meaning that it does not interact with
// the QF/QV and is not disabled. Such ISRs cannot post or publish events.
void USART0_RX_IRQHandler(void); // prototype
void USART0_RX_IRQHandler(void) {
// while RX FIFO NOT empty
while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0U) {
std::uint8_t b = static_cast<uint8_t>(l_USART0->RXDATA);
QP::QS::rxPut(b);
}
QV_ARM_ERRATUM_838869();
}
#endif // Q_SPY
//............................................................................
#ifdef QF_ON_CONTEXT_SW
// NOTE: the context-switch callback is called with interrupts DISABLED
void QF_onContextSw(QP::QActive *prev, QP::QActive *next) {
QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section!
QS_OBJ(prev);
QS_OBJ(next);
QS_END_INCRIT()
}
#endif // QF_ON_CONTEXT_SW
} // extern "C"
//============================================================================
namespace BSP {
void init() {
// Configure the MPU to prevent NULL-pointer dereferencing ...
MPU->RBAR = 0x0U // base address (NULL)
| MPU_RBAR_VALID_Msk // valid region
| (MPU_RBAR_REGION_Msk & 7U); // region #7
MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region
| (0x0U << MPU_RASR_AP_Pos) // no-access region
| MPU_RASR_ENABLE_Msk; // region enable
MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region
| MPU_CTRL_ENABLE_Msk; // enable the MPU
__ISB();
__DSB();
// enable the MemManage_Handler for MPU exception
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
// NOTE: SystemInit() has been already called from the startup code
// but SystemCoreClock needs to be updated
SystemCoreClockUpdate();
// NOTE: The VFP (hardware Floating Point) unit is configured by QV
// enable clock for to the peripherals used by this application...
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
// configure the LEDs
GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0);
GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0);
GPIO_PinOutClear(LED_PORT, LED0_PIN);
GPIO_PinOutClear(LED_PORT, LED1_PIN);
// configure the Buttons
GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1);
GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1);
BSP::randomSeed(1234U);
// initialize the QS software tracing...
if (!QS_INIT(nullptr)) {
Q_ERROR();
}
// dictionaries...
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler);
QS_USR_DICTIONARY(PHILO_STAT);
QS_USR_DICTIONARY(PAUSED_STAT);
QS_USR_DICTIONARY(CONTEXT_SW);
QS_ONLY(APP::produce_sig_dict());
// setup the QS filters...
QS_GLB_FILTER(QP::QS_ALL_RECORDS); // all records
QS_GLB_FILTER(-QP::QS_QF_TICK); // exclude the clock tick
QS_LOC_FILTER(-(APP::N_PHILO + 3U)); // exclude prio. of AO_Ticker0
}
//............................................................................
void start() {
// initialize event pools
static QF_MPOOL_EL(APP::TableEvt) smlPoolSto[2*APP::N_PHILO];
QP::QF::poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// initialize publish-subscribe
static QP::QSubscrList subscrSto[APP::MAX_PUB_SIG];
QP::QActive::psInit(subscrSto, Q_DIM(subscrSto));
// start AOs/threads...
static QP::QEvt const *philoQueueSto[APP::N_PHILO][APP::N_PHILO];
for (std::uint8_t n = 0U; n < APP::N_PHILO; ++n) {
APP::AO_Philo[n]->start(
n + 3U, // QF-prio/pthre. see NOTE1
philoQueueSto[n], // event queue storage
Q_DIM(philoQueueSto[n]), // queue length [events]
nullptr, 0U); // no stack storage
}
static QP::QEvt const *tableQueueSto[APP::N_PHILO];
APP::AO_Table->start(
APP::N_PHILO + 7U, // QP prio. of the AO
tableQueueSto, // event queue storage
Q_DIM(tableQueueSto), // queue length [events]
nullptr, 0U); // no stack storage
}
//............................................................................
void displayPhilStat(std::uint8_t n, char const *stat) {
Q_UNUSED_PAR(n);
if (stat[0] == 'e') {
GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN);
}
else {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN);
}
// app-specific trace record...
QS_BEGIN_ID(PHILO_STAT, APP::AO_Table->getPrio())
QS_U8(1, n); // Philosopher number
QS_STR(stat); // Philosopher status
QS_END()
}
//............................................................................
void displayPaused(std::uint8_t const paused) {
if (paused != 0U) {
GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN);
}
else {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN);
}
// application-specific trace record
QS_BEGIN_ID(PAUSED_STAT, APP::AO_Table->getPrio())
QS_U8(1, paused); // Paused status
QS_END()
}
//............................................................................
void randomSeed(uint32_t const seed) {
l_rndSeed = seed;
}
//............................................................................
std::uint32_t random() { // a very cheap pseudo-random-number generator
// Some floating point code is to exercise the VFP...
float volatile x = 3.1415926F;
x = x + 2.7182818F;
// NOTE: no need to protect shared 'l_rndSeed' in the QV kernel
// "Super-Duper" Linear Congruential Generator (LCG)
// LCG(2^32, 3*7*11*13*23, 0, seed)
std::uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U);
l_rndSeed = rnd; // set for the next time
return (rnd >> 8U);
}
//............................................................................
void ledOn() {
GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN);
}
//............................................................................
void ledOff() {
GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN);
}
//............................................................................
void terminate(int16_t result) {
Q_UNUSED_PAR(result);
}
} // namespace BSP
//============================================================================
// namespace QP
namespace QP {
// QF callbacks...
void QF::onStartup() {
// set up the SysTick timer to fire at BSP::TICKS_PER_SEC rate
SysTick_Config(SystemCoreClock / BSP::TICKS_PER_SEC);
// assign all priority bits for preemption-prio. and none to sub-prio.
NVIC_SetPriorityGrouping(0U);
// set priorities of ALL ISRs used in the system, see NOTE1
NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt
NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U);
NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U);
// ...
// enable IRQs...
NVIC_EnableIRQ(GPIO_EVEN_IRQn);
#ifdef Q_SPY
NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX
#endif
}
//............................................................................
void QF::onCleanup() {
}
//............................................................................
void QV::onIdle() { // CAUTION: called with interrupts DISABLED, see NOTE0
// toggle the User LED on and then off, see NOTE3
// GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN);
// GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN);
#ifdef Q_SPY
// intgerrupts still disabled
QS::rxParse(); // parse all the received bytes
QF_INT_ENABLE();
if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty?
QF_INT_DISABLE();
std::uint16_t b = QS::getByte();
QF_INT_ENABLE();
if (b != QS_EOD) { // not End-Of-Data?
l_USART0->TXDATA = b; // put into the DR register
}
}
#elif defined NDEBUG
// Put the CPU and peripherals to the low-power mode.
// you might need to customize the clock management for your application,
// see the datasheet for your particular Cortex-M MCU.
//
QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts
#else
QF_INT_ENABLE(); // just enable interrupts
#endif
}
//============================================================================
// QS callbacks...
#ifdef Q_SPY
namespace QS {
//............................................................................
bool onStartup(void const *arg) {
Q_UNUSED_PAR(arg);
static std::uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel
initBuf(qsTxBuf, sizeof(qsTxBuf));
static std::uint8_t qsRxBuf[100]; // buffer for QS-RX channel
rxInitBuf(qsRxBuf, sizeof(qsRxBuf));
static USART_InitAsync_TypeDef init = {
usartEnable, // Enable RX/TX when init completed
0, // Use current clock for configuring baudrate
115200, // 115200 bits/s
usartOVS16, // 16x oversampling
usartDatabits8, // 8 databits
usartNoParity, // No parity
usartStopbits1, // 1 stopbit
0, // Do not disable majority vote
0, // Not USART PRS input mode
usartPrsRxCh0, // PRS channel 0
0, // Auto CS functionality enable/disable switch
0, // Auto CS Hold cycles
0 // Auto CS Setup cycles
};
// Enable peripheral clocks
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
// To avoid false start, configure output as high
GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin
GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin
// Enable DK RS232/UART switch
GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1);
CMU_ClockEnable(cmuClock_USART0, true);
// configure the UART for the desired baud rate, 8-N-1 operation
init.enable = usartDisable;
USART_InitAsync(l_USART0, &init);
// enable pins at correct UART/USART location.
l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 &
~(_USART_ROUTELOC0_TXLOC_MASK
| _USART_ROUTELOC0_RXLOC_MASK));
// Clear previous RX interrupts
USART_IntClear(l_USART0, USART_IF_RXDATAV);
NVIC_ClearPendingIRQ(USART0_RX_IRQn);
// Enable RX interrupts
USART_IntEnable(l_USART0, USART_IF_RXDATAV);
// NOTE: do not enable the UART0 interrupt in the NVIC yet.
// Wait till QF_onStartup()
// Finally enable the UART
USART_Enable(l_USART0, usartEnable);
QS_tickPeriod_ = SystemCoreClock / BSP::TICKS_PER_SEC;
QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero
return true; // return success
}
//............................................................................
void onCleanup() {
}
//............................................................................
QSTimeCtr onGetTime() { // NOTE: invoked with interrupts DISABLED
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set?
return QS_tickTime_ - (QSTimeCtr)SysTick->VAL;
}
else { // the rollover occurred, but the SysTick_ISR did not run yet
return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL;
}
}
//............................................................................
// NOTE:
// No critical section in QS::onFlush() to avoid nesting of critical sections
// in case QS::onFlush() is called from Q_onError().
void onFlush() {
for (;;) {
std::uint16_t b = getByte();
if (b != QS_EOD) {
while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) {
}
l_USART0->TXDATA = b;
}
else {
break;
}
}
}
//............................................................................
void onReset() {
NVIC_SystemReset();
}
//............................................................................
void onCommand(std::uint8_t cmdId, std::uint32_t param1,
std::uint32_t param2, std::uint32_t param3)
{
Q_UNUSED_PAR(cmdId);
Q_UNUSED_PAR(param1);
Q_UNUSED_PAR(param2);
Q_UNUSED_PAR(param3);
}
} // namespace QS
#endif // Q_SPY
//----------------------------------------------------------------------------
} // namespace QP
//============================================================================
// NOTE0:
// The QV:onIdle() callback is called with interrupts disabled, because the
// determination of the idle condition might change by any interrupt posting
// an event. QV::onIdle() must internally enable interrupts, ideally
// atomically with putting the CPU to the power-saving mode.
//
// NOTE1:
// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest
// ISR priority that is disabled by the QF framework. The value is suitable
// for the NVIC_SetPriority() CMSIS function.
//
// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e.,
// with the numerical values of priorities equal or higher than
// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF/QK services. These ISRs
// are "QF-aware".
//
// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority
// level (i.e., with the numerical values of priorities less than
// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel.
// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they
// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism
// by which a "QF-unaware" ISR can communicate with the QF framework is by
// triggering a "QF-aware" ISR, which can post/publish events.
//
// NOTE2:
// The User LED is used to visualize the idle loop activity. The brightness
// of the LED is proportional to the frequency of the idle loop.
// Please note that the LED is toggled with interrupts locked, so no interrupt
// execution time contributes to the brightness of the User LED.

View File

@ -1,316 +0,0 @@
##############################################################################
# Product: Makefile for QP/C++ on EMF32-SLSTK3401A, QV kernel, GNU-ARM
# Last Updated for Version: 7.2.0
# Date of the Last Update: 2022-12-14
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005 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 3 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# https://github.com/QuantumLeaps/qtools/releases
#
#-----------------------------------------------------------------------------
# project name
#
PROJECT := dpp-qv
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environment var.)
ifeq ($(QPCPP),)
QPCPP := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/arm-cm/qv/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPCPP)/src/qf \
$(QPCPP)/src/qv \
$(QPCPP)/src/qs \
$(QP_PORT_DIR) \
$(QPCPP)/3rd_party/efm32pg1b \
$(QPCPP)/3rd_party/efm32pg1b/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR) \
-I$(QPCPP)/3rd_party/CMSIS/Include \
-I$(QPCPP)/3rd_party/efm32pg1b
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
startup_efm32pg1b.c \
system_efm32pg1b.c \
em_cmu.c \
em_emu.c \
em_gpio.c \
em_usart.c
# C++ source files
CPP_SRCS := \
bsp.cpp \
main.cpp \
philo.cpp \
table.cpp
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.cpp \
qep_msm.cpp \
qf_act.cpp \
qf_actq.cpp \
qf_defer.cpp \
qf_dyn.cpp \
qf_mem.cpp \
qf_ps.cpp \
qf_qact.cpp \
qf_qeq.cpp \
qf_qmact.cpp \
qf_time.cpp \
qv.cpp \
qv_port.cpp
QP_ASMS := \
QS_SRCS := \
qs.cpp \
qs_rx.cpp \
qs_fp.cpp
LIB_DIRS :=
LIBS :=
# defines
DEFINES := -DEFM32PG1B200F256GM48=1 \
-DQF_ON_CONTEXT_SW
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m4
ARM_FPU := -mfpu=vfp
FLOAT_ABI := -mfloat-abi=softfp
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-g++
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically, you should not need to change anything below this line
# basic utilities (included in Qtools for Windows), see:
# http://sourceforge.net/projects/qpc/files/Qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M
#
# combine all the sources...
CPP_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
CPP_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CPP) $(CPPFLAGS) $(QPCPP)/src/qs/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -1,71 +0,0 @@
About this Example
==================
This example can be built from the command prompt with the provided
Makefile. The example can also be imported as a Makefile-based
project into Eclipse-based IDEs.
The Makefile
============
The provided Makefile should be easy to adapt for your own projects.
It contains three build configurations: Debug (default), Release, and
Spy.
Also, the Makefile has been specifically designed to work as an external
Makefile with the Eclipse CDT.
The various build configurations are built as follows:
make
make CONF=rel
make CONF=spy
make clean
make CONF=rel clean
make CONF=spy clean
***
NOTE:
The installation folder of the GNU-ARM toolset on YOUR machine needs
to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM.
As described in the comment for this symbol, the GNU-ARM toolset is taken
from: http://gnutoolchains.com/arm-eabi
It is highly recommended to use the same GNU-ARM distribution, especially
for ARM Cortex-M4F projects, due to the support for the hardware FPU
(float-abi=hard).
***
Adjusting Stack and Heap Sizes
==============================
The stack and heap sizes are determined in this project by the GCC linker
script (.ld file), which provides a template of the recommended GCC linker
script for QP applications.
Startup Code
============
The startup code for the EFM32PG1B200F256GM48 MCU used in this project
is located in the "3rd_party" folder in the following location:
qpc\3rd_party\efm32pg1b\gnu\startup_efm32pg1b.c
The file startup_efm32pg1b.c provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

View File

@ -1,139 +0,0 @@
/*****************************************************************************
* Product: Linker script for EFM32-SLSTK3401A, GNU-ARM linker
* Last Updated for Version: 5.9.8
* Date of the Last Update: 2017-09-13
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 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 3 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:
* http://www.state-machine.com
* mailto:info@state-machine.com
*****************************************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler) /* entry Point */
MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0;
SECTIONS {
.isr_vector : { /* the vector table goes FIRST into ROM */
KEEP(*(.isr_vector)) /* vector table */
. = ALIGN(4);
} >ROM
.text : { /* code and constants */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >ROM
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
.init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
.fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
_etext = .; /* global symbols at end of code */
.stack : {
__stack_start__ = .;
. = . + STACK_SIZE;
. = ALIGN(4);
__stack_end__ = .;
} >RAM
.data : AT (_etext) {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
} >RAM
.bss : {
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
} >RAM
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM
__exidx_end = .;
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
.heap : {
__heap_start__ = .;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = .;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}

View File

@ -1,49 +0,0 @@
::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board
::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html
::
setlocal
@echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin
::----------------------------------------------------------------------------
:: NOTE: Adjust the following symbol to the location of the
:: JLink utility on your machine
::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat
@goto end
)
if ["%~1"]==[""] (
@echo The binary file missing
@goto end
)
if not exist %~s1 (
@echo The binary file '%1' does not exist
@goto end
)
:: generate the Jlink command file depending on the first parameter %1
@echo si 1 >flash.jlink
@echo speed 4000 >>flash.jlink
@echo r >>flash.jlink
@echo h >>flash.jlink
@echo loadbin %1, 0 >>flash.jlink
@echo exit >>flash.jlink
@echo on
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
@echo off
@del flash.jlink
:end
endlocal

View File

@ -1,53 +0,0 @@
About this Example
==================
This example demonstrates how to use the IAR EWARM IDE to build
a QP application.
IAR Project File
----------------
The IAR EWARM project file provided with this example uses relative paths
to the QP/C framework location (includes, port, and libraries. These
relative paths must be modified when the project is moved to different
relative location.
Stack Size and Heap Size
------------------------
In this project, the size of the C stack and heap are determined in
the linker script blinky-qk.icf (see the next section).
Linker Script
-------------
The IAR linker script provides a template of the recommended linker script
for QP applications. This file needs to be customized to set the
application-specific sizes of the Stack and Heap. This file can be edited
from the IAR EWARM IDE via the Project Options/Linker settings.
Startup Code
============
The startup code for the EFM32PG1B200F256GM48 MCU used in this project is
located in the "3rd_party" folder in the following location:
3rd_party\efm32pg1b\iar\startup_efm32pg1b.s
The file startup_efm32pg1b.s provides a template of the recommended
startup for QP applications and should be easily customizable for other
ARM Cortex-M microcontrollers.
The startup file typically does not need to be modified or adapted for
applications. It provides only weak definitions of all exception and
interrupt handlers, as well as the assert_failed() function.
The weak function assert_failed() defined in this file might be re-defined
in the application to customize it for the application-specific error-
handling policy.
***
NOTE: The function assert_failed() typically should NOT use the stack,
because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and
should NOT return.
***

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\dpp-qv.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -1,29 +0,0 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP };

View File

@ -1,103 +0,0 @@
# This is an example of QView customization for a specific application
# (DPP in this case). This example animates the Phil images on the
# QView canvas. Additionally, there is a button in the middle of the screen,
# which, when clicked once pauses the DPP ("forks" are not being served).
# A second click on the button, "un-pauses" the DPP ("forks" are served
# to all hungry Philosophers).
#
# This version of the DPP customization uses the application-specific
# trace record QS_USER_00 (PHILO_STAT) produced when the status of
# a Philo changes.
class DPP:
def __init__(self):
# add commands to the Custom menu...
QView.custom_menu.add_command(label="Custom command",
command=self.cust_command)
# configure the custom QView.canvas...
QView.show_canvas() # make the canvas visible
QView.canvas.configure(width=400, height=260)
# tuple of activity images (correspond to self._philo_state)
self._act_img = (
PhotoImage(file=HOME_DIR + "/img/thinking.gif"),
PhotoImage(file=HOME_DIR + "/img/hungry.gif"),
PhotoImage(file=HOME_DIR + "/img/eating.gif"),
)
# tuple of philo canvas images (correspond to self._philo_obj)
self._philo_img = (\
QView.canvas.create_image(190, 57, image=self._act_img[0]),
QView.canvas.create_image(273, 100, image=self._act_img[0]),
QView.canvas.create_image(237, 185, image=self._act_img[0]),
QView.canvas.create_image(146, 185, image=self._act_img[0]),
QView.canvas.create_image(107, 100, image=self._act_img[0])
)
# button images for UP and DOWN
self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif")
self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif")
# images of a button for pause/serve
self.btn = QView.canvas.create_image(200, 120, image=self.img_UP)
QView.canvas.tag_bind(self.btn, "<ButtonPress-1>", self.cust_pause)
# request target reset on startup...
# NOTE: Normally, for an embedded application you would like
# to start with resetting the Target, to start clean with
# Qs dictionaries, etc.
reset_target()
# on_reset() callback
def on_reset(self):
# clear the lists
self._philo_obj = [0, 0, 0, 0, 0]
self._philo_state = [0, 0, 0]
# on_run() callback
def on_run(self):
glb_filter("QS_USER_00")
# NOTE: the names of objects for current_obj() must match
# the QS Object Dictionaries produced by the application.
current_obj(OBJ_AO, "Table::inst")
# turn lists into tuples for better performance
self._philo_obj = tuple(self._philo_obj)
self._philo_state = tuple(self._philo_state)
# example of a custom command
def cust_command(self):
command(1, 12345)
# example of a custom interaction with a canvas object (pause/serve)
def cust_pause(self, event):
if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP):
QView.canvas.itemconfig(self.btn, image=self.img_UP)
post("SERVE_SIG")
QView.print_text("Table SERVING")
else:
QView.canvas.itemconfig(self.btn, image=self.img_DWN)
post("PAUSE_SIG")
QView.print_text("Table PAUSED")
# Intercept the QS_USER_00 application-specific trace record.
# This record has the following structure (see bsp.c:displayPhilStat()):
# Seq-Num, Record-ID, Timestamp, format-byte, Philo-num,
# format-byte, Zero-terminated string (status)
def QS_USER_00(self, packet):
# unpack: Timestamp->data[0], Philo-num->data[1], status->data[3]
data = qunpack("xxTxBxZ", packet)
i = data[1]
j = ("t", "h", "e").index(data[2][0]) # the first letter
# animate the given philo image according to its activity
QView.canvas.itemconfig(self._philo_img[i], image=self._act_img[j])
# print a message to the text view
QView.print_text("%010d Philo %1d is %s"%(data[0], i, data[2]))
#=============================================================================
QView.customize(DPP()) # set the QView customization

Some files were not shown because too many files have changed in this diff Show More