mirror of
https://github.com/QuantumLeaps/qpc.git
synced 2025-01-28 07:03:10 +08:00
5.9.2
This commit is contained in:
parent
f8459420f5
commit
b2d669391a
198
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu.h
vendored
Normal file
198
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu.h
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
/*============================================================================
|
||||
* Modified for GNU-ARM from the original port to IAR-ARM as follows:
|
||||
* - renamed OS_CPU_PendSVHandler to CMSIS-compatible name PendSV_Handler
|
||||
* - renamed OS_CPU_SysTickHandler to CMSIS-compatible name SysTick_Handler
|
||||
* - renamed __ARMVFP__ to __FPU_PRESENT
|
||||
*
|
||||
* Quantum Leaps, LLC. www.state-machine.com
|
||||
* 2015-03-23
|
||||
*===========================================================================*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M4 Port
|
||||
*
|
||||
* File : OS_CPU.H
|
||||
* Version : V2.92.09
|
||||
* By : JJL
|
||||
* JBL
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE short-term evaluation, for educational use or
|
||||
* for peaceful research. If you plan or intend to use uC/OS-II in a commercial application/
|
||||
* product then, you need to contact Micrium to properly license uC/OS-II for its use in your
|
||||
* application/product. We provide ALL the source code for your convenience and to help you
|
||||
* experience uC/OS-II. The fact that the source is provided does NOT mean that you can use
|
||||
* it commercially without paying a licensing fee.
|
||||
*
|
||||
* Knowledge of the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the embedded community with the finest software available.
|
||||
* Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
|
||||
*
|
||||
* For : ARMv7 Cortex-M4
|
||||
* Mode : Thumb-2 ISA
|
||||
* Toolchain : IAR EWARM
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
#ifndef OS_CPU_EXCEPT_STK_SIZE
|
||||
#define OS_CPU_EXCEPT_STK_SIZE 128u /* Default exception stack size is 128 OS_STK entries */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __FPU_PRESENT
|
||||
#define OS_CPU_ARM_FP_EN 1u
|
||||
#else
|
||||
#define OS_CPU_ARM_FP_EN 0u
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS TICK INTERRUPT PRIORITY CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
|
||||
* should be configured as the highest priority interrupt but won't adversely affect system
|
||||
* operations.
|
||||
*
|
||||
* (2) For systems that need one or more high, real-time interrupts; these should be configured
|
||||
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
|
||||
*
|
||||
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
|
||||
* occasionally delay tick interrupts, then the real-time interrupts can successfully
|
||||
* handle their intermittent/periodic events with the system not losing tick interrupts
|
||||
* but only increasing the jitter.
|
||||
*
|
||||
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
|
||||
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
|
||||
* to handle all its interrupts/tasks. The system time reference gets compromised as a
|
||||
* result of losing tick interrupts.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_CFG_SYSTICK_PRIO 0u
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DATA TYPES
|
||||
* (Compiler Specific)
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
typedef unsigned char BOOLEAN;
|
||||
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
|
||||
typedef signed char INT8S; /* Signed 8 bit quantity */
|
||||
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
|
||||
typedef signed short INT16S; /* Signed 16 bit quantity */
|
||||
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
|
||||
typedef signed int INT32S; /* Signed 32 bit quantity */
|
||||
typedef float FP32; /* Single precision floating point */
|
||||
typedef double FP64; /* Double precision floating point */
|
||||
|
||||
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */
|
||||
typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* Cortex-M4
|
||||
* Critical Section Management
|
||||
*
|
||||
* Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts
|
||||
* will be enabled even if they were disabled before entering the critical section.
|
||||
* NOT IMPLEMENTED
|
||||
*
|
||||
* Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if
|
||||
* interrupts were disabled before entering the critical section, they will be disabled when
|
||||
* leaving the critical section.
|
||||
* NOT IMPLEMENTED
|
||||
*
|
||||
* Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
|
||||
* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
|
||||
* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
|
||||
* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
|
||||
* into the CPU's status register.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CRITICAL_METHOD 3u
|
||||
|
||||
#if OS_CRITICAL_METHOD == 3u
|
||||
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
|
||||
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* Cortex-M4 Miscellaneous
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_STK_GROWTH 1u /* Stack grows from HIGH to LOW memory on ARM */
|
||||
|
||||
#define OS_TASK_SW() OSCtxSw()
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_CPU_EXT OS_STK OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE];
|
||||
OS_CPU_EXT OS_STK *OS_CPU_ExceptStkBase;
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CRITICAL_METHOD == 3u /* See OS_CPU_A.ASM */
|
||||
OS_CPU_SR OS_CPU_SR_Save (void);
|
||||
void OS_CPU_SR_Restore (OS_CPU_SR cpu_sr);
|
||||
#endif
|
||||
|
||||
void OSCtxSw (void);
|
||||
void OSIntCtxSw (void);
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
void PendSV_Handler (void); /* QL was: void OS_CPU_PendSVHandler (void); */
|
||||
|
||||
/* See OS_CPU_C.C */
|
||||
void SysTick_Handler (void); /* QL was: void OS_CPU_SysTickHandler (void); */
|
||||
void OS_CPU_SysTickInit (INT32U cnts);
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
void OS_CPU_FP_Reg_Push (OS_STK *stkPtr);
|
||||
void OS_CPU_FP_Reg_Pop (OS_STK *stkPtr);
|
||||
#endif
|
||||
|
||||
#endif
|
321
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s
vendored
Normal file
321
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s
vendored
Normal file
@ -0,0 +1,321 @@
|
||||
/*===========================================================================
|
||||
* Modified from the original as follows:
|
||||
* - changed to the GNU-AS syntax
|
||||
* - renamed OS_CPU_PendSVHandler to CMSIS-compatible name PendSV_Handler
|
||||
* - changed the conditional compilation for the FPU to the new syntax
|
||||
* #ifdef __ARMVFP__/#endif
|
||||
*
|
||||
* Quantum Leaps, LLC. https://state-machine.com
|
||||
* 2017-06-05
|
||||
*============================================================================
|
||||
*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2013; Micrium, Inc.* Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M4 Port
|
||||
*
|
||||
* File : OS_CPU_A.ASM
|
||||
* Version : V2.92.09
|
||||
* By : JJL
|
||||
* BAN
|
||||
* JBL
|
||||
*
|
||||
* For : ARMv7 Cortex-M4
|
||||
* Mode : Thumb-2 ISA
|
||||
* Toolchain : IAR EWARM
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/********************************************************************************************************
|
||||
* CODE GENERATION DIRECTIVES
|
||||
********************************************************************************************************/
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
|
||||
/********************************************************************************************************
|
||||
* EQUATES
|
||||
********************************************************************************************************/
|
||||
|
||||
.equ NVIC_INT_CTRL,0xE000ED04 /* Interrupt control state register. */
|
||||
.equ NVIC_SYSPRI14,0xE000ED22 /* System priority register (priority 14) */
|
||||
.equ NVIC_PENDSV_PRI,0xFF /* PendSV priority value (lowest). */
|
||||
.equ NVIC_PENDSVSET,0x10000000 /* Value to trigger PendSV exception. */
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* FLOATING POINT REGISTERS PUSH
|
||||
* void OS_CPU_FP_Reg_Push (OS_STK *stkPtr)
|
||||
*
|
||||
* Note(s) : 1) This function saves S0-S31, and FPSCR registers of the Floating Point Unit.
|
||||
*
|
||||
* 2) Pseudo-code is:
|
||||
* a) Get FPSCR register value;
|
||||
* b) Push value on process stack;
|
||||
* c) Push remaining regs S0-S31 on process stack;
|
||||
* d) Update OSTCBCur->OSTCBStkPtr;
|
||||
********************************************************************************************************/
|
||||
|
||||
.ifdef __FPU_PRESENT /* QL was: IF {FPU} != "SoftVFP" */
|
||||
.section .text.OS_CPU_FP_Reg_Push
|
||||
.global OS_CPU_FP_Reg_Push
|
||||
.type OS_CPU_FP_Reg_Push, %function
|
||||
OS_CPU_FP_Reg_Push:
|
||||
MRS R1, PSP /* PSP is process stack pointer */
|
||||
CBZ R1, OS_CPU_FP_nosave /* Skip FP register save the first time */
|
||||
|
||||
VMRS R1, FPSCR
|
||||
STR R1, [R0, #-4]!
|
||||
VSTMDB R0!, {S0-S31}
|
||||
LDR R1, =OSTCBCur
|
||||
LDR R2, [R1]
|
||||
STR R0, [R2]
|
||||
OS_CPU_FP_nosave:
|
||||
BX LR
|
||||
.size OS_CPU_FP_Reg_Push, . - OS_CPU_FP_Reg_Push
|
||||
.endif /* QL was: ENDIF */
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* FLOATING POINT REGISTERS POP
|
||||
* void OS_CPU_FP_Reg_Pop (OS_STK *stkPtr)
|
||||
*
|
||||
* Note(s) : 1) This function restores S0-S31, and FPSCR registers of the Floating Point Unit.
|
||||
*
|
||||
* 2) Pseudo-code is:
|
||||
* a) Restore regs S0-S31 of new process stack;
|
||||
* b) Restore FPSCR reg value
|
||||
* c) Update OSTCBHighRdy->OSTCBStkPtr pointer of new proces stack;
|
||||
********************************************************************************************************/
|
||||
|
||||
.ifdef __FPU_PRESENT /* QL was: IF {FPU} != "SoftVFP" */
|
||||
.section .text.OS_CPU_FP_Reg_Pop
|
||||
.global OS_CPU_FP_Reg_Pop
|
||||
.type OS_CPU_FP_Reg_Pop, %function
|
||||
OS_CPU_FP_Reg_Pop:
|
||||
VLDMIA R0!, {S0-S31}
|
||||
LDMIA R0!, {R1}
|
||||
VMSR FPSCR, R1
|
||||
LDR R1, =OSTCBHighRdy
|
||||
LDR R2, [R1]
|
||||
STR R0, [R2]
|
||||
BX LR
|
||||
.size OS_CPU_FP_Reg_Pop, . - OS_CPU_FP_Reg_Pop
|
||||
.endif /* QL was: ENDIF */
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* CRITICAL SECTION METHOD 3 FUNCTIONS
|
||||
*
|
||||
* Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
|
||||
* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
|
||||
* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
|
||||
* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
|
||||
* into the CPU's status register.
|
||||
*
|
||||
* Prototypes : OS_CPU_SR OS_CPU_SR_Save(void);
|
||||
* void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
|
||||
*
|
||||
*
|
||||
* Note(s) : 1) These functions are used in general like this:
|
||||
*
|
||||
* void Task (void *p_arg)
|
||||
* {
|
||||
* #if OS_CRITICAL_METHOD == 3 // Allocate storage for CPU status register
|
||||
* OS_CPU_SR cpu_sr;
|
||||
* #endif
|
||||
*
|
||||
* :
|
||||
* :
|
||||
* OS_ENTER_CRITICAL(); // cpu_sr = OS_CPU_SaveSR();
|
||||
* :
|
||||
* :
|
||||
* OS_EXIT_CRITICAL(); // OS_CPU_RestoreSR(cpu_sr);
|
||||
* :
|
||||
* :
|
||||
* }
|
||||
********************************************************************************************************/
|
||||
.section .text.OS_CPU_SR_Save
|
||||
.global OS_CPU_SR_Save
|
||||
.type OS_CPU_SR_Save, %function
|
||||
OS_CPU_SR_Save:
|
||||
MRS R0, PRIMASK /* Set prio int mask to mask all (except faults) */
|
||||
CPSID I
|
||||
BX LR
|
||||
.size OS_CPU_SR_Save, . - OS_CPU_SR_Save
|
||||
|
||||
.section .text.OS_CPU_SR_Restore
|
||||
.global OS_CPU_SR_Restore
|
||||
.type OS_CPU_SR_Restore, %function
|
||||
OS_CPU_SR_Restore:
|
||||
MSR PRIMASK, R0
|
||||
BX LR
|
||||
.size OS_CPU_SR_Restore, . - OS_CPU_SR_Restore
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* START MULTITASKING
|
||||
* void OSStartHighRdy(void)
|
||||
*
|
||||
* Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
|
||||
* the first task to start.
|
||||
*
|
||||
* 2) OSStartHighRdy() MUST:
|
||||
* a) Setup PendSV exception priority to lowest;
|
||||
* b) Set initial PSP to 0, to tell context switcher this is first run;
|
||||
* c) Set the main stack to OS_CPU_ExceptStkBase
|
||||
* d) Set OSRunning to TRUE;
|
||||
* e) Trigger PendSV exception;
|
||||
* f) Enable interrupts (tasks will run with interrupts enabled).
|
||||
********************************************************************************************************/
|
||||
|
||||
.section .text.OSStartHighRdy
|
||||
.global OSStartHighRdy
|
||||
.type OSStartHighRdy, %function
|
||||
OSStartHighRdy:
|
||||
LDR R0, =NVIC_SYSPRI14 /* Set the PendSV exception priority */
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
MOVS R0, #0 /* Set the PSP to 0 for initial context switch call */
|
||||
MSR PSP, R0
|
||||
|
||||
LDR R0, =OS_CPU_ExceptStkBase /* Initialize the MSP to the OS_CPU_ExceptStkBase */
|
||||
LDR R1, [R0]
|
||||
MSR MSP, R1
|
||||
|
||||
LDR R0, =OSRunning /* OSRunning = TRUE */
|
||||
MOVS R1, #1
|
||||
STRB R1, [R0]
|
||||
|
||||
LDR R0, =NVIC_INT_CTRL /* Trigger the PendSV exception (causes context switch) */
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
|
||||
CPSIE I /* Enable interrupts at processor level */
|
||||
|
||||
OSStartHang:
|
||||
B OSStartHang /* Should never get here */
|
||||
.size OSStartHighRdy, . - OSStartHighRdy
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
|
||||
*
|
||||
* Note(s) : 1) OSCtxSw() is called when OS wants to perform a task context switch. This function
|
||||
* triggers the PendSV exception which is where the real work is done.
|
||||
********************************************************************************************************/
|
||||
|
||||
.section .text.OSCtxSw
|
||||
.global OSCtxSw
|
||||
.type OSCtxSw, %function
|
||||
OSCtxSw:
|
||||
LDR R0, =NVIC_INT_CTRL /* Trigger the PendSV exception (causes context switch) */
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
.size OSCtxSw, . - OSCtxSw
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
|
||||
*
|
||||
* Note(s) : 1) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as
|
||||
* the result of an interrupt. This function simply triggers a PendSV exception which will
|
||||
* be handled when there are no more interrupts active and interrupts are enabled.
|
||||
********************************************************************************************************/
|
||||
|
||||
.section .text.OSIntCtxSw
|
||||
.global OSIntCtxSw
|
||||
.type OSIntCtxSw, %function
|
||||
OSIntCtxSw:
|
||||
LDR R0, =NVIC_INT_CTRL /* Trigger the PendSV exception (causes context switch) */
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
.size OSIntCtxSw, . - OSIntCtxSw
|
||||
|
||||
|
||||
/********************************************************************************************************
|
||||
* HANDLE PendSV EXCEPTION
|
||||
* void OS_CPU_PendSVHandler(void)
|
||||
*
|
||||
* Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
|
||||
* context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
|
||||
* processor context on any exception, and restores same on return from exception. So only
|
||||
* saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
|
||||
* this way means that context saving and restoring is identical whether it is initiated from
|
||||
* a thread or occurs due to an interrupt or exception.
|
||||
*
|
||||
* 2) Pseudo-code is:
|
||||
* a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
|
||||
* b) Save remaining regs r4-r11 on process stack;
|
||||
* c) Save the process SP in its TCB, OSTCBCur->OSTCBStkPtr = SP;
|
||||
* d) Call OSTaskSwHook();
|
||||
* e) Get current high priority, OSPrioCur = OSPrioHighRdy;
|
||||
* f) Get current ready thread TCB, OSTCBCur = OSTCBHighRdy;
|
||||
* g) Get new process SP from TCB, SP = OSTCBHighRdy->OSTCBStkPtr;
|
||||
* h) Restore R4-R11 from new process stack;
|
||||
* i) Perform exception return which will restore remaining context.
|
||||
*
|
||||
* 3) On entry into PendSV handler:
|
||||
* a) The following have been saved on the process stack (by processor):
|
||||
* xPSR, PC, LR, R12, R0-R3
|
||||
* b) Processor mode is switched to Handler mode (from Thread mode)
|
||||
* c) Stack is Main stack (switched from Process stack)
|
||||
* d) OSTCBCur points to the OS_TCB of the task to suspend
|
||||
* OSTCBHighRdy points to the OS_TCB of the task to resume
|
||||
*
|
||||
* 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
|
||||
* know that it will only be run when no other exception or interrupt is active, and
|
||||
* therefore safe to assume that context being switched out was using the process stack (PSP).
|
||||
********************************************************************************************************/
|
||||
|
||||
.section .text.PendSV_Handler
|
||||
.global PendSV_Handler
|
||||
.type PendSV_Handler, %function
|
||||
PendSV_Handler: /* QL was: OS_CPU_PendSVHandler */
|
||||
CPSID I /* Prevent interruption during context switch */
|
||||
MRS R0, PSP /* PSP is process stack pointer */
|
||||
CBZ R0, OS_CPU_PendSVHandler_nosave /* Skip register save the first time */
|
||||
|
||||
SUBS R0, R0, #0x20 /* Save remaining regs r4-11 on process stack */
|
||||
STM R0, {R4-R11}
|
||||
|
||||
LDR R1, =OSTCBCur /* OSTCBCur->OSTCBStkPtr = SP; */
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1] /* R0 is SP of process being switched out */
|
||||
|
||||
/* At this point, entire context of process has been saved */
|
||||
OS_CPU_PendSVHandler_nosave:
|
||||
PUSH {R14} /* Save LR exc_return value */
|
||||
LDR R0, =OSTaskSwHook /* OSTaskSwHook(); */
|
||||
BLX R0
|
||||
POP {R14}
|
||||
|
||||
LDR R0, =OSPrioCur /* OSPrioCur = OSPrioHighRdy; */
|
||||
LDR R1, =OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
LDR R0, =OSTCBCur /* OSTCBCur = OSTCBHighRdy; */
|
||||
LDR R1, =OSTCBHighRdy
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2] /* R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr; */
|
||||
LDM R0, {R4-R11} /* Restore r4-11 from new process stack */
|
||||
ADDS R0, R0, #0x20
|
||||
MSR PSP, R0 /* Load PSP with new process SP */
|
||||
ORR LR, LR, #0xF4 /* Ensure exception return uses process stack */
|
||||
CPSIE I
|
||||
BX LR /* Exception return will restore remaining context */
|
||||
.size PendSV_Handler, . - PendSV_Handler
|
||||
|
||||
.end
|
649
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_c.c
vendored
Normal file
649
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_c.c
vendored
Normal file
@ -0,0 +1,649 @@
|
||||
/*============================================================================
|
||||
* Modified from the original to interoperate with CMSIS standard as follows:
|
||||
* - renamed OS_CPU_SysTickHandler to CMSIS-compatible name SysTick_Handler
|
||||
* - added expected configuration of the Cortex-M4F FPU to OSInitHookEnd()
|
||||
* - removed dependency on "lib_def.h"
|
||||
* - added definition of CPU_STK typdef
|
||||
* - added definitions of DEF_DISABLED and DEF_ENABLED
|
||||
* - replaced the use of macros DEF_BIT_FIELD() and DEF_BIT_MASK()
|
||||
* with the simple code equivalents
|
||||
*
|
||||
* Quantum Leaps, LLC. www.state-machine.com
|
||||
* 2015-03-24
|
||||
*===========================================================================*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
*
|
||||
* (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* ARM Cortex-M4 Port
|
||||
*
|
||||
* File : OS_CPU_C.C
|
||||
* Version : V2.92.09
|
||||
* By : JJL
|
||||
* BAN
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE short-term evaluation, for educational use or
|
||||
* for peaceful research. If you plan or intend to use uC/OS-II in a commercial application/
|
||||
* product then, you need to contact Micrium to properly license uC/OS-II for its use in your
|
||||
* experience uC/OS-II. The fact that the source is provided does NOT mean that you can use
|
||||
* it commercially without paying a licensing fee.
|
||||
*
|
||||
* Knowledge of the source code may NOT be used to develop a similar product.
|
||||
*
|
||||
* Please help us continue to provide the embedded community with the finest software available.
|
||||
* Your honesty is greatly appreciated.
|
||||
*
|
||||
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
|
||||
*
|
||||
* For : ARMv7 Cortex-M4
|
||||
* Mode : Thumb-2 ISA
|
||||
* Toolchain : IAR EWARM
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define DEF_DISABLED 0u
|
||||
#define DEF_ENABLED 1u
|
||||
|
||||
#include <ucos_ii.h>
|
||||
#include <os_cpu.h> /* QL was: #include <lib_def.h> */
|
||||
typedef INT32U CPU_STK; /* QL added: Defines CPU stack data type. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_TMR_EN > 0u
|
||||
static INT16U OSTmrCtr;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_CM4_NVIC_ST_CTRL (*((volatile INT32U *)0xE000E010uL)) /* SysTick Ctrl & Status Reg. */
|
||||
#define OS_CPU_CM4_NVIC_ST_RELOAD (*((volatile INT32U *)0xE000E014uL)) /* SysTick Reload Value Reg. */
|
||||
#define OS_CPU_CM4_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018uL)) /* SysTick Current Value Reg. */
|
||||
#define OS_CPU_CM4_NVIC_ST_CAL (*((volatile INT32U *)0xE000E01CuL)) /* SysTick Cal Value Reg. */
|
||||
#define OS_CPU_CM4_NVIC_SHPRI1 (*((volatile INT32U *)0xE000ED18uL)) /* System Handlers 4 to 7 Prio. */
|
||||
#define OS_CPU_CM4_NVIC_SHPRI2 (*((volatile INT32U *)0xE000ED1CuL)) /* System Handlers 8 to 11 Prio. */
|
||||
#define OS_CPU_CM4_NVIC_SHPRI3 (*((volatile INT32U *)0xE000ED20uL)) /* System Handlers 12 to 15 Prio. */
|
||||
#define OS_CPU_CM4_NVIC_CPACR (*((volatile INT32U *)0xE000ED88uL)) /* Coprocessor Access Control Reg. */
|
||||
#define OS_CPU_CM4_SCB_FPCCR (*((volatile INT32U *)0xE000EF34uL)) /* Floating-Point Context Control Reg. */
|
||||
|
||||
|
||||
#define OS_CPU_CM4_NVIC_ST_CTRL_COUNT 0x00010000uL /* Count flag. */
|
||||
#define OS_CPU_CM4_NVIC_ST_CTRL_CLK_SRC 0x00000004uL /* Clock Source. */
|
||||
#define OS_CPU_CM4_NVIC_ST_CTRL_INTEN 0x00000002uL /* Interrupt enable. */
|
||||
#define OS_CPU_CM4_NVIC_ST_CTRL_ENABLE 0x00000001uL /* Counter mode. */
|
||||
#define OS_CPU_CM4_NVIC_PRIO_MIN 0xFFu /* Min handler prio. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
* (BEGINNING)
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts should be disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSInitHookBegin (void)
|
||||
{
|
||||
INT32U size;
|
||||
OS_STK *pstk;
|
||||
|
||||
/* Clear exception stack for stack checking. */
|
||||
pstk = &OS_CPU_ExceptStk[0];
|
||||
size = OS_CPU_EXCEPT_STK_SIZE;
|
||||
while (size > 0u) {
|
||||
size--;
|
||||
*pstk++ = (OS_STK)0;
|
||||
}
|
||||
|
||||
/* Align the ISR stack to 8-bytes */
|
||||
OS_CPU_ExceptStkBase = (OS_STK *)&OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE];
|
||||
OS_CPU_ExceptStkBase = (OS_STK *)((OS_STK)(OS_CPU_ExceptStkBase) & 0xFFFFFFF8);
|
||||
|
||||
#if OS_TMR_EN > 0u
|
||||
OSTmrCtr = 0u;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
* (END)
|
||||
*
|
||||
* Description: This function is called by OSInit() at the end of OSInit().
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts should be disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSInitHookEnd (void)
|
||||
{
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
/* Enable access to Floating-point coprocessor. */
|
||||
OS_CPU_CM4_NVIC_CPACR |= ((3UL << 10*2) | (3UL << 11*2));
|
||||
|
||||
/* Explictily Disable the automatic FPU state preservation as well as the FPU lazy stacking */
|
||||
OS_CPU_CM4_SCB_FPCCR &= ~((1U << 31) | (1U << 30));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK CREATION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is created.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the task control block of the task being created.
|
||||
*
|
||||
* Note(s) : 1) Interrupts are disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSTaskCreateHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TaskCreateHook(ptcb);
|
||||
#else
|
||||
(void)ptcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK DELETION HOOK
|
||||
*
|
||||
* Description: This function is called when a task is deleted.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the task control block of the task being deleted.
|
||||
*
|
||||
* Note(s) : 1) Interrupts are disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSTaskDelHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TaskDelHook(ptcb);
|
||||
#else
|
||||
(void)ptcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* IDLE TASK HOOK
|
||||
*
|
||||
* Description: This function is called by the idle task. This hook has been added to allow you to do
|
||||
* such things as STOP the CPU to conserve power.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts are enabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSTaskIdleHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TaskIdleHook();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK RETURN HOOK
|
||||
*
|
||||
* Description: This function is called if a task accidentally returns. In other words, a task should
|
||||
* either be an infinite loop or delete itself when done.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the task control block of the task that is returning.
|
||||
*
|
||||
* Note(s) : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSTaskReturnHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TaskReturnHook(ptcb);
|
||||
#else
|
||||
(void)ptcb;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* STATISTIC TASK HOOK
|
||||
*
|
||||
* Description: This function is called every second by uC/OS-II's statistics task. This allows your
|
||||
* application to add functionality to the statistics task.
|
||||
*
|
||||
* Arguments : none
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSTaskStatHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TaskStatHook();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
|
||||
* stack frame of the task being created. This function is highly processor specific.
|
||||
*
|
||||
* Arguments : task is a pointer to the task code
|
||||
*
|
||||
* p_arg is a pointer to a user supplied data area that will be passed to the task
|
||||
* when the task first executes.
|
||||
*
|
||||
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
|
||||
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
|
||||
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
|
||||
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
|
||||
* of the stack.
|
||||
*
|
||||
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
|
||||
* (see uCOS_II.H for OS_TASK_OPT_xxx).
|
||||
*
|
||||
* Returns : Always returns the location of the new top-of-stack once the processor registers have
|
||||
* been placed on the stack in the proper order.
|
||||
*
|
||||
* Note(s) : (1) Interrupts are enabled when task starts executing.
|
||||
*
|
||||
* (2) All tasks run in Thread mode, using process stack.
|
||||
*
|
||||
* (3) There are two different stack frames depending on whether the Floating-Point(FP)
|
||||
* co-processor is enabled or not.
|
||||
*
|
||||
* (a) The stack frame shown in the diagram is used when the FP co-processor is not present and
|
||||
* OS_TASK_OPT_SAVE_FP is disabled. In this case, the FP registers and FP Status Control
|
||||
* register are not saved in the stack frame.
|
||||
*
|
||||
* (b) If the FP co-processor is present but the OS_TASK_OPT_SAVE_FP is not set, then the stack
|
||||
* frame is saved as shown in diagram (a). Moreover, if OS_TASK_OPT_SAVE_FP is set, then the
|
||||
* FP registers and FP Status Control register are saved in the stack frame.
|
||||
*
|
||||
* (1) When enabling the FP co-processor, make sure to clear bits ASPEN and LSPEN in the
|
||||
* Floating-Point Context Control Register (FPCCR).
|
||||
*
|
||||
* +------------+ +------------+
|
||||
* | | | |
|
||||
* +------------+ +------------+
|
||||
* | xPSR | | xPSR |
|
||||
* +------------+ +------------+
|
||||
* |Return Addr | |Return Addr |
|
||||
* +------------+ +------------+
|
||||
* | LR(R14) | | LR(R14) |
|
||||
* +------------+ +------------+
|
||||
* | R12 | | R12 |
|
||||
* +------------+ +------------+
|
||||
* | R3 | | R3 |
|
||||
* +------------+ +------------+
|
||||
* | R2 | | R0 |
|
||||
* +------------+ +------------+
|
||||
* | R1 | | R1 |
|
||||
* +------------+ +------------+
|
||||
* | R0 | | R0 |
|
||||
* +------------+ +------------+
|
||||
* | R11 | | R11 |
|
||||
* +------------+ +------------+
|
||||
* | R10 | | R10 |
|
||||
* +------------+ +------------+
|
||||
* | R9 | | R9 |
|
||||
* +------------+ +------------+
|
||||
* | R8 | | R8 |
|
||||
* +------------+ +------------+
|
||||
* | R7 | | R7 |
|
||||
* +------------+ +------------+
|
||||
* | R6 | | R6 |
|
||||
* +------------+ +------------+
|
||||
* | R5 | | R5 |
|
||||
* +------------+ +------------+
|
||||
* | R4 | | R4 |
|
||||
* +------------+ +------------+
|
||||
* (a) | FPSCR |
|
||||
* +------------+
|
||||
* | S31 |
|
||||
* +------------+
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* +------------+
|
||||
* | S1 |
|
||||
+------------+
|
||||
* | S0 |
|
||||
* +------------+
|
||||
* (b)
|
||||
*
|
||||
* (4) The SP must be 8-byte aligned in conforming to the Procedure Call Standard for the ARM architecture
|
||||
*
|
||||
* (a) Section 2.1 of the ABI for the ARM Architecture Advisory Note. SP must be 8-byte aligned
|
||||
* on entry to AAPCS-Conforming functions states :
|
||||
*
|
||||
* The Procedure Call Standard for the ARM Architecture [AAPCS] requires primitive
|
||||
* data types to be naturally aligned according to their sizes (for size = 1, 2, 4, 8 bytes).
|
||||
* Doing otherwise creates more problems than it solves.
|
||||
*
|
||||
* In return for preserving the natural alignment of data, conforming code is permitted
|
||||
* to rely on that alignment. To support aligning data allocated on the stack, the stack
|
||||
* pointer (SP) is required to be 8-byte aligned on entry to a conforming function. In
|
||||
* practice this requirement is met if:
|
||||
*
|
||||
* (1) At each call site, the current size of the calling function<EFBFBD>s stack frame is a multiple of 8 bytes.
|
||||
* This places an obligation on compilers and assembly language programmers.
|
||||
*
|
||||
* (2) SP is a multiple of 8 when control first enters a program.
|
||||
* This places an obligation on authors of low level OS, RTOS, and runtime library
|
||||
* code to align SP at all points at which control first enters
|
||||
* a body of (AAPCS-conforming) code.
|
||||
*
|
||||
* In turn, this requires the value of SP to be aligned to 0 modulo 8:
|
||||
*
|
||||
* (3) By exception handlers, before calling AAPCS-conforming code.
|
||||
*
|
||||
* (4) By OS/RTOS/run-time system code, before giving control to an application.
|
||||
*
|
||||
* (b) Section 2.3.1 corrective steps from the the SP must be 8-byte aligned on entry
|
||||
* to AAPCS-conforming functions advisory note also states.
|
||||
*
|
||||
* " This requirement extends to operating systems and run-time code for all architecture versions
|
||||
* prior to ARMV7 and to the A, R and M architecture profiles thereafter. Special considerations
|
||||
* associated with ARMV7M are discussed in <EFBFBD>2.3.3"
|
||||
*
|
||||
* (1) Even if the SP 8-byte aligment is not a requirement for the ARMv7M profile, the stack is aligned
|
||||
* to 8-byte boundaries to support legacy execution enviroments.
|
||||
*
|
||||
* (c) Section 5.2.1.2 from the Procedure Call Standard for the ARM
|
||||
* architecture states : "The stack must also conform to the following
|
||||
* constraint at a public interface:
|
||||
*
|
||||
* (1) SP mod 8 = 0. The stack must be double-word aligned"
|
||||
*
|
||||
* (d) From the ARM Technical Support Knowledge Base. 8 Byte stack aligment.
|
||||
*
|
||||
* "8 byte stack alignment is a requirement of the ARM Architecture Procedure
|
||||
* Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte
|
||||
* aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external
|
||||
* interfaces. In practice this requirement is met if:
|
||||
*
|
||||
* (1) At each external interface, the current stack pointer
|
||||
* is a multiple of 8 bytes.
|
||||
*
|
||||
* (2) Your OS maintains 8 byte stack alignment on its external interfaces
|
||||
* e.g. on task switches"
|
||||
*
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
|
||||
{
|
||||
OS_STK *p_stk;
|
||||
|
||||
|
||||
p_stk = ptos + 1u; /* Load stack pointer */
|
||||
/* Align the stack to 8-bytes. */
|
||||
p_stk = (OS_STK *)((OS_STK)(p_stk) & 0xFFFFFFF8u);
|
||||
/* Registers stacked as if auto-saved on exception */
|
||||
*(--p_stk) = (OS_STK)0x01000000uL; /* xPSR */
|
||||
*(--p_stk) = (OS_STK)task; /* Entry Point */
|
||||
*(--p_stk) = (OS_STK)OS_TaskReturn; /* R14 (LR) */
|
||||
*(--p_stk) = (OS_STK)0x12121212uL; /* R12 */
|
||||
*(--p_stk) = (OS_STK)0x03030303uL; /* R3 */
|
||||
*(--p_stk) = (OS_STK)0x02020202uL; /* R2 */
|
||||
*(--p_stk) = (OS_STK)0x01010101uL; /* R1 */
|
||||
*(--p_stk) = (OS_STK)p_arg; /* R0 : argument */
|
||||
|
||||
/* Remaining registers saved on process stack */
|
||||
*(--p_stk) = (OS_STK)0x11111111uL; /* R11 */
|
||||
*(--p_stk) = (OS_STK)0x10101010uL; /* R10 */
|
||||
*(--p_stk) = (OS_STK)0x09090909uL; /* R9 */
|
||||
*(--p_stk) = (OS_STK)0x08080808uL; /* R8 */
|
||||
*(--p_stk) = (OS_STK)0x07070707uL; /* R7 */
|
||||
*(--p_stk) = (OS_STK)0x06060606uL; /* R6 */
|
||||
*(--p_stk) = (OS_STK)0x05050505uL; /* R5 */
|
||||
*(--p_stk) = (OS_STK)0x04040404uL; /* R4 */
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
if ((opt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) {
|
||||
*--p_stk = (OS_STK)0x02000000u; /* FPSCR */
|
||||
/* Initialize S0-S31 floating point registers */
|
||||
*--p_stk = (OS_STK)0x41F80000u; /* S31 */
|
||||
*--p_stk = (OS_STK)0x41F00000u; /* S30 */
|
||||
*--p_stk = (OS_STK)0x41E80000u; /* S29 */
|
||||
*--p_stk = (OS_STK)0x41E00000u; /* S28 */
|
||||
*--p_stk = (OS_STK)0x41D80000u; /* S27 */
|
||||
*--p_stk = (OS_STK)0x41D00000u; /* S26 */
|
||||
*--p_stk = (OS_STK)0x41C80000u; /* S25 */
|
||||
*--p_stk = (OS_STK)0x41C00000u; /* S24 */
|
||||
*--p_stk = (OS_STK)0x41B80000u; /* S23 */
|
||||
*--p_stk = (OS_STK)0x41B00000u; /* S22 */
|
||||
*--p_stk = (OS_STK)0x41A80000u; /* S21 */
|
||||
*--p_stk = (OS_STK)0x41A00000u; /* S20 */
|
||||
*--p_stk = (OS_STK)0x41980000u; /* S19 */
|
||||
*--p_stk = (OS_STK)0x41900000u; /* S18 */
|
||||
*--p_stk = (OS_STK)0x41880000u; /* S17 */
|
||||
*--p_stk = (OS_STK)0x41800000u; /* S16 */
|
||||
*--p_stk = (OS_STK)0x41700000u; /* S15 */
|
||||
*--p_stk = (OS_STK)0x41600000u; /* S14 */
|
||||
*--p_stk = (OS_STK)0x41500000u; /* S13 */
|
||||
*--p_stk = (OS_STK)0x41400000u; /* S12 */
|
||||
*--p_stk = (OS_STK)0x41300000u; /* S11 */
|
||||
*--p_stk = (OS_STK)0x41200000u; /* S10 */
|
||||
*--p_stk = (OS_STK)0x41100000u; /* S9 */
|
||||
*--p_stk = (OS_STK)0x41000000u; /* S8 */
|
||||
*--p_stk = (OS_STK)0x40E00000u; /* S7 */
|
||||
*--p_stk = (OS_STK)0x40C00000u; /* S6 */
|
||||
*--p_stk = (OS_STK)0x40A00000u; /* S5 */
|
||||
*--p_stk = (OS_STK)0x40800000u; /* S4 */
|
||||
*--p_stk = (OS_STK)0x40400000u; /* S3 */
|
||||
*--p_stk = (OS_STK)0x40000000u; /* S2 */
|
||||
*--p_stk = (OS_STK)0x3F800000u; /* S1 */
|
||||
*--p_stk = (OS_STK)0x00000000u; /* S0 */
|
||||
}
|
||||
#endif
|
||||
|
||||
return (p_stk);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK SWITCH HOOK
|
||||
*
|
||||
* Description: This function is called when a task switch is performed. This allows you to perform other
|
||||
* operations during a context switch.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts are disabled during this call.
|
||||
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
|
||||
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
|
||||
* task being switched out (i.e. the preempted task).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if (OS_CPU_HOOKS_EN > 0u) && (OS_TASK_SW_HOOK_EN > 0u)
|
||||
void OSTaskSwHook (void)
|
||||
{
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
if ((OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) {
|
||||
OS_CPU_FP_Reg_Push(OSTCBCur->OSTCBStkPtr);
|
||||
}
|
||||
|
||||
if ((OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) {
|
||||
OS_CPU_FP_Reg_Pop(OSTCBHighRdy->OSTCBStkPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TaskSwHook();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS_TCBInit() HOOK
|
||||
*
|
||||
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.
|
||||
*
|
||||
* Arguments : ptcb is a pointer to the TCB of the task being created.
|
||||
*
|
||||
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_CPU_HOOKS_EN > 0u
|
||||
void OSTCBInitHook (OS_TCB *ptcb)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TCBInitHook(ptcb);
|
||||
#else
|
||||
(void)ptcb; /* Prevent compiler warning */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TICK HOOK
|
||||
*
|
||||
* Description: This function is called every tick.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if (OS_CPU_HOOKS_EN > 0u) && (OS_TIME_TICK_HOOK_EN > 0u)
|
||||
void OSTimeTickHook (void)
|
||||
{
|
||||
#if OS_APP_HOOKS_EN > 0u
|
||||
App_TimeTickHook();
|
||||
#endif
|
||||
|
||||
#if OS_TMR_EN > 0u
|
||||
OSTmrCtr++;
|
||||
if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {
|
||||
OSTmrCtr = 0;
|
||||
OSTmrSignal();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK HANDLER
|
||||
*
|
||||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
|
||||
* interrupt.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void SysTick_Handler (void) /* QL was: void OS_CPU_SysTickHandler (void) */
|
||||
{
|
||||
OS_CPU_SR cpu_sr;
|
||||
|
||||
|
||||
OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR */
|
||||
OSIntNesting++;
|
||||
OS_EXIT_CRITICAL();
|
||||
|
||||
OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */
|
||||
|
||||
OSIntExit(); /* Tell uC/OS-II that we are leaving the ISR */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick.
|
||||
*
|
||||
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInit (INT32U cnts)
|
||||
{
|
||||
INT32U prio;
|
||||
|
||||
|
||||
OS_CPU_CM4_NVIC_ST_RELOAD = cnts - 1u;
|
||||
|
||||
/* Set SysTick handler prio. */
|
||||
prio = OS_CPU_CM4_NVIC_SHPRI3;
|
||||
prio &= 0x00FFFFFF; /* QL was: DEF_BIT_FIELD(24, 0); */
|
||||
prio |= OS_CPU_CFG_SYSTICK_PRIO << 24; /* QL was: DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24); */
|
||||
|
||||
OS_CPU_CM4_NVIC_SHPRI3 = prio;
|
||||
|
||||
/* Enable timer. */
|
||||
OS_CPU_CM4_NVIC_ST_CTRL |= OS_CPU_CM4_NVIC_ST_CTRL_CLK_SRC |
|
||||
OS_CPU_CM4_NVIC_ST_CTRL_ENABLE;
|
||||
/* Enable timer interrupt. */
|
||||
OS_CPU_CM4_NVIC_ST_CTRL |= OS_CPU_CM4_NVIC_ST_CTRL_INTEN;
|
||||
}
|
315
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_dbg.c
vendored
Normal file
315
3rd_party/uCOS-II/Ports/ARM-Cortex-M4/Generic/GNU/os_dbg.c
vendored
Normal file
@ -0,0 +1,315 @@
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-II
|
||||
* The Real-Time Kernel
|
||||
* DEBUGGER CONSTANTS
|
||||
*
|
||||
* (c) Copyright 1992-2009, Micrium, Weston, FL
|
||||
* All Rights Reserved
|
||||
*
|
||||
* File : OS_DBG.C
|
||||
* By : Jean J. Labrosse
|
||||
* Version : V2.92.09
|
||||
*
|
||||
* LICENSING TERMS:
|
||||
* ---------------
|
||||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
|
||||
* If you plan on using uC/OS-II in a commercial product you need to contact Micri<EFBFBD>m to properly license
|
||||
* its use in your product. We provide ALL the source code for your convenience and to help you experience
|
||||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
|
||||
* licensing fee.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <ucos_ii.h>
|
||||
|
||||
#define OS_COMPILER_OPT __root
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUG DATA
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSDebugEn = OS_DEBUG_EN; /* Debug constants are defined below */
|
||||
|
||||
#if OS_DEBUG_EN > 0u
|
||||
|
||||
OS_COMPILER_OPT INT32U const OSEndiannessTest = 0x12345678L; /* Variable to test CPU endianness */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSEventEn = OS_EVENT_EN;
|
||||
OS_COMPILER_OPT INT16U const OSEventMax = OS_MAX_EVENTS; /* Number of event control blocks */
|
||||
OS_COMPILER_OPT INT16U const OSEventNameEn = OS_EVENT_NAME_EN;
|
||||
#if (OS_EVENT_EN > 0u) && (OS_MAX_EVENTS > 0u)
|
||||
OS_COMPILER_OPT INT16U const OSEventSize = sizeof(OS_EVENT); /* Size in Bytes of OS_EVENT */
|
||||
OS_COMPILER_OPT INT16U const OSEventTblSize = sizeof(OSEventTbl); /* Size of OSEventTbl[] in bytes */
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSEventSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSEventTblSize = 0u;
|
||||
#endif
|
||||
OS_COMPILER_OPT INT16U const OSEventMultiEn = OS_EVENT_MULTI_EN;
|
||||
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSFlagEn = OS_FLAG_EN;
|
||||
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
|
||||
OS_COMPILER_OPT INT16U const OSFlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */
|
||||
OS_COMPILER_OPT INT16U const OSFlagNodeSize = sizeof(OS_FLAG_NODE); /* Size in Bytes of OS_FLAG_NODE */
|
||||
OS_COMPILER_OPT INT16U const OSFlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSFlagGrpSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSFlagNodeSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSFlagWidth = 0u;
|
||||
#endif
|
||||
OS_COMPILER_OPT INT16U const OSFlagMax = OS_MAX_FLAGS;
|
||||
OS_COMPILER_OPT INT16U const OSFlagNameEn = OS_FLAG_NAME_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSLowestPrio = OS_LOWEST_PRIO;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSMboxEn = OS_MBOX_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSMemEn = OS_MEM_EN;
|
||||
OS_COMPILER_OPT INT16U const OSMemMax = OS_MAX_MEM_PART; /* Number of memory partitions */
|
||||
OS_COMPILER_OPT INT16U const OSMemNameEn = OS_MEM_NAME_EN;
|
||||
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
|
||||
OS_COMPILER_OPT INT16U const OSMemSize = sizeof(OS_MEM); /* Mem. Partition header sine (bytes) */
|
||||
OS_COMPILER_OPT INT16U const OSMemTblSize = sizeof(OSMemTbl);
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSMemSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSMemTblSize = 0u;
|
||||
#endif
|
||||
OS_COMPILER_OPT INT16U const OSMutexEn = OS_MUTEX_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSPtrSize = sizeof(void *); /* Size in Bytes of a pointer */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSQEn = OS_Q_EN;
|
||||
OS_COMPILER_OPT INT16U const OSQMax = OS_MAX_QS; /* Number of queues */
|
||||
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
|
||||
OS_COMPILER_OPT INT16U const OSQSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSQSize = 0u;
|
||||
#endif
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSRdyTblSize = OS_RDY_TBL_SIZE; /* Number of bytes in the ready table */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSSemEn = OS_SEM_EN;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSStkWidth = sizeof(OS_STK); /* Size in Bytes of a stack entry */
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSTaskCreateEn = OS_TASK_CREATE_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskCreateExtEn = OS_TASK_CREATE_EXT_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskDelEn = OS_TASK_DEL_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskIdleStkSize = OS_TASK_IDLE_STK_SIZE;
|
||||
OS_COMPILER_OPT INT16U const OSTaskProfileEn = OS_TASK_PROFILE_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskMax = OS_MAX_TASKS + OS_N_SYS_TASKS; /* Total max. number of tasks */
|
||||
OS_COMPILER_OPT INT16U const OSTaskNameEn = OS_TASK_NAME_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskStatEn = OS_TASK_STAT_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskStatStkSize = OS_TASK_STAT_STK_SIZE;
|
||||
OS_COMPILER_OPT INT16U const OSTaskStatStkChkEn = OS_TASK_STAT_STK_CHK_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskSwHookEn = OS_TASK_SW_HOOK_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTaskRegTblSize = OS_TASK_REG_TBL_SIZE;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSTCBPrioTblMax = OS_LOWEST_PRIO + 1u; /* Number of entries in OSTCBPrioTbl[] */
|
||||
OS_COMPILER_OPT INT16U const OSTCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */
|
||||
OS_COMPILER_OPT INT16U const OSTicksPerSec = OS_TICKS_PER_SEC;
|
||||
OS_COMPILER_OPT INT16U const OSTimeTickHookEn = OS_TIME_TICK_HOOK_EN;
|
||||
OS_COMPILER_OPT INT16U const OSVersionNbr = OS_VERSION;
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSTmrEn = OS_TMR_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTmrCfgMax = OS_TMR_CFG_MAX;
|
||||
OS_COMPILER_OPT INT16U const OSTmrCfgNameEn = OS_TMR_CFG_NAME_EN;
|
||||
OS_COMPILER_OPT INT16U const OSTmrCfgWheelSize = OS_TMR_CFG_WHEEL_SIZE;
|
||||
OS_COMPILER_OPT INT16U const OSTmrCfgTicksPerSec = OS_TMR_CFG_TICKS_PER_SEC;
|
||||
|
||||
#if (OS_TMR_EN > 0u) && (OS_TMR_CFG_MAX > 0u)
|
||||
OS_COMPILER_OPT INT16U const OSTmrSize = sizeof(OS_TMR);
|
||||
OS_COMPILER_OPT INT16U const OSTmrTblSize = sizeof(OSTmrTbl);
|
||||
OS_COMPILER_OPT INT16U const OSTmrWheelSize = sizeof(OS_TMR_WHEEL);
|
||||
OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = sizeof(OSTmrWheelTbl);
|
||||
#else
|
||||
OS_COMPILER_OPT INT16U const OSTmrSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSTmrTblSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSTmrWheelSize = 0u;
|
||||
OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = 0u;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUG DATA
|
||||
* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-II
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if OS_DEBUG_EN > 0u
|
||||
|
||||
OS_COMPILER_OPT INT16U const OSDataSize = sizeof(OSCtxSwCtr)
|
||||
#if (OS_EVENT_EN > 0u) && (OS_MAX_EVENTS > 0u)
|
||||
+ sizeof(OSEventFreeList)
|
||||
+ sizeof(OSEventTbl)
|
||||
#endif
|
||||
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
|
||||
+ sizeof(OSFlagTbl)
|
||||
+ sizeof(OSFlagFreeList)
|
||||
#endif
|
||||
#if OS_TASK_STAT_EN > 0u
|
||||
+ sizeof(OSCPUUsage)
|
||||
+ sizeof(OSIdleCtrMax)
|
||||
+ sizeof(OSIdleCtrRun)
|
||||
+ sizeof(OSStatRdy)
|
||||
+ sizeof(OSTaskStatStk)
|
||||
#endif
|
||||
#if OS_TICK_STEP_EN > 0u
|
||||
+ sizeof(OSTickStepState)
|
||||
#endif
|
||||
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
|
||||
+ sizeof(OSMemFreeList)
|
||||
+ sizeof(OSMemTbl)
|
||||
#endif
|
||||
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
|
||||
+ sizeof(OSQFreeList)
|
||||
+ sizeof(OSQTbl)
|
||||
#endif
|
||||
#if OS_TIME_GET_SET_EN > 0u
|
||||
+ sizeof(OSTime)
|
||||
#endif
|
||||
#if (OS_TMR_EN > 0u) && (OS_TMR_CFG_MAX > 0u)
|
||||
+ sizeof(OSTmrFree)
|
||||
+ sizeof(OSTmrUsed)
|
||||
+ sizeof(OSTmrTime)
|
||||
+ sizeof(OSTmrSem)
|
||||
+ sizeof(OSTmrSemSignal)
|
||||
+ sizeof(OSTmrTbl)
|
||||
+ sizeof(OSTmrFreeList)
|
||||
+ sizeof(OSTmrTaskStk)
|
||||
+ sizeof(OSTmrWheelTbl)
|
||||
#endif
|
||||
+ sizeof(OSIntNesting)
|
||||
+ sizeof(OSLockNesting)
|
||||
+ sizeof(OSPrioCur)
|
||||
+ sizeof(OSPrioHighRdy)
|
||||
+ sizeof(OSRdyGrp)
|
||||
+ sizeof(OSRdyTbl)
|
||||
+ sizeof(OSRunning)
|
||||
+ sizeof(OSTaskCtr)
|
||||
+ sizeof(OSIdleCtr)
|
||||
+ sizeof(OSTaskIdleStk)
|
||||
+ sizeof(OSTCBCur)
|
||||
+ sizeof(OSTCBFreeList)
|
||||
+ sizeof(OSTCBHighRdy)
|
||||
+ sizeof(OSTCBList)
|
||||
+ sizeof(OSTCBPrioTbl)
|
||||
+ sizeof(OSTCBTbl);
|
||||
|
||||
#endif
|
||||
|
||||
/*$PAGE*/
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS DEBUG INITIALIZATION
|
||||
*
|
||||
* Description: This function is used to make sure that debug variables that are unused in the application
|
||||
* are not optimized away. This function might not be necessary for all compilers. In this
|
||||
* case, you should simply DELETE the code in this function while still leaving the declaration
|
||||
* of the function itself.
|
||||
*
|
||||
* Arguments : none
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out
|
||||
* the 'const' variables which are declared in this file.
|
||||
* (2) You may decide to 'compile out' the code (by using #if 0/#endif) INSIDE the function
|
||||
* if your compiler DOES NOT optimize out the 'const' variables above.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if OS_DEBUG_EN > 0u
|
||||
void OSDebugInit (void)
|
||||
{
|
||||
void *ptemp;
|
||||
|
||||
|
||||
ptemp = (void *)&OSDebugEn;
|
||||
|
||||
ptemp = (void *)&OSEndiannessTest;
|
||||
|
||||
ptemp = (void *)&OSEventMax;
|
||||
ptemp = (void *)&OSEventNameEn;
|
||||
ptemp = (void *)&OSEventEn;
|
||||
ptemp = (void *)&OSEventSize;
|
||||
ptemp = (void *)&OSEventTblSize;
|
||||
ptemp = (void *)&OSEventMultiEn;
|
||||
|
||||
ptemp = (void *)&OSFlagEn;
|
||||
ptemp = (void *)&OSFlagGrpSize;
|
||||
ptemp = (void *)&OSFlagNodeSize;
|
||||
ptemp = (void *)&OSFlagWidth;
|
||||
ptemp = (void *)&OSFlagMax;
|
||||
ptemp = (void *)&OSFlagNameEn;
|
||||
|
||||
ptemp = (void *)&OSLowestPrio;
|
||||
|
||||
ptemp = (void *)&OSMboxEn;
|
||||
|
||||
ptemp = (void *)&OSMemEn;
|
||||
ptemp = (void *)&OSMemMax;
|
||||
ptemp = (void *)&OSMemNameEn;
|
||||
ptemp = (void *)&OSMemSize;
|
||||
ptemp = (void *)&OSMemTblSize;
|
||||
|
||||
ptemp = (void *)&OSMutexEn;
|
||||
|
||||
ptemp = (void *)&OSPtrSize;
|
||||
|
||||
ptemp = (void *)&OSQEn;
|
||||
ptemp = (void *)&OSQMax;
|
||||
ptemp = (void *)&OSQSize;
|
||||
|
||||
ptemp = (void *)&OSRdyTblSize;
|
||||
|
||||
ptemp = (void *)&OSSemEn;
|
||||
|
||||
ptemp = (void *)&OSStkWidth;
|
||||
|
||||
ptemp = (void *)&OSTaskCreateEn;
|
||||
ptemp = (void *)&OSTaskCreateExtEn;
|
||||
ptemp = (void *)&OSTaskDelEn;
|
||||
ptemp = (void *)&OSTaskIdleStkSize;
|
||||
ptemp = (void *)&OSTaskProfileEn;
|
||||
ptemp = (void *)&OSTaskMax;
|
||||
ptemp = (void *)&OSTaskNameEn;
|
||||
ptemp = (void *)&OSTaskStatEn;
|
||||
ptemp = (void *)&OSTaskStatStkSize;
|
||||
ptemp = (void *)&OSTaskStatStkChkEn;
|
||||
ptemp = (void *)&OSTaskSwHookEn;
|
||||
|
||||
ptemp = (void *)&OSTCBPrioTblMax;
|
||||
ptemp = (void *)&OSTCBSize;
|
||||
|
||||
ptemp = (void *)&OSTicksPerSec;
|
||||
ptemp = (void *)&OSTimeTickHookEn;
|
||||
|
||||
#if OS_TMR_EN > 0u
|
||||
ptemp = (void *)&OSTmrTbl[0];
|
||||
ptemp = (void *)&OSTmrWheelTbl[0];
|
||||
|
||||
ptemp = (void *)&OSTmrEn;
|
||||
ptemp = (void *)&OSTmrCfgMax;
|
||||
ptemp = (void *)&OSTmrCfgNameEn;
|
||||
ptemp = (void *)&OSTmrCfgWheelSize;
|
||||
ptemp = (void *)&OSTmrCfgTicksPerSec;
|
||||
ptemp = (void *)&OSTmrSize;
|
||||
ptemp = (void *)&OSTmrTblSize;
|
||||
|
||||
ptemp = (void *)&OSTmrWheelSize;
|
||||
ptemp = (void *)&OSTmrWheelTblSize;
|
||||
#endif
|
||||
|
||||
ptemp = (void *)&OSVersionNbr;
|
||||
|
||||
ptemp = (void *)&OSDataSize;
|
||||
|
||||
ptemp = ptemp; /* Prevent compiler warning for 'ptemp' not being used! */
|
||||
}
|
||||
#endif
|
28
README.txt
28
README.txt
@ -42,6 +42,34 @@ mailto:info@state-machine.com
|
||||
#######################################################################
|
||||
##################### QP/C Revision History ###########################
|
||||
|
||||
QP/C Version 5.9.2 (05-Jun-2017)
|
||||
--------------------------------
|
||||
This release adapts the Makefiles for GNU-ARM to the new location of the
|
||||
GNU-ARM toolset, which is now included in the QTools Collection (v 5.9.1)
|
||||
for Windows.
|
||||
|
||||
Also, this release improves the flash loading scripts for the JLink
|
||||
hardware debugger (for GNU-ARM projects for the EFM32-SLSTK3401A board).
|
||||
Specifically, the JLink configuration file for flash download is
|
||||
generated by the flash batch script based on the command-line paramter
|
||||
(the binary file to load into the flash). This eliminates the need to
|
||||
manually maintain JLink configuration files.
|
||||
|
||||
Also, this release adds bi-directional QP/Spy to the embOS example
|
||||
project for the STM32F4-Discovery board.
|
||||
|
||||
Also, this release adds GNU-ARM port to uC/OS-II and adds GNU-ARM example
|
||||
project for the EK-TM4C123GXL board.
|
||||
|
||||
Finally, this release implements the feature request #125 "Include QPC
|
||||
Demo application for STM32F4 processor without RTOS" (see
|
||||
https://sourceforge.net/p/qpc/feature-requests/125/ ). The DPP demo for
|
||||
the STM32F4-Discovery board has been added in the directory:
|
||||
qpc\examples\arm-cm\dpp_stm32f4-discovery . This demo includes QV, QK and
|
||||
QXK kernels and ARM-Keil, GNU-ARM, and IAR-ARM toolsets. The demos support
|
||||
bi-directional QP/Spy.
|
||||
|
||||
|
||||
QP/C Version 5.9.1 (26-May-2017)
|
||||
--------------------------------
|
||||
This release fixes the following bug:
|
||||
|
@ -5,7 +5,7 @@
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "QP/C"
|
||||
PROJECT_NUMBER = "5.9.1"
|
||||
PROJECT_NUMBER = "5.9.2"
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO = images/header_logo_ql.png
|
||||
OUTPUT_DIRECTORY =
|
||||
|
@ -5,7 +5,7 @@
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "QP/C"
|
||||
PROJECT_NUMBER = "5.9.1"
|
||||
PROJECT_NUMBER = "5.9.2"
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO = images/header_logo_ql.png
|
||||
OUTPUT_DIRECTORY =
|
||||
|
@ -5,7 +5,7 @@
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "QP/C"
|
||||
PROJECT_NUMBER = "5.9.1"
|
||||
PROJECT_NUMBER = "5.9.2"
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO = images/header_logo_ql.png
|
||||
OUTPUT_DIRECTORY =
|
||||
|
@ -1,6 +1,26 @@
|
||||
/**
|
||||
@page history Revision History
|
||||
|
||||
@section qpc_5_9_2 Version 5.9.2, 2017-06-05
|
||||
This release adapts the Makefiles for GNU-ARM to the new location of the
|
||||
GNU-ARM toolset, which is now included in the QTools Collection (v 5.9.1)
|
||||
for Windows.
|
||||
|
||||
Also, this release improves the flash loading scripts for the JLink
|
||||
hardware debugger. Specifically, the JLink configuration file for flash
|
||||
download is generated by the flash batch script based on the command-line
|
||||
paramter (the binary file to load into the flash). This eliminates the
|
||||
need to manually maintain JLink configuration files.
|
||||
|
||||
Finally, this release implements the feature request #125 "Include QPC
|
||||
Demo application for STM32F4 processor without RTOS" (see https://sourceforge.net/p/qpc/feature-requests/125/ ). The DPP demo for
|
||||
the STM32F4-Discovery board has been added in the directory:
|
||||
qpc\examples\arm-cm\dpp_stm32f4-discovery . This demo includes QV, QK and
|
||||
QXK kernels and ARM-Keil, GNU-ARM, and IAR-ARM toolsets. The demos support
|
||||
bi-directional QP/Spy.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@section qpc_5_9_1 Version 5.9.1, 2017-05-26
|
||||
This release fixes the following bug:
|
||||
- <a href="https://sourceforge.net/p/qpc/bugs/169/" target="_blank" class="extern">bug#169 "Submachine-state eXit Point does not work correctly"</a>
|
||||
|
@ -1,8 +1,8 @@
|
||||
@echo off
|
||||
:: ==========================================================================
|
||||
:: Product: QP/C script for generating Doxygen documentation
|
||||
:: Last Updated for Version: 5.9.1
|
||||
:: Date of the Last Update: 2017-05-23
|
||||
:: Last Updated for Version: 5.9.2
|
||||
:: Date of the Last Update: 2017-06-05
|
||||
::
|
||||
:: Q u a n t u m L e a P s
|
||||
:: ---------------------------
|
||||
@ -38,7 +38,7 @@ echo usage:
|
||||
echo make
|
||||
echo make -CHM
|
||||
|
||||
set VERSION=5.9.1
|
||||
set VERSION=5.9.2
|
||||
|
||||
:: Generate Resource Standard Metrics for QP/C ...............................
|
||||
set DOXHOME="C:\tools\doxygen\bin"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @page metrics Code Metrics
|
||||
|
||||
@code
|
||||
Standard Code Metrics for QP/C 5.9.1
|
||||
Standard Code Metrics for QP/C 5.9.2
|
||||
|
||||
Resource Standard Metrics (TM) for C, C++, C# and Java
|
||||
Version 7.75 - mSquaredTechnologies.com
|
||||
@ -9,7 +9,7 @@
|
||||
License Type: Windows Single User License
|
||||
Licensed To : Quantum Leaps, LLC
|
||||
License No. : WS2975 License Date: Dec 15, 2013
|
||||
Build Date : Sep 2 2009 Run Date: May 27, 2017
|
||||
Build Date : Sep 2 2009 Run Date: Jun 05, 2017
|
||||
(C)1996-2009 M Squared Technologies LLC
|
||||
________________________________________________________________________
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
##############################################################################
|
||||
# Product: Makefile for Blinky on EMF32-SLSTK3401A, QK kernel, GNU-ARM
|
||||
# Last Updated for Version: 5.6.4
|
||||
# Date of the Last Update: 2016-05-08
|
||||
# Last Updated for Version: 5.9.1
|
||||
# Date of the Last Update: 2017-06-03
|
||||
#
|
||||
# Q u a n t u m L e a P s
|
||||
# ---------------------------
|
||||
@ -153,7 +153,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -7,22 +7,42 @@
|
||||
setlocal
|
||||
|
||||
@echo off
|
||||
@echo Load the program to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash bin-file
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: JLink utility on your machine
|
||||
::
|
||||
set JLINK=C:\tools\SEGGER\JLink\Jlink.exe
|
||||
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] EQU [] (
|
||||
@echo binary file missing
|
||||
@goto end
|
||||
)
|
||||
if NOT exist "%1" (
|
||||
@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
|
||||
|
||||
:: set the Jlink command file depending on the first parameter %1
|
||||
set CMD_FILE=flash_dbg.jlink
|
||||
if [%1] NEQ [] set CMD_FILE=flash_%1.jlink
|
||||
@echo on
|
||||
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
|
||||
@echo off
|
||||
|
||||
%JLINK% -device EFM32PG1B200F256GM48 %CMD_FILE%
|
||||
@del flash.jlink
|
||||
|
||||
:end
|
||||
|
||||
endlocal
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin dbg\blinky-qk.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin rel\blinky-qk.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin spy\blinky-qk.bin, 0
|
||||
exit
|
@ -1,70 +0,0 @@
|
||||
|
||||
dbg\qf_act.o: file format elf32-littlearm
|
||||
|
||||
|
||||
Disassembly of section .text.QF_add_:
|
||||
|
||||
00000000 <QF_add_>:
|
||||
0: b538 push {r3, r4, r5, lr}
|
||||
2: 4605 mov r5, r0
|
||||
4: 6a84 ldr r4, [r0, #40] ; 0x28
|
||||
6: 1e63 subs r3, r4, #1
|
||||
8: 2b1f cmp r3, #31
|
||||
a: d803 bhi.n 14 <QF_add_+0x14>
|
||||
c: 4b0a ldr r3, [pc, #40] ; (38 <QF_add_+0x38>)
|
||||
e: f853 3024 ldr.w r3, [r3, r4, lsl #2]
|
||||
12: b11b cbz r3, 1c <QF_add_+0x1c>
|
||||
14: 2164 movs r1, #100 ; 0x64
|
||||
16: 4809 ldr r0, [pc, #36] ; (3c <QF_add_+0x3c>)
|
||||
18: f7ff fffe bl 0 <Q_onAssert>
|
||||
1c: f3ef 8311 mrs r3, BASEPRI
|
||||
20: b672 cpsid i
|
||||
22: 223f movs r2, #63 ; 0x3f
|
||||
24: f382 8811 msr BASEPRI, r2
|
||||
28: b662 cpsie i
|
||||
2a: 4a03 ldr r2, [pc, #12] ; (38 <QF_add_+0x38>)
|
||||
2c: f842 5024 str.w r5, [r2, r4, lsl #2]
|
||||
30: f383 8811 msr BASEPRI, r3
|
||||
34: bd38 pop {r3, r4, r5, pc}
|
||||
36: bf00 nop
|
||||
...
|
||||
|
||||
Disassembly of section .text.QF_remove_:
|
||||
|
||||
00000000 <QF_remove_>:
|
||||
0: b538 push {r3, r4, r5, lr}
|
||||
2: 4604 mov r4, r0
|
||||
4: 6a85 ldr r5, [r0, #40] ; 0x28
|
||||
6: 1e6b subs r3, r5, #1
|
||||
8: 2b1f cmp r3, #31
|
||||
a: d804 bhi.n 16 <QF_remove_+0x16>
|
||||
c: 4b0b ldr r3, [pc, #44] ; (3c <QF_remove_+0x3c>)
|
||||
e: f853 3025 ldr.w r3, [r3, r5, lsl #2]
|
||||
12: 4298 cmp r0, r3
|
||||
14: d003 beq.n 1e <QF_remove_+0x1e>
|
||||
16: 21c8 movs r1, #200 ; 0xc8
|
||||
18: 4809 ldr r0, [pc, #36] ; (40 <QF_remove_+0x40>)
|
||||
1a: f7ff fffe bl 0 <Q_onAssert>
|
||||
1e: f3ef 8311 mrs r3, BASEPRI
|
||||
22: b672 cpsid i
|
||||
24: 223f movs r2, #63 ; 0x3f
|
||||
26: f382 8811 msr BASEPRI, r2
|
||||
2a: b662 cpsie i
|
||||
2c: 2200 movs r2, #0
|
||||
2e: 4903 ldr r1, [pc, #12] ; (3c <QF_remove_+0x3c>)
|
||||
30: f841 2025 str.w r2, [r1, r5, lsl #2]
|
||||
34: 6062 str r2, [r4, #4]
|
||||
36: f383 8811 msr BASEPRI, r3
|
||||
3a: bd38 pop {r3, r4, r5, pc}
|
||||
...
|
||||
|
||||
Disassembly of section .text.QF_bzero:
|
||||
|
||||
00000000 <QF_bzero>:
|
||||
0: b129 cbz r1, e <QF_bzero+0xe>
|
||||
2: 1841 adds r1, r0, r1
|
||||
4: 2300 movs r3, #0
|
||||
6: f800 3b01 strb.w r3, [r0], #1
|
||||
a: 4281 cmp r1, r0
|
||||
c: d1fb bne.n 6 <QF_bzero+0x6>
|
||||
e: 4770 bx lr
|
@ -1,7 +1,7 @@
|
||||
##############################################################################
|
||||
# Product: Makefile for Blinky on EMF32-SLSTK3401A, QV kernel, GNU-ARM
|
||||
# Last Updated for Version: 5.8.1
|
||||
# Date of the Last Update: 2016-12-15
|
||||
# Last Updated for Version: 5.9.2
|
||||
# Date of the Last Update: 2017-06-03
|
||||
#
|
||||
# Q u a n t u m L e a P s
|
||||
# ---------------------------
|
||||
@ -152,7 +152,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -7,22 +7,42 @@
|
||||
setlocal
|
||||
|
||||
@echo off
|
||||
@echo Load the program to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash bin-file
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: JLink utility on your machine
|
||||
::
|
||||
set JLINK=C:\tools\SEGGER\JLink\Jlink.exe
|
||||
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] EQU [] (
|
||||
@echo binary image missing
|
||||
@goto end
|
||||
)
|
||||
if NOT exist "%1" (
|
||||
@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
|
||||
|
||||
:: set the Jlink command file depending on the first parameter %1
|
||||
set CMD_FILE=flash_dbg.jlink
|
||||
if [%1] NEQ [] set CMD_FILE=flash_%1.jlink
|
||||
@echo on
|
||||
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
|
||||
@echo off
|
||||
|
||||
%JLINK% -device EFM32PG1B200F256GM48 %CMD_FILE%
|
||||
@del flash.jlink
|
||||
|
||||
:end
|
||||
|
||||
endlocal
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin dbg\blinky-qv.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin rel\blinky-qv, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin spy\blinky-qv, 0
|
||||
exit
|
@ -150,7 +150,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -17,7 +17,7 @@ setlocal
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set LMFLASH=C:\tools\TI\LM_Flash_Programmer\LMFlash.exe
|
||||
set LMFLASH=%QTOOLS%\..\LM_Flash_Programmer\LMFlash.exe
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
|
@ -149,7 +149,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -17,7 +17,7 @@ setlocal
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set LMFLASH=C:\tools\TI\LM_Flash_Programmer\LMFlash.exe
|
||||
set LMFLASH=%QTOOLS%\..\LM_Flash_Programmer\LMFlash.exe
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
|
@ -171,7 +171,8 @@ void USART0_RX_IRQHandler(void) {
|
||||
void USART0_RX_IRQHandler(void) {}
|
||||
#endif
|
||||
|
||||
/*..........................................................................*/
|
||||
|
||||
/* BSP functions ===========================================================*/
|
||||
void BSP_init(void) {
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
@ -248,7 +249,7 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) {
|
||||
QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */
|
||||
QS_U8(1, n); /* Philosopher number */
|
||||
QS_STR(stat); /* Philosopher status */
|
||||
QS_END()
|
||||
QS_END() /* application-specific record end */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPaused(uint8_t paused) {
|
||||
@ -287,7 +288,7 @@ void BSP_terminate(int16_t result) {
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
/* QF callbacks ============================================================*/
|
||||
void QF_onStartup(void) {
|
||||
/* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */
|
||||
SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
|
||||
@ -430,18 +431,9 @@ uint8_t QS_onStartup(void const *arg) {
|
||||
QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */
|
||||
|
||||
/* setup the QS filters... */
|
||||
QS_FILTER_ON(QS_QEP_STATE_ENTRY);
|
||||
QS_FILTER_ON(QS_QEP_STATE_EXIT);
|
||||
QS_FILTER_ON(QS_QEP_STATE_INIT);
|
||||
QS_FILTER_ON(QS_QEP_INIT_TRAN);
|
||||
QS_FILTER_ON(QS_QEP_INTERN_TRAN);
|
||||
QS_FILTER_ON(QS_QEP_TRAN);
|
||||
QS_FILTER_ON(QS_QEP_IGNORED);
|
||||
QS_FILTER_ON(QS_QEP_DISPATCH);
|
||||
QS_FILTER_ON(QS_QEP_UNHANDLED);
|
||||
|
||||
QS_FILTER_ON(PHILO_STAT);
|
||||
QS_FILTER_ON(COMMAND_STAT);
|
||||
QS_FILTER_ON(QS_SM_RECORDS); /* state machine records */
|
||||
//QS_FILTER_ON(QS_AO_RECORDS); /* active object records */
|
||||
QS_FILTER_ON(QS_UA_RECORDS); /* all user records */
|
||||
|
||||
return (uint8_t)1; /* return success */
|
||||
}
|
||||
@ -467,7 +459,7 @@ void QS_onFlush(void) {
|
||||
/* while TXE not empty */
|
||||
while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) {
|
||||
}
|
||||
l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */
|
||||
l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */
|
||||
QF_INT_DISABLE();
|
||||
}
|
||||
QF_INT_ENABLE();
|
||||
|
@ -1,7 +1,7 @@
|
||||
##############################################################################
|
||||
# Product: Makefile for DPP on EMF32-SLSTK3401A, QK kernel, GNU-ARM
|
||||
# Last Updated for Version: 5.6.4
|
||||
# Date of the Last Update: 2016-05-08
|
||||
# Last Updated for Version: 5.9.2
|
||||
# Date of the Last Update: 2017-06-03
|
||||
#
|
||||
# Q u a n t u m L e a P s
|
||||
# ---------------------------
|
||||
@ -155,7 +155,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -7,22 +7,42 @@
|
||||
setlocal
|
||||
|
||||
@echo off
|
||||
@echo Load the program to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash bin-file
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: JLink utility on your machine
|
||||
::
|
||||
set JLINK=C:\tools\SEGGER\JLink\Jlink.exe
|
||||
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] EQU [] (
|
||||
@echo binary image missing
|
||||
@goto end
|
||||
)
|
||||
if NOT exist "%1" (
|
||||
@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
|
||||
|
||||
:: set the Jlink command file depending on the first parameter %1
|
||||
set CMD_FILE=flash_dbg.jlink
|
||||
if [%1] NEQ [] set CMD_FILE=flash_%1.jlink
|
||||
@echo on
|
||||
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
|
||||
@echo off
|
||||
|
||||
%JLINK% -device EFM32PG1B200F256GM48 %CMD_FILE%
|
||||
@del flash.jlink
|
||||
|
||||
:end
|
||||
|
||||
endlocal
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin dbg\dpp-qk.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin rel\dpp-qk.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin spy\dpp-qk.bin, 0
|
||||
exit
|
@ -1,7 +1,7 @@
|
||||
##############################################################################
|
||||
# Product: Makefile for DPP on EMF32-SLSTK3401A, QV kernel, GNU-ARM
|
||||
# Last Updated for Version: 5.8.1
|
||||
# Date of the Last Update: 2016-12-15
|
||||
# Last Updated for Version: 5.9.2
|
||||
# Date of the Last Update: 2017-06-03
|
||||
#
|
||||
# Q u a n t u m L e a P s
|
||||
# ---------------------------
|
||||
@ -154,7 +154,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -7,22 +7,42 @@
|
||||
setlocal
|
||||
|
||||
@echo off
|
||||
@echo Load the program to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash bin-file
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: JLink utility on your machine
|
||||
::
|
||||
set JLINK=C:\tools\SEGGER\JLink\Jlink.exe
|
||||
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] EQU [] (
|
||||
@echo binary image missing
|
||||
@goto end
|
||||
)
|
||||
if NOT exist "%1" (
|
||||
@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
|
||||
|
||||
:: set the Jlink command file depending on the first parameter %1
|
||||
set CMD_FILE=flash_dbg.jlink
|
||||
if [%1] NEQ [] set CMD_FILE=flash_%1.jlink
|
||||
@echo on
|
||||
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
|
||||
@echo off
|
||||
|
||||
%JLINK% -device EFM32PG1B200F256GM48 %CMD_FILE%
|
||||
@del flash.jlink
|
||||
|
||||
:end
|
||||
|
||||
endlocal
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin dbg\dpp-qv.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin rel\dpp-qv.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin spy\dpp-qv.bin, 0
|
||||
exit
|
@ -1,7 +1,7 @@
|
||||
##############################################################################
|
||||
# Product: Makefile for DPP on EMF32-SLSTK3401A, QXK kernel, GNU-ARM
|
||||
# Last Updated for Version: 5.6.4
|
||||
# Date of the Last Update: 2016-05-08
|
||||
# Last Updated for Version: 5.9.2
|
||||
# Date of the Last Update: 2017-06-03
|
||||
#
|
||||
# Q u a n t u m L e a P s
|
||||
# ---------------------------
|
||||
@ -158,7 +158,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -7,22 +7,42 @@
|
||||
setlocal
|
||||
|
||||
@echo off
|
||||
@echo Load the program to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
@echo Load a given binary file to the flash of EFM32-SLSTK3401A
|
||||
@echo usage: flash bin-file
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: JLink utility on your machine
|
||||
::
|
||||
set JLINK=C:\tools\SEGGER\JLink\Jlink.exe
|
||||
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] EQU [] (
|
||||
@echo binary image missing
|
||||
@goto end
|
||||
)
|
||||
if NOT exist "%1" (
|
||||
@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
|
||||
|
||||
:: set the Jlink command file depending on the first parameter %1
|
||||
set CMD_FILE=flash_dbg.jlink
|
||||
if [%1] NEQ [] set CMD_FILE=flash_%1.jlink
|
||||
@echo on
|
||||
%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink
|
||||
@echo off
|
||||
|
||||
%JLINK% -device EFM32PG1B200F256GM48 %CMD_FILE%
|
||||
@del flash.jlink
|
||||
|
||||
:end
|
||||
|
||||
endlocal
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin dbg\dpp-qxk.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin rel\dpp-qxk.bin, 0
|
||||
exit
|
@ -1,6 +0,0 @@
|
||||
si 1
|
||||
speed 4000
|
||||
r
|
||||
h
|
||||
loadbin spy\dpp-qxk.bin, 0
|
||||
exit
|
@ -153,7 +153,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -17,7 +17,7 @@ setlocal
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set LMFLASH=C:\tools\TI\LM_Flash_Programmer\LMFlash.exe
|
||||
set LMFLASH=%QTOOLS%\..\LM_Flash_Programmer\LMFlash.exe
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
|
@ -152,7 +152,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -17,7 +17,7 @@ setlocal
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set LMFLASH=C:\tools\TI\LM_Flash_Programmer\LMFlash.exe
|
||||
set LMFLASH=%QTOOLS%\..\LM_Flash_Programmer\LMFlash.exe
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
|
@ -156,7 +156,7 @@ FLOAT_ABI := -mfloat-abi=softfp
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -17,7 +17,7 @@ setlocal
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set LMFLASH=C:\tools\TI\LM_Flash_Programmer\LMFlash.exe
|
||||
set LMFLASH=%QTOOLS%\..\LM_Flash_Programmer\LMFlash.exe
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
|
@ -151,7 +151,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -150,7 +150,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -151,7 +151,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -150,7 +150,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -154,7 +154,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -151,7 +151,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
@ -150,7 +150,7 @@ FLOAT_ABI :=
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM = C:/tools/gnu_arm-eabi
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-eabi
|
||||
endif
|
||||
|
||||
# make sure that the GNU-ARM toolset exists...
|
||||
|
54
examples/arm-cm/dpp_stm32f4-discovery/bsp.h
Normal file
54
examples/arm-cm/dpp_stm32f4-discovery/bsp.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*****************************************************************************
|
||||
* Product: DPP example
|
||||
* Last Updated for Version: 5.8.1
|
||||
* Date of the Last Update: 2016-12-12
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
#ifndef bsp_h
|
||||
#define bsp_h
|
||||
|
||||
#define BSP_TICKS_PER_SEC 100U
|
||||
|
||||
void BSP_init(void);
|
||||
void BSP_displayPaused(uint8_t paused);
|
||||
void BSP_displayPhilStat(uint8_t n, char_t const *stat);
|
||||
void BSP_terminate(int16_t result);
|
||||
|
||||
void BSP_randomSeed(uint32_t seed); /* random seed */
|
||||
uint32_t BSP_random(void); /* pseudo-random generator */
|
||||
|
||||
/* for testing... */
|
||||
void BSP_wait4PB1(void);
|
||||
void BSP_ledOn(void);
|
||||
void BSP_ledOff(void);
|
||||
|
||||
extern QActive *the_Ticker0;
|
||||
|
||||
#endif /* bsp_h */
|
71
examples/arm-cm/dpp_stm32f4-discovery/dpp.h
Normal file
71
examples/arm-cm/dpp_stm32f4-discovery/dpp.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* Model: dpp.qm
|
||||
* File: ./dpp.h
|
||||
*
|
||||
* This code has been generated by QM tool (see state-machine.com/qm).
|
||||
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
/*${.::dpp.h} ..............................................................*/
|
||||
#ifndef dpp_h
|
||||
#define dpp_h
|
||||
|
||||
enum DPPSignals {
|
||||
EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */
|
||||
DONE_SIG, /* published by Philosopher when done eating */
|
||||
PAUSE_SIG, /* published by BSP to pause serving forks */
|
||||
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 */
|
||||
|
||||
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
|
||||
TIMEOUT_SIG, /* used by Philosophers for time events */
|
||||
MAX_SIG /* the last signal */
|
||||
};
|
||||
|
||||
|
||||
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
|
||||
#error qpc version 5.8.0 or higher required
|
||||
#endif
|
||||
|
||||
/*${Events::TableEvt} ......................................................*/
|
||||
typedef struct {
|
||||
/* protected: */
|
||||
QEvt super;
|
||||
|
||||
/* public: */
|
||||
uint8_t philoNum;
|
||||
} TableEvt;
|
||||
|
||||
|
||||
/* number of philosophers */
|
||||
#define N_PHILO ((uint8_t)5)
|
||||
|
||||
/*${AOs::Philo_ctor} .......................................................*/
|
||||
void Philo_ctor(void);
|
||||
|
||||
extern QMActive * const AO_Philo[N_PHILO];
|
||||
|
||||
|
||||
/*${AOs::Table_ctor} .......................................................*/
|
||||
void Table_ctor(void);
|
||||
|
||||
extern QActive * const AO_Table;
|
||||
|
||||
|
||||
#ifdef qxk_h
|
||||
void Test1_ctor(void);
|
||||
extern QXThread * const XT_Test1;
|
||||
void Test2_ctor(void);
|
||||
extern QXThread * const XT_Test2;
|
||||
#endif /* qxk_h */
|
||||
|
||||
#endif /* dpp_h */
|
445
examples/arm-cm/dpp_stm32f4-discovery/dpp.qm
Normal file
445
examples/arm-cm/dpp_stm32f4-discovery/dpp.qm
Normal file
@ -0,0 +1,445 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<model version="4.0.0" links="0">
|
||||
<documentation>Dining Philosopher Problem example
|
||||
NOTE: Requries QP5.</documentation>
|
||||
<framework name="qpc"/>
|
||||
<package name="Events" stereotype="0x01">
|
||||
<class name="TableEvt" superclass="qpc::QEvt">
|
||||
<attribute name="philoNum" type="uint8_t" visibility="0x00" properties="0x00"/>
|
||||
</class>
|
||||
</package>
|
||||
<package name="AOs" stereotype="0x02">
|
||||
<class name="Philo" superclass="qpc::QActive">
|
||||
<attribute name="timeEvt" type="QTimeEvt" visibility="0x02" properties="0x00"/>
|
||||
<statechart>
|
||||
<initial target="../1">
|
||||
<action>static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */
|
||||
(void)e; /* suppress the compiler warning about unused parameter */
|
||||
if (registered == (uint8_t)0) {
|
||||
registered = (uint8_t)1;
|
||||
|
||||
QS_OBJ_DICTIONARY(&l_philo[0]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[0].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[1]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[1].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[2]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[2].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[3]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[3].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[4]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[4].timeEvt);
|
||||
|
||||
QS_FUN_DICTIONARY(&Philo_initial);
|
||||
QS_FUN_DICTIONARY(&Philo_thinking);
|
||||
QS_FUN_DICTIONARY(&Philo_hungry);
|
||||
QS_FUN_DICTIONARY(&Philo_eating);
|
||||
}
|
||||
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */
|
||||
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
|
||||
|
||||
QActive_subscribe(&me->super, EAT_SIG);
|
||||
QActive_subscribe(&me->super, TEST_SIG);</action>
|
||||
<initial_glyph conn="2,3,5,1,20,5,-3">
|
||||
<action box="0,-2,6,2"/>
|
||||
</initial_glyph>
|
||||
</initial>
|
||||
<state name="thinking">
|
||||
<entry>QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U);</entry>
|
||||
<exit>QTimeEvt_disarm(&me->timeEvt);</exit>
|
||||
<tran trig="TIMEOUT" target="../../2">
|
||||
<tran_glyph conn="2,13,3,1,20,12,-3">
|
||||
<action box="0,-2,6,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="EAT, DONE">
|
||||
<action>/* EAT or DONE must be for other Philos than this one */
|
||||
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));</action>
|
||||
<tran_glyph conn="2,17,3,-1,13">
|
||||
<action box="0,-2,14,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="TEST">
|
||||
<tran_glyph conn="2,20,3,-1,13">
|
||||
<action box="0,-2,11,4"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<state_glyph node="2,5,17,16">
|
||||
<entry box="1,2,5,2"/>
|
||||
<exit box="1,4,6,2"/>
|
||||
</state_glyph>
|
||||
</state>
|
||||
<state name="hungry">
|
||||
<entry>TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
|
||||
pe->philoNum = PHILO_ID(me);
|
||||
QACTIVE_POST(AO_Table, &pe->super, me);</entry>
|
||||
<tran trig="EAT">
|
||||
<choice target="../../../3">
|
||||
<guard>Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)</guard>
|
||||
<choice_glyph conn="15,30,5,1,7,13,-3">
|
||||
<action box="1,0,19,4"/>
|
||||
</choice_glyph>
|
||||
</choice>
|
||||
<tran_glyph conn="2,30,3,-1,13">
|
||||
<action box="0,-2,14,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="DONE">
|
||||
<action>/* DONE must be for other Philos than this one */
|
||||
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));</action>
|
||||
<tran_glyph conn="2,36,3,-1,14">
|
||||
<action box="0,-2,14,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<state_glyph node="2,23,17,16">
|
||||
<entry box="1,2,5,2"/>
|
||||
</state_glyph>
|
||||
</state>
|
||||
<state name="eating">
|
||||
<entry>QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U);</entry>
|
||||
<exit>TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
|
||||
pe->philoNum = PHILO_ID(me);
|
||||
QF_PUBLISH(&pe->super, me);</exit>
|
||||
<tran trig="TIMEOUT" target="../../1">
|
||||
<tran_glyph conn="2,51,3,1,22,-41,-5">
|
||||
<action box="0,-2,6,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="EAT, DONE">
|
||||
<action>/* EAT or DONE must be for other Philos than this one */
|
||||
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));</action>
|
||||
<tran_glyph conn="2,55,3,-1,13">
|
||||
<action box="0,-2,14,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<state_glyph node="2,41,17,18">
|
||||
<entry box="1,2,5,2"/>
|
||||
<exit box="1,4,5,2"/>
|
||||
</state_glyph>
|
||||
</state>
|
||||
<state_diagram size="37,61"/>
|
||||
</statechart>
|
||||
</class>
|
||||
<class name="Table" superclass="qpc::QActive">
|
||||
<attribute name="fork[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
|
||||
<attribute name="isHungry[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
|
||||
<statechart>
|
||||
<initial target="../1/2">
|
||||
<action>uint8_t n;
|
||||
(void)e; /* suppress the compiler warning about unused parameter */
|
||||
|
||||
QS_OBJ_DICTIONARY(&l_table);
|
||||
QS_FUN_DICTIONARY(&QHsm_top);
|
||||
QS_FUN_DICTIONARY(&Table_initial);
|
||||
QS_FUN_DICTIONARY(&Table_active);
|
||||
QS_FUN_DICTIONARY(&Table_serving);
|
||||
QS_FUN_DICTIONARY(&Table_paused);
|
||||
|
||||
QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */
|
||||
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
|
||||
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
|
||||
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
|
||||
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
|
||||
|
||||
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
|
||||
|
||||
QActive_subscribe(&me->super, DONE_SIG);
|
||||
QActive_subscribe(&me->super, PAUSE_SIG);
|
||||
QActive_subscribe(&me->super, SERVE_SIG);
|
||||
QActive_subscribe(&me->super, TEST_SIG);
|
||||
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
me->fork[n] = FREE;
|
||||
me->isHungry[n] = 0U;
|
||||
BSP_displayPhilStat(n, "thinking");
|
||||
}</action>
|
||||
<initial_glyph conn="3,3,5,1,44,18,-9">
|
||||
<action box="0,-2,6,2"/>
|
||||
</initial_glyph>
|
||||
</initial>
|
||||
<state name="active">
|
||||
<tran trig="TEST">
|
||||
<tran_glyph conn="2,11,3,-1,14">
|
||||
<action box="0,-2,11,4"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="EAT">
|
||||
<action>Q_ERROR();</action>
|
||||
<tran_glyph conn="2,15,3,-1,14">
|
||||
<action box="0,-2,10,4"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<state name="serving">
|
||||
<entry brief="give pending permissions to eat">uint8_t n;
|
||||
for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */
|
||||
if ((me->isHungry[n] != 0U)
|
||||
&& (me->fork[LEFT(n)] == FREE)
|
||||
&& (me->fork[n] == FREE))
|
||||
{
|
||||
TableEvt *te;
|
||||
|
||||
me->fork[LEFT(n)] = USED;
|
||||
me->fork[n] = USED;
|
||||
te = Q_NEW(TableEvt, EAT_SIG);
|
||||
te->philoNum = n;
|
||||
QF_PUBLISH(&te->super, me);
|
||||
me->isHungry[n] = 0U;
|
||||
BSP_displayPhilStat(n, "eating ");
|
||||
}
|
||||
}</entry>
|
||||
<tran trig="HUNGRY">
|
||||
<action>uint8_t n, m;
|
||||
|
||||
n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* phil ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
|
||||
BSP_displayPhilStat(n, "hungry ");
|
||||
m = LEFT(n);</action>
|
||||
<choice>
|
||||
<guard brief="both free">(me->fork[m] == FREE) && (me->fork[n] == FREE)</guard>
|
||||
<action>TableEvt *pe;
|
||||
me->fork[m] = USED;
|
||||
me->fork[n] = USED;
|
||||
pe = Q_NEW(TableEvt, EAT_SIG);
|
||||
pe->philoNum = n;
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
BSP_displayPhilStat(n, "eating ");</action>
|
||||
<choice_glyph conn="19,26,5,-1,10">
|
||||
<action box="1,0,10,2"/>
|
||||
</choice_glyph>
|
||||
</choice>
|
||||
<choice>
|
||||
<guard>else</guard>
|
||||
<action>me->isHungry[n] = 1U;</action>
|
||||
<choice_glyph conn="19,26,4,-1,5,10">
|
||||
<action box="1,5,6,2"/>
|
||||
</choice_glyph>
|
||||
</choice>
|
||||
<tran_glyph conn="4,26,3,-1,15">
|
||||
<action box="0,-2,8,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="DONE">
|
||||
<action>uint8_t n, m;
|
||||
TableEvt *pe;
|
||||
|
||||
n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* phil ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
|
||||
BSP_displayPhilStat(n, "thinking");
|
||||
m = LEFT(n);
|
||||
/* both forks of Phil[n] must be used */
|
||||
Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
|
||||
|
||||
me->fork[m] = FREE;
|
||||
me->fork[n] = FREE;
|
||||
m = RIGHT(n); /* check the right neighbor */
|
||||
|
||||
if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) {
|
||||
me->fork[n] = USED;
|
||||
me->fork[m] = USED;
|
||||
me->isHungry[m] = 0U;
|
||||
pe = Q_NEW(TableEvt, EAT_SIG);
|
||||
pe->philoNum = m;
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
BSP_displayPhilStat(m, "eating ");
|
||||
}
|
||||
m = LEFT(n); /* check the left neighbor */
|
||||
n = LEFT(m); /* left fork of the left neighbor */
|
||||
if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) {
|
||||
me->fork[m] = USED;
|
||||
me->fork[n] = USED;
|
||||
me->isHungry[m] = 0U;
|
||||
pe = Q_NEW(TableEvt, EAT_SIG);
|
||||
pe->philoNum = m;
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
BSP_displayPhilStat(m, "eating ");
|
||||
}</action>
|
||||
<tran_glyph conn="4,34,3,-1,15">
|
||||
<action box="0,-2,6,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="EAT">
|
||||
<action>Q_ERROR();</action>
|
||||
<tran_glyph conn="4,37,3,-1,15">
|
||||
<action box="0,-2,12,4"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="PAUSE" target="../../3">
|
||||
<tran_glyph conn="4,41,3,1,37,6,-3">
|
||||
<action box="0,-2,7,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<state_glyph node="4,19,34,24">
|
||||
<entry box="1,2,27,2"/>
|
||||
</state_glyph>
|
||||
</state>
|
||||
<state name="paused">
|
||||
<entry>BSP_displayPaused(1U);</entry>
|
||||
<exit>BSP_displayPaused(0U);</exit>
|
||||
<tran trig="SERVE" target="../../2">
|
||||
<tran_glyph conn="4,57,3,1,39,-20,-5">
|
||||
<action box="0,-2,7,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="HUNGRY">
|
||||
<action>uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* philo ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
me->isHungry[n] = 1U;
|
||||
BSP_displayPhilStat(n, "hungry ");</action>
|
||||
<tran_glyph conn="4,60,3,-1,15">
|
||||
<action box="0,-2,6,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<tran trig="DONE">
|
||||
<action>uint8_t n, m;
|
||||
|
||||
n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* phil ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
|
||||
BSP_displayPhilStat(n, "thinking");
|
||||
m = LEFT(n);
|
||||
/* both forks of Phil[n] must be used */
|
||||
Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
|
||||
|
||||
me->fork[m] = FREE;
|
||||
me->fork[n] = FREE;</action>
|
||||
<tran_glyph conn="4,63,3,-1,15">
|
||||
<action box="0,-2,6,2"/>
|
||||
</tran_glyph>
|
||||
</tran>
|
||||
<state_glyph node="4,45,34,20">
|
||||
<entry box="1,2,18,4"/>
|
||||
<exit box="1,6,18,4"/>
|
||||
</state_glyph>
|
||||
</state>
|
||||
<state_glyph node="2,5,43,62"/>
|
||||
</state>
|
||||
<state_diagram size="49,69"/>
|
||||
</statechart>
|
||||
</class>
|
||||
<attribute name="AO_Philo[N_PHILO]" type="QMActive * const" visibility="0x00" properties="0x00"/>
|
||||
<attribute name="AO_Table" type="QActive * const" visibility="0x00" properties="0x00"/>
|
||||
<operation name="Philo_ctor" type="void" visibility="0x00" properties="0x00">
|
||||
<code>uint8_t n;
|
||||
Philo *me;
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
me = &l_philo[n];
|
||||
QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial));
|
||||
QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);
|
||||
}</code>
|
||||
</operation>
|
||||
<operation name="Table_ctor" type="void" visibility="0x00" properties="0x00">
|
||||
<code>uint8_t n;
|
||||
Table *me = &l_table;
|
||||
|
||||
QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial));
|
||||
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
me->fork[n] = FREE;
|
||||
me->isHungry[n] = 0U;
|
||||
}</code>
|
||||
</operation>
|
||||
</package>
|
||||
<directory name=".">
|
||||
<file name="dpp.h">
|
||||
<text>#ifndef dpp_h
|
||||
#define dpp_h
|
||||
|
||||
enum DPPSignals {
|
||||
EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */
|
||||
DONE_SIG, /* published by Philosopher when done eating */
|
||||
PAUSE_SIG, /* published by BSP to pause serving forks */
|
||||
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 */
|
||||
|
||||
HUNGRY_SIG, /* posted direclty to Table from hungry Philo */
|
||||
TIMEOUT_SIG, /* used by Philosophers for time events */
|
||||
MAX_SIG /* the last signal */
|
||||
};
|
||||
|
||||
$declare(Events::TableEvt)
|
||||
|
||||
/* number of philosophers */
|
||||
#define N_PHILO ((uint8_t)5)
|
||||
|
||||
$declare(AOs::Philo_ctor)
|
||||
$declare(AOs::AO_Philo[N_PHILO])
|
||||
|
||||
$declare(AOs::Table_ctor)
|
||||
$declare(AOs::AO_Table)
|
||||
|
||||
#ifdef qxk_h
|
||||
void Test1_ctor(void);
|
||||
extern QXThread * const XT_Test1;
|
||||
void Test2_ctor(void);
|
||||
extern QXThread * const XT_Test2;
|
||||
#endif /* qxk_h */
|
||||
|
||||
#endif /* dpp_h */</text>
|
||||
</file>
|
||||
<file name="philo.c">
|
||||
<text>#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/* Active object class -----------------------------------------------------*/
|
||||
$declare(AOs::Philo)
|
||||
|
||||
/* Local objects -----------------------------------------------------------*/
|
||||
static Philo l_philo[N_PHILO]; /* storage for all Philos */
|
||||
|
||||
#define THINK_TIME \
|
||||
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U))
|
||||
#define EAT_TIME \
|
||||
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC)
|
||||
|
||||
/* helper macro to provide the ID of Philo "me_" */
|
||||
#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo))
|
||||
|
||||
/* Global objects ----------------------------------------------------------*/
|
||||
QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */
|
||||
&l_philo[0].super,
|
||||
&l_philo[1].super,
|
||||
&l_philo[2].super,
|
||||
&l_philo[3].super,
|
||||
&l_philo[4].super
|
||||
};
|
||||
|
||||
/* Philo definition --------------------------------------------------------*/
|
||||
$define(AOs::Philo_ctor)
|
||||
$define(AOs::Philo)</text>
|
||||
</file>
|
||||
<file name="table.c">
|
||||
<text>#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/* Active object class -----------------------------------------------------*/
|
||||
$declare(AOs::Table)
|
||||
|
||||
#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO))
|
||||
#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO))
|
||||
#define FREE ((uint8_t)0)
|
||||
#define USED ((uint8_t)1)
|
||||
|
||||
/* Local objects -----------------------------------------------------------*/
|
||||
static Table l_table; /* the single instance of the Table active object */
|
||||
|
||||
/* Global-scope objects ----------------------------------------------------*/
|
||||
QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */
|
||||
|
||||
/*..........................................................................*/
|
||||
$define(AOs::Table_ctor)
|
||||
$define(AOs::Table)</text>
|
||||
</file>
|
||||
</directory>
|
||||
</model>
|
225
examples/arm-cm/dpp_stm32f4-discovery/philo.c
Normal file
225
examples/arm-cm/dpp_stm32f4-discovery/philo.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*****************************************************************************
|
||||
* Model: dpp.qm
|
||||
* File: ./philo.c
|
||||
*
|
||||
* This code has been generated by QM tool (see state-machine.com/qm).
|
||||
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
/*${.::philo.c} ............................................................*/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/* Active object class -----------------------------------------------------*/
|
||||
|
||||
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
|
||||
#error qpc version 5.8.0 or higher required
|
||||
#endif
|
||||
|
||||
/*${AOs::Philo} ............................................................*/
|
||||
typedef struct {
|
||||
/* protected: */
|
||||
QActive super;
|
||||
|
||||
/* private: */
|
||||
QTimeEvt timeEvt;
|
||||
} Philo;
|
||||
|
||||
/* protected: */
|
||||
static QState Philo_initial(Philo * const me, QEvt const * const e);
|
||||
static QState Philo_thinking(Philo * const me, QEvt const * const e);
|
||||
static QState Philo_hungry(Philo * const me, QEvt const * const e);
|
||||
static QState Philo_eating(Philo * const me, QEvt const * const e);
|
||||
|
||||
|
||||
/* Local objects -----------------------------------------------------------*/
|
||||
static Philo l_philo[N_PHILO]; /* storage for all Philos */
|
||||
|
||||
#define THINK_TIME \
|
||||
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U))
|
||||
#define EAT_TIME \
|
||||
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC)
|
||||
|
||||
/* helper macro to provide the ID of Philo "me_" */
|
||||
#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo))
|
||||
|
||||
/* Global objects ----------------------------------------------------------*/
|
||||
QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */
|
||||
&l_philo[0].super,
|
||||
&l_philo[1].super,
|
||||
&l_philo[2].super,
|
||||
&l_philo[3].super,
|
||||
&l_philo[4].super
|
||||
};
|
||||
|
||||
/* Philo definition --------------------------------------------------------*/
|
||||
/*${AOs::Philo_ctor} .......................................................*/
|
||||
void Philo_ctor(void) {
|
||||
uint8_t n;
|
||||
Philo *me;
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
me = &l_philo[n];
|
||||
QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial));
|
||||
QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);
|
||||
}
|
||||
}
|
||||
/*${AOs::Philo} ............................................................*/
|
||||
/*${AOs::Philo::SM} ........................................................*/
|
||||
static QState Philo_initial(Philo * const me, QEvt const * const e) {
|
||||
/* ${AOs::Philo::SM::initial} */
|
||||
static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */
|
||||
(void)e; /* suppress the compiler warning about unused parameter */
|
||||
if (registered == (uint8_t)0) {
|
||||
registered = (uint8_t)1;
|
||||
|
||||
QS_OBJ_DICTIONARY(&l_philo[0]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[0].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[1]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[1].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[2]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[2].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[3]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[3].timeEvt);
|
||||
QS_OBJ_DICTIONARY(&l_philo[4]);
|
||||
QS_OBJ_DICTIONARY(&l_philo[4].timeEvt);
|
||||
|
||||
QS_FUN_DICTIONARY(&Philo_initial);
|
||||
QS_FUN_DICTIONARY(&Philo_thinking);
|
||||
QS_FUN_DICTIONARY(&Philo_hungry);
|
||||
QS_FUN_DICTIONARY(&Philo_eating);
|
||||
}
|
||||
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */
|
||||
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */
|
||||
|
||||
QActive_subscribe(&me->super, EAT_SIG);
|
||||
QActive_subscribe(&me->super, TEST_SIG);
|
||||
return Q_TRAN(&Philo_thinking);
|
||||
}
|
||||
/*${AOs::Philo::SM::thinking} ..............................................*/
|
||||
static QState Philo_thinking(Philo * const me, QEvt const * const e) {
|
||||
QState status_;
|
||||
switch (e->sig) {
|
||||
/* ${AOs::Philo::SM::thinking} */
|
||||
case Q_ENTRY_SIG: {
|
||||
QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Philo::SM::thinking} */
|
||||
case Q_EXIT_SIG: {
|
||||
QTimeEvt_disarm(&me->timeEvt);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Philo::SM::thinking::TIMEOUT} */
|
||||
case TIMEOUT_SIG: {
|
||||
status_ = Q_TRAN(&Philo_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)->philoNum != PHILO_ID(me));
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Philo::SM::thinking::TEST} */
|
||||
case TEST_SIG: {
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
status_ = Q_SUPER(&QHsm_top);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
/*${AOs::Philo::SM::hungry} ................................................*/
|
||||
static QState Philo_hungry(Philo * const me, QEvt const * const e) {
|
||||
QState status_;
|
||||
switch (e->sig) {
|
||||
/* ${AOs::Philo::SM::hungry} */
|
||||
case Q_ENTRY_SIG: {
|
||||
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
|
||||
pe->philoNum = PHILO_ID(me);
|
||||
QACTIVE_POST(AO_Table, &pe->super, me);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Philo::SM::hungry::EAT} */
|
||||
case EAT_SIG: {
|
||||
/* ${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */
|
||||
if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) {
|
||||
status_ = Q_TRAN(&Philo_eating);
|
||||
}
|
||||
else {
|
||||
status_ = Q_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)->philoNum != PHILO_ID(me));
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
status_ = Q_SUPER(&QHsm_top);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
/*${AOs::Philo::SM::eating} ................................................*/
|
||||
static QState Philo_eating(Philo * const me, QEvt const * const e) {
|
||||
QState status_;
|
||||
switch (e->sig) {
|
||||
/* ${AOs::Philo::SM::eating} */
|
||||
case Q_ENTRY_SIG: {
|
||||
QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Philo::SM::eating} */
|
||||
case Q_EXIT_SIG: {
|
||||
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
|
||||
pe->philoNum = PHILO_ID(me);
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Philo::SM::eating::TIMEOUT} */
|
||||
case TIMEOUT_SIG: {
|
||||
status_ = Q_TRAN(&Philo_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)->philoNum != PHILO_ID(me));
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
status_ = Q_SUPER(&QHsm_top);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
|
24
examples/arm-cm/dpp_stm32f4-discovery/qk/arm/README.txt
Normal file
24
examples/arm-cm/dpp_stm32f4-discovery/qk/arm/README.txt
Normal file
@ -0,0 +1,24 @@
|
||||
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/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
|
||||
numberical value of the heap size (for most embedded projects
|
||||
yyy should be 0, as the using the heap is not recommended).
|
||||
|
||||
|
1258
examples/arm-cm/dpp_stm32f4-discovery/qk/arm/dpp-qk.uvoptx
Normal file
1258
examples/arm-cm/dpp_stm32f4-discovery/qk/arm/dpp-qk.uvoptx
Normal file
File diff suppressed because it is too large
Load Diff
1913
examples/arm-cm/dpp_stm32f4-discovery/qk/arm/dpp-qk.uvprojx
Normal file
1913
examples/arm-cm/dpp_stm32f4-discovery/qk/arm/dpp-qk.uvprojx
Normal file
File diff suppressed because it is too large
Load Diff
534
examples/arm-cm/dpp_stm32f4-discovery/qk/bsp.c
Normal file
534
examples/arm-cm/dpp_stm32f4-discovery/qk/bsp.c
Normal file
@ -0,0 +1,534 @@
|
||||
/*****************************************************************************
|
||||
* Product: "DPP" example on STM32F4-Discovery board, preemptive QK kernel
|
||||
* Last Updated for Version: 5.9.1
|
||||
* Date of the Last Update: 2017-06-01
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#include "stm32f4xx.h" /* CMSIS-compliant header file for the MCU used */
|
||||
#include "stm32f4xx_exti.h"
|
||||
#include "stm32f4xx_gpio.h"
|
||||
#include "stm32f4xx_rcc.h"
|
||||
#include "stm32f4xx_usart.h"
|
||||
/* add other drivers if necessary... */
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority().
|
||||
* DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE!
|
||||
*/
|
||||
enum KernelUnawareISRs { /* see NOTE00 */
|
||||
USART2_PRIO,
|
||||
/* ... */
|
||||
MAX_KERNEL_UNAWARE_CMSIS_PRI /* keep always last */
|
||||
};
|
||||
/* "kernel-unaware" interrupts can't overlap "kernel-aware" interrupts */
|
||||
Q_ASSERT_COMPILE(MAX_KERNEL_UNAWARE_CMSIS_PRI <= QF_AWARE_ISR_CMSIS_PRI);
|
||||
|
||||
enum KernelAwareISRs {
|
||||
SYSTICK_PRIO = QF_AWARE_ISR_CMSIS_PRI, /* see NOTE00 */
|
||||
/* ... */
|
||||
MAX_KERNEL_AWARE_CMSIS_PRI /* keep always last */
|
||||
};
|
||||
/* "kernel-aware" interrupts should not overlap the PendSV priority */
|
||||
Q_ASSERT_COMPILE(MAX_KERNEL_AWARE_CMSIS_PRI <= (0xFF >>(8-__NVIC_PRIO_BITS)));
|
||||
|
||||
/* ISRs defined in this BSP ------------------------------------------------*/
|
||||
void SysTick_Handler(void);
|
||||
void USART2_IRQHandler(void);
|
||||
|
||||
/* Local-scope defines -----------------------------------------------------*/
|
||||
#define LED_GPIO_PORT GPIOD
|
||||
#define LED_GPIO_CLK RCC_AHB1Periph_GPIOD
|
||||
|
||||
#define LED4_PIN GPIO_Pin_12
|
||||
#define LED3_PIN GPIO_Pin_13
|
||||
#define LED5_PIN GPIO_Pin_14
|
||||
#define LED6_PIN GPIO_Pin_15
|
||||
|
||||
#define BTN_GPIO_PORT GPIOA
|
||||
#define BTN_GPIO_CLK RCC_AHB1Periph_GPIOA
|
||||
#define BTN_B1 GPIO_Pin_0
|
||||
|
||||
static uint32_t l_rnd; /* random seed */
|
||||
static QMutex l_rndMutex; /* mutex to protect the random seed */
|
||||
|
||||
#ifdef Q_SPY
|
||||
static QSTimeCtr QS_tickTime_;
|
||||
static QSTimeCtr QS_tickPeriod_;
|
||||
|
||||
/* event-source identifiers used for tracing */
|
||||
static uint8_t const l_SysTick;
|
||||
|
||||
enum AppRecords { /* application-specific trace records */
|
||||
PHILO_STAT = QS_USER,
|
||||
COMMAND_STAT
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ISRs used in this project ===============================================*/
|
||||
void SysTick_Handler(void) {
|
||||
/* state of the button debouncing, see below */
|
||||
static struct ButtonsDebouncing {
|
||||
uint32_t depressed;
|
||||
uint32_t previous;
|
||||
} buttons = { 0U, 0U };
|
||||
uint32_t current;
|
||||
uint32_t tmp;
|
||||
|
||||
QK_ISR_ENTRY(); /* inform QK about entering an ISR */
|
||||
|
||||
#ifdef Q_SPY
|
||||
{
|
||||
tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */
|
||||
QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */
|
||||
}
|
||||
#endif
|
||||
|
||||
QF_TICK_X(0U, &l_SysTick);
|
||||
|
||||
/* Perform the debouncing of buttons. The algorithm for debouncing
|
||||
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
|
||||
* and Michael Barr, page 71.
|
||||
*/
|
||||
current = BTN_GPIO_PORT->IDR; /* read BTN GPIO */
|
||||
tmp = buttons.depressed; /* save the debounced 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 */
|
||||
if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */
|
||||
if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */
|
||||
static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U};
|
||||
QF_PUBLISH(&pauseEvt, &l_SysTick);
|
||||
}
|
||||
else { /* the button is released */
|
||||
static QEvt const serveEvt = { SERVE_SIG, 0U, 0U};
|
||||
QF_PUBLISH(&serveEvt, &l_SysTick);
|
||||
}
|
||||
}
|
||||
|
||||
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 USART2_IRQHandler(void) {
|
||||
if ((USART2->SR & USART_SR_RXNE) != 0) {
|
||||
uint32_t b = USART2->DR;
|
||||
QS_RX_PUT(b);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void USART2_IRQHandler(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* BSP functions ===========================================================*/
|
||||
void BSP_init(void) {
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
*/
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* configure the FPU usage by choosing one of the options... */
|
||||
#if 1
|
||||
/* OPTION 1:
|
||||
* Use the automatic FPU state preservation and the FPU lazy stacking.
|
||||
*
|
||||
* NOTE:
|
||||
* Use the following setting when FPU is used in more than one task or
|
||||
* in any ISRs. This setting is the safest and recommended, but requires
|
||||
* extra stack space and CPU cycles.
|
||||
*/
|
||||
FPU->FPCCR |= (1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos);
|
||||
#else
|
||||
/* OPTION 2:
|
||||
* Do NOT to use the automatic FPU state preservation and
|
||||
* do NOT to use the FPU lazy stacking.
|
||||
*
|
||||
* NOTE:
|
||||
* Use the following setting when FPU is used in ONE task only and not
|
||||
* in any ISR. This setting is very efficient, but if more than one task
|
||||
* (or ISR) start using the FPU, this can lead to corruption of the
|
||||
* FPU registers. This option should be used with CAUTION.
|
||||
*/
|
||||
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
|
||||
#endif
|
||||
|
||||
GPIO_InitTypeDef GPIO_struct;
|
||||
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
*/
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* Explictily Disable the automatic FPU state preservation as well as
|
||||
* the FPU lazy stacking
|
||||
*/
|
||||
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
|
||||
|
||||
/* Initialize thr port for the LEDs */
|
||||
RCC_AHB1PeriphClockCmd(LED_GPIO_CLK , ENABLE);
|
||||
|
||||
/* GPIO Configuration for the LEDs... */
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED3_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED4_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED5_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED6_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */
|
||||
|
||||
/* Initialize thr port for Button */
|
||||
RCC_AHB1PeriphClockCmd(BTN_GPIO_CLK , ENABLE);
|
||||
|
||||
/* GPIO Configuration for the Button... */
|
||||
GPIO_struct.GPIO_Pin = BTN_B1;
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(BTN_GPIO_PORT, &GPIO_struct);
|
||||
|
||||
/* seed the random number generator */
|
||||
BSP_randomSeed(1234U);
|
||||
|
||||
if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */
|
||||
Q_ERROR();
|
||||
}
|
||||
QS_OBJ_DICTIONARY(&l_SysTick);
|
||||
QS_USR_DICTIONARY(PHILO_STAT);
|
||||
QS_USR_DICTIONARY(COMMAND_STAT);
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPhilStat(uint8_t n, char const *stat) {
|
||||
(void)n;
|
||||
|
||||
if (stat[0] == 'h') {
|
||||
LED_GPIO_PORT->BSRRL = LED3_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */
|
||||
}
|
||||
if (stat[0] == 'e') {
|
||||
LED_GPIO_PORT->BSRRL = LED5_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED on */
|
||||
}
|
||||
|
||||
QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */
|
||||
QS_U8(1, n); /* Philosopher number */
|
||||
QS_STR(stat); /* Philosopher status */
|
||||
QS_END() /* application-specific record end */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPaused(uint8_t paused) {
|
||||
if (paused) {
|
||||
LED_GPIO_PORT->BSRRL = LED4_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED on */
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */
|
||||
uint32_t rnd;
|
||||
|
||||
/* exercise the FPU with some floating point computations */
|
||||
/* NOTE: this code can be only called from a task that created with
|
||||
* the option OS_TASK_OPT_SAVE_FP.
|
||||
*/
|
||||
float volatile x = 3.1415926F;
|
||||
x = x + 2.7182818F;
|
||||
|
||||
QMutex_lock(&l_rndMutex); /* lock the random-seed mutex */
|
||||
/* "Super-Duper" Linear Congruential Generator (LCG)
|
||||
* LCG(2^32, 3*7*11*13*23, 0, seed)
|
||||
*/
|
||||
rnd = l_rnd * (3U*7U*11U*13U*23U);
|
||||
l_rnd = rnd; /* set for the next time */
|
||||
QMutex_unlock(&l_rndMutex); /* unlock the random-seed mutex */
|
||||
|
||||
return (rnd >> 8);
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_randomSeed(uint32_t seed) {
|
||||
l_rnd = seed;
|
||||
QMutex_init(&l_rndMutex, N_PHILO); /* ceiling == max Philo priority */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_terminate(int16_t result) {
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* QF callbacks ============================================================*/
|
||||
void QF_onStartup(void) {
|
||||
/* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */
|
||||
SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
|
||||
|
||||
/* assing all priority bits for preemption-prio. and none to sub-prio. */
|
||||
NVIC_SetPriorityGrouping(0U);
|
||||
|
||||
/* set priorities of ALL ISRs used in the system, see NOTE00
|
||||
*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority().
|
||||
* DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE!
|
||||
*/
|
||||
NVIC_SetPriority(USART2_IRQn, USART2_PRIO);
|
||||
NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO);
|
||||
/* ... */
|
||||
|
||||
/* enable IRQs... */
|
||||
#ifdef Q_SPY
|
||||
NVIC_EnableIRQ(USART2_IRQn); /* USART2 interrupt used for QS-RX */
|
||||
#endif
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QF_onCleanup(void) {
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QK_onIdle(void) {
|
||||
QF_INT_DISABLE();
|
||||
LED_GPIO_PORT->BSRRL = LED6_PIN; /* turn LED on */
|
||||
__NOP(); /* wait a little to actually see the LED glow */
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */
|
||||
QF_INT_ENABLE();
|
||||
|
||||
#ifdef Q_SPY
|
||||
QS_rxParse(); /* parse all the received bytes */
|
||||
|
||||
if ((USART2->SR & USART_FLAG_TXE) != 0) { /* is TXE empty? */
|
||||
uint16_t b;
|
||||
|
||||
QF_INT_DISABLE();
|
||||
b = QS_getByte();
|
||||
QF_INT_ENABLE();
|
||||
|
||||
if (b != QS_EOD) { /* not End-Of-Data? */
|
||||
USART2->DR = (b & 0xFFU); /* 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-M3 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
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
void Q_onAssert(char const *module, int loc) {
|
||||
/*
|
||||
* NOTE: add here your application-specific error handling
|
||||
*/
|
||||
(void)module;
|
||||
(void)loc;
|
||||
QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/* QS callbacks ============================================================*/
|
||||
#ifdef Q_SPY
|
||||
/*..........................................................................*/
|
||||
uint8_t QS_onStartup(void const *arg) {
|
||||
static uint8_t qsBuf[2*1024]; /* buffer for QS-TX channel */
|
||||
static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */
|
||||
GPIO_InitTypeDef GPIO_struct;
|
||||
USART_InitTypeDef USART_struct;
|
||||
|
||||
(void)arg; /* avoid the "unused parameter" compiler warning */
|
||||
QS_initBuf(qsBuf, sizeof(qsBuf));
|
||||
QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf));
|
||||
|
||||
/* enable peripheral clock for USART2 */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
|
||||
/* GPIOA clock enable */
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||
|
||||
/* GPIOA Configuration: USART2 TX on PA2 and RX on PA3 */
|
||||
GPIO_struct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP ;
|
||||
GPIO_Init(GPIOA, &GPIO_struct);
|
||||
|
||||
/* Connect USART2 pins to AF2 */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); /* TX = PA2 */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); /* RX = PA3 */
|
||||
|
||||
USART_struct.USART_BaudRate = 115200;
|
||||
USART_struct.USART_WordLength = USART_WordLength_8b;
|
||||
USART_struct.USART_StopBits = USART_StopBits_1;
|
||||
USART_struct.USART_Parity = USART_Parity_No;
|
||||
USART_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
USART_Init(USART2, &USART_struct);
|
||||
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* enable RX interrupt */
|
||||
USART_Cmd(USART2, ENABLE); /* enable USART2 */
|
||||
|
||||
QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC;
|
||||
QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */
|
||||
|
||||
/* setup the QS filters... */
|
||||
QS_FILTER_ON(QS_SM_RECORDS); /* state machine records */
|
||||
QS_FILTER_ON(QS_AO_RECORDS); /* active object records */
|
||||
QS_FILTER_ON(QS_UA_RECORDS); /* all user records */
|
||||
|
||||
return (uint8_t)1; /* return success */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onCleanup(void) {
|
||||
}
|
||||
/*..........................................................................*/
|
||||
QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */
|
||||
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */
|
||||
return QS_tickTime_ - (QSTimeCtr)SysTick->VAL;
|
||||
}
|
||||
else { /* the rollover occured, but the SysTick_ISR did not run yet */
|
||||
return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL;
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onFlush(void) {
|
||||
uint16_t b;
|
||||
|
||||
QF_INT_DISABLE();
|
||||
while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */
|
||||
QF_INT_ENABLE();
|
||||
while ((USART2->SR & USART_FLAG_TXE) == 0) { /* while TXE not empty */
|
||||
}
|
||||
USART2->DR = (b & 0xFFU); /* put into the DR register */
|
||||
QF_INT_DISABLE();
|
||||
}
|
||||
QF_INT_ENABLE();
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onReset(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onCommand(uint8_t cmdId,
|
||||
uint32_t param1, uint32_t param2, uint32_t param3)
|
||||
{
|
||||
void assert_failed(char const *module, int loc);
|
||||
(void)cmdId;
|
||||
(void)param1;
|
||||
(void)param2;
|
||||
(void)param3;
|
||||
QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */
|
||||
QS_U8(2, cmdId);
|
||||
QS_U32(8, param1);
|
||||
QS_U32(8, param2);
|
||||
QS_U32(8, param3);
|
||||
QS_END()
|
||||
|
||||
if (cmdId == 10U) {
|
||||
Q_ERROR();
|
||||
}
|
||||
else if (cmdId == 11U) {
|
||||
assert_failed("QS_onCommand", 123);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Q_SPY */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*****************************************************************************
|
||||
* NOTE00:
|
||||
* 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.
|
||||
*
|
||||
* NOTE01:
|
||||
* 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.
|
||||
*
|
||||
* NOTE02:
|
||||
* One of the LEDs is used to visualize the idle loop activity. The brightness
|
||||
* of the LED is proportional to the frequency of invcations 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.
|
||||
*/
|
328
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/Makefile
Normal file
328
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/Makefile
Normal file
@ -0,0 +1,328 @@
|
||||
##############################################################################
|
||||
# Product: DPP on STM32F4-Discovery, QK, GNU-ARM gnutoolchains.com/arm-eabi
|
||||
# Last Updated for Version: 5.9.1
|
||||
# Date of the Last Update: 2017-06-01
|
||||
#
|
||||
# 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
|
||||
##############################################################################
|
||||
# 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 := dpp-qk
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# project directories
|
||||
#
|
||||
|
||||
# location of the QP/C framework (if not provided in an environemnt var.)
|
||||
ifeq ($(QPC),)
|
||||
QPC := ../../../../..
|
||||
endif
|
||||
|
||||
# QP port used in this project
|
||||
QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu
|
||||
|
||||
# list of all source directories used by this project
|
||||
VPATH = \
|
||||
.. \
|
||||
../.. \
|
||||
$(QPC)/src/qf \
|
||||
$(QPC)/src/qk \
|
||||
$(QPC)/src/qs \
|
||||
$(QP_PORT_DIR) \
|
||||
$(QPC)/3rd_party/stm32f4-discovery \
|
||||
$(QPC)/3rd_party/stm32f4-discovery/src \
|
||||
$(QPC)/3rd_party/stm32f4-discovery/gnu
|
||||
|
||||
# list of all include directories needed by this project
|
||||
INCLUDES = \
|
||||
-I../.. \
|
||||
-I$(QPC)/include \
|
||||
-I$(QPC)/src \
|
||||
-I$(QP_PORT_DIR) \
|
||||
-I$(QPC)/3rd_party/CMSIS/Include \
|
||||
-I$(QPC)/3rd_party/stm32f4-discovery \
|
||||
-I$(QPC)/3rd_party/stm32f4-discovery/inc
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# files
|
||||
#
|
||||
|
||||
# assembler source files
|
||||
ASM_SRCS :=
|
||||
|
||||
# C source files
|
||||
C_SRCS := \
|
||||
bsp.c \
|
||||
main.c \
|
||||
philo.c \
|
||||
table.c \
|
||||
system_stm32f4xx.c \
|
||||
startup_stm32f4xx.c \
|
||||
stm32f4xx_gpio.c \
|
||||
stm32f4xx_rcc.c \
|
||||
stm32f4xx_usart.c
|
||||
|
||||
# C++ source files
|
||||
CPP_SRCS :=
|
||||
|
||||
OUTPUT := $(PROJECT)
|
||||
LD_SCRIPT := $(PROJECT).ld
|
||||
|
||||
QP_SRCS := \
|
||||
qep_hsm.c \
|
||||
qep_msm.c \
|
||||
qf_act.c \
|
||||
qf_actq.c \
|
||||
qf_defer.c \
|
||||
qf_dyn.c \
|
||||
qf_mem.c \
|
||||
qf_ps.c \
|
||||
qf_qact.c \
|
||||
qf_qeq.c \
|
||||
qf_qmact.c \
|
||||
qf_time.c \
|
||||
qk.c \
|
||||
qk_mutex.c
|
||||
|
||||
QP_ASMS := \
|
||||
qk_port.s
|
||||
|
||||
QS_SRCS := \
|
||||
qs.c \
|
||||
qs_rx.c \
|
||||
qs_fp.c
|
||||
|
||||
LIB_DIRS :=
|
||||
LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES :=
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!)
|
||||
# ARM_FPU: [ | vfp]
|
||||
# FLOAT_ABI: [ | soft | softfp | hard]
|
||||
#
|
||||
ARM_CPU := -mcpu=cortex-m4
|
||||
ARM_ARCH := 7 # NOTE: must match the ARM_CPU!
|
||||
ARM_FPU := -mfpu=vfp
|
||||
FLOAT_ABI := -mfloat-abi=softfp
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-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-eabi-gcc
|
||||
CPP := $(GNU_ARM)/bin/arm-eabi-g++
|
||||
AS := $(GNU_ARM)/bin/arm-eabi-as
|
||||
LINK := $(GNU_ARM)/bin/arm-eabi-gcc
|
||||
BIN := $(GNU_ARM)/bin/arm-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 soruces...
|
||||
C_SRCS += $(QP_SRCS)
|
||||
ASM_SRCS += $(QP_ASMS)
|
||||
|
||||
# add the pre-defined symbol for ARM architecture
|
||||
DEFINES += -D__ARM_ARCH=$(ARM_ARCH)
|
||||
ASM_CPU += -defsym=__ARM_ARCH=$(ARM_ARCH)
|
||||
|
||||
# add the pre-defined symbol __FPU_PRESENT if needed...
|
||||
ifneq (,$(ARM_FPU))
|
||||
DEFINES += -D__FPU_PRESENT
|
||||
ASM_FPU += -defsym=__FPU_PRESENT=1
|
||||
endif
|
||||
|
||||
ifeq (rel, $(CONF)) # Release configuration ..................................
|
||||
|
||||
BIN_DIR := rel
|
||||
|
||||
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
|
||||
|
||||
CFLAGS = $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
|
||||
|
||||
CPPFLAGS = $(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
|
||||
|
||||
C_SRCS += $(QS_SRCS)
|
||||
|
||||
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
|
||||
|
||||
CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O $(INCLUDES) $(DEFINES) -DQ_SPY
|
||||
|
||||
CPPFLAGS = -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 = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O $(INCLUDES) $(DEFINES)
|
||||
|
||||
CPPFLAGS = -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 -nostdlib \
|
||||
-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)
|
||||
$(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -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) -c $< -o $@
|
||||
|
||||
$(BIN_DIR)/%.o : %.cpp
|
||||
$(CPP) $(CPPFLAGS) -c $< -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)
|
71
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/README.txt
Normal file
71
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/README.txt
Normal file
@ -0,0 +1,71 @@
|
||||
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 recommened 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 used in this project is located in the "3rd_party" folder
|
||||
in the following location:
|
||||
|
||||
3rd_party\<board>\gcc\startup_<mcu>.c
|
||||
|
||||
The file startup_<mcu>.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.
|
||||
***
|
135
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/dpp-qk.ld
Normal file
135
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/dpp-qk.ld
Normal file
@ -0,0 +1,135 @@
|
||||
/*****************************************************************************
|
||||
* Product: Linker script for STM32F407VG, GNU-ARM linker
|
||||
* Last Updated for Version: 5.9.1
|
||||
* Date of the Last Update: 2017-06-01
|
||||
*
|
||||
* 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 Tiva TM4C123GH6PM */
|
||||
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
/* The size of the stack used by the application. NOTE: you need to adjust */
|
||||
STACK_SIZE = 1024;
|
||||
|
||||
/* 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
|
||||
|
||||
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 ( * )
|
||||
}
|
||||
}
|
33
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/flash.bat
Normal file
33
examples/arm-cm/dpp_stm32f4-discovery/qk/gnu/flash.bat
Normal file
@ -0,0 +1,33 @@
|
||||
::============================================================================
|
||||
:: Batch file to load the DPP program to the flash of STM32 boards
|
||||
::
|
||||
:: NOTE: requires the ST-LINK utlity from ST, see:
|
||||
:: http://www.st.com/en/embedded-software/stsw-link004.html
|
||||
::
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
@echo Load the program to the flash of STM32 board
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set STLINK="C:\tools\ST\ST-LINK\ST-LINK Utility\ST-LINK_CLI.exe"
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
if [%1] NEQ [] set BUILD_DIR=%1
|
||||
@echo on
|
||||
|
||||
%STLINK% -P %BUILD_DIR%\dpp-qk.bin 0x08000000
|
||||
|
||||
@echo.
|
||||
@echo.
|
||||
@echo Reset the target to start running your program!
|
||||
|
||||
@echo off
|
||||
endlocal
|
4213
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.ewd
Normal file
4213
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.ewd
Normal file
File diff suppressed because it is too large
Load Diff
3203
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.ewp
Normal file
3203
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.ewp
Normal file
File diff suppressed because it is too large
Load Diff
10
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.eww
Normal file
10
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.eww
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\dpp-qk.ewp</path>
|
||||
</project>
|
||||
<batchBuild/>
|
||||
</workspace>
|
||||
|
||||
|
35
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.icf
Normal file
35
examples/arm-cm/dpp_stm32f4-discovery/qk/iar/dpp-qk.icf
Normal file
@ -0,0 +1,35 @@
|
||||
/*###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__ = 0x08000000;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 1024;
|
||||
define symbol __ICFEDIT_size_heap__ = 0;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __region_RAM1_start__ = 0x10000000;
|
||||
define symbol __region_RAM1_end__ = 0x1000FFFF;
|
||||
|
||||
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 region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_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 in RAM_region { readwrite,
|
||||
block CSTACK, block HEAP };
|
||||
place in RAM1_region { section .sram };
|
93
examples/arm-cm/dpp_stm32f4-discovery/qk/main.c
Normal file
93
examples/arm-cm/dpp_stm32f4-discovery/qk/main.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
* Product: DPP example
|
||||
* Last Updated for Version: 5.9.0
|
||||
* Date of the Last Update: 2017-03-13
|
||||
*
|
||||
* Q u a n t u m L e a P s
|
||||
* ---------------------------
|
||||
* innovating embedded systems
|
||||
*
|
||||
* Copyright (C) 2005-2017 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
static QTicker l_ticker0;
|
||||
QActive *the_Ticker0 = &l_ticker0;
|
||||
|
||||
/*..........................................................................*/
|
||||
int main() {
|
||||
static QEvt const *tableQueueSto[N_PHILO];
|
||||
static QEvt const *philoQueueSto[N_PHILO][N_PHILO];
|
||||
static QSubscrList subscrSto[MAX_PUB_SIG];
|
||||
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */
|
||||
uint8_t n;
|
||||
|
||||
Philo_ctor(); /* instantiate all Philosopher active objects */
|
||||
Table_ctor(); /* instantiate the Table active object */
|
||||
QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */
|
||||
|
||||
QF_init(); /* initialize the framework and the underlying RT kernel */
|
||||
BSP_init(); /* initialize the Board Support Package */
|
||||
|
||||
/* object dictionaries... */
|
||||
QS_OBJ_DICTIONARY(smlPoolSto);
|
||||
QS_OBJ_DICTIONARY(tableQueueSto);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[0]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[1]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[2]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[3]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[4]);
|
||||
|
||||
/* initialize publish-subscribe... */
|
||||
QF_psInit(subscrSto, Q_DIM(subscrSto));
|
||||
|
||||
/* initialize event pools... */
|
||||
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
|
||||
|
||||
QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0);
|
||||
|
||||
/* start the active objects... */
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
QACTIVE_START(AO_Philo[n], /* AO to start */
|
||||
(uint_fast8_t)(n + 2), /* QP priority of the AO */
|
||||
philoQueueSto[n], /* event queue storage */
|
||||
Q_DIM(philoQueueSto[n]), /* queue length [events] */
|
||||
(void *)0, /* stack storage (not used) */
|
||||
0U, /* size of the stack [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
}
|
||||
QACTIVE_START(AO_Table, /* AO to start */
|
||||
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */
|
||||
tableQueueSto, /* event queue storage */
|
||||
Q_DIM(tableQueueSto), /* queue length [events] */
|
||||
(void *)0, /* stack storage (not used) */
|
||||
0U, /* size of the stack [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
|
||||
return QF_run(); /* run the QF application */
|
||||
}
|
||||
|
24
examples/arm-cm/dpp_stm32f4-discovery/qv/arm/README.txt
Normal file
24
examples/arm-cm/dpp_stm32f4-discovery/qv/arm/README.txt
Normal file
@ -0,0 +1,24 @@
|
||||
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/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
|
||||
numberical value of the heap size (for most embedded projects
|
||||
yyy should be 0, as the using the heap is not recommended).
|
||||
|
||||
|
1246
examples/arm-cm/dpp_stm32f4-discovery/qv/arm/dpp-qv.uvoptx
Normal file
1246
examples/arm-cm/dpp_stm32f4-discovery/qv/arm/dpp-qv.uvoptx
Normal file
File diff suppressed because it is too large
Load Diff
1898
examples/arm-cm/dpp_stm32f4-discovery/qv/arm/dpp-qv.uvprojx
Normal file
1898
examples/arm-cm/dpp_stm32f4-discovery/qv/arm/dpp-qv.uvprojx
Normal file
File diff suppressed because it is too large
Load Diff
524
examples/arm-cm/dpp_stm32f4-discovery/qv/bsp.c
Normal file
524
examples/arm-cm/dpp_stm32f4-discovery/qv/bsp.c
Normal file
@ -0,0 +1,524 @@
|
||||
/*****************************************************************************
|
||||
* Product: "DPP" example on STM32F4-Discovery board, cooperative QV kernel
|
||||
* Last Updated for Version: 5.9.1
|
||||
* Date of the Last Update: 2017-06-01
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#include "stm32f4xx.h" /* CMSIS-compliant header file for the MCU used */
|
||||
#include "stm32f4xx_exti.h"
|
||||
#include "stm32f4xx_gpio.h"
|
||||
#include "stm32f4xx_rcc.h"
|
||||
#include "stm32f4xx_usart.h"
|
||||
/* add other drivers if necessary... */
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority().
|
||||
* DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE!
|
||||
*/
|
||||
enum KernelUnawareISRs { /* see NOTE00 */
|
||||
USART2_PRIO,
|
||||
/* ... */
|
||||
MAX_KERNEL_UNAWARE_CMSIS_PRI /* keep always last */
|
||||
};
|
||||
/* "kernel-unaware" interrupts can't overlap "kernel-aware" interrupts */
|
||||
Q_ASSERT_COMPILE(MAX_KERNEL_UNAWARE_CMSIS_PRI <= QF_AWARE_ISR_CMSIS_PRI);
|
||||
|
||||
enum KernelAwareISRs {
|
||||
SYSTICK_PRIO = QF_AWARE_ISR_CMSIS_PRI, /* see NOTE00 */
|
||||
/* ... */
|
||||
MAX_KERNEL_AWARE_CMSIS_PRI /* keep always last */
|
||||
};
|
||||
/* "kernel-aware" interrupts should not overlap the PendSV priority */
|
||||
Q_ASSERT_COMPILE(MAX_KERNEL_AWARE_CMSIS_PRI <= (0xFF >>(8-__NVIC_PRIO_BITS)));
|
||||
|
||||
/* ISRs defined in this BSP ------------------------------------------------*/
|
||||
void SysTick_Handler(void);
|
||||
void USART2_IRQHandler(void);
|
||||
|
||||
/* Local-scope defines -----------------------------------------------------*/
|
||||
#define LED_GPIO_PORT GPIOD
|
||||
#define LED_GPIO_CLK RCC_AHB1Periph_GPIOD
|
||||
|
||||
#define LED4_PIN GPIO_Pin_12
|
||||
#define LED3_PIN GPIO_Pin_13
|
||||
#define LED5_PIN GPIO_Pin_14
|
||||
#define LED6_PIN GPIO_Pin_15
|
||||
|
||||
#define BTN_GPIO_PORT GPIOA
|
||||
#define BTN_GPIO_CLK RCC_AHB1Periph_GPIOA
|
||||
#define BTN_B1 GPIO_Pin_0
|
||||
|
||||
static uint32_t l_rnd; /* random seed */
|
||||
|
||||
#ifdef Q_SPY
|
||||
static QSTimeCtr QS_tickTime_;
|
||||
static QSTimeCtr QS_tickPeriod_;
|
||||
|
||||
/* event-source identifiers used for tracing */
|
||||
static uint8_t const l_SysTick;
|
||||
|
||||
enum AppRecords { /* application-specific trace records */
|
||||
PHILO_STAT = QS_USER,
|
||||
COMMAND_STAT
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ISRs used in this project ===============================================*/
|
||||
void SysTick_Handler(void) {
|
||||
/* state of the button debouncing, see below */
|
||||
static struct ButtonsDebouncing {
|
||||
uint32_t depressed;
|
||||
uint32_t previous;
|
||||
} buttons = { 0U, 0U };
|
||||
uint32_t current;
|
||||
uint32_t tmp;
|
||||
|
||||
#ifdef Q_SPY
|
||||
{
|
||||
tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */
|
||||
QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */
|
||||
}
|
||||
#endif
|
||||
|
||||
QF_TICK_X(0U, &l_SysTick);
|
||||
|
||||
/* Perform the debouncing of buttons. The algorithm for debouncing
|
||||
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
|
||||
* and Michael Barr, page 71.
|
||||
*/
|
||||
current = BTN_GPIO_PORT->IDR; /* read BTN GPIO */
|
||||
tmp = buttons.depressed; /* save the debounced 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 */
|
||||
if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */
|
||||
if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */
|
||||
static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U};
|
||||
QF_PUBLISH(&pauseEvt, &l_SysTick);
|
||||
}
|
||||
else { /* the button is released */
|
||||
static QEvt const serveEvt = { SERVE_SIG, 0U, 0U};
|
||||
QF_PUBLISH(&serveEvt, &l_SysTick);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
#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 USART2_IRQHandler(void) {
|
||||
if ((USART2->SR & USART_SR_RXNE) != 0) {
|
||||
uint32_t b = USART2->DR;
|
||||
QS_RX_PUT(b);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void USART2_IRQHandler(void) {}
|
||||
#endif
|
||||
|
||||
/* BSP functions ===========================================================*/
|
||||
void BSP_init(void) {
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
*/
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* configure the FPU usage by choosing one of the options... */
|
||||
#if 1
|
||||
/* OPTION 1:
|
||||
* Use the automatic FPU state preservation and the FPU lazy stacking.
|
||||
*
|
||||
* NOTE:
|
||||
* Use the following setting when FPU is used in more than one task or
|
||||
* in any ISRs. This setting is the safest and recommended, but requires
|
||||
* extra stack space and CPU cycles.
|
||||
*/
|
||||
FPU->FPCCR |= (1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos);
|
||||
#else
|
||||
/* OPTION 2:
|
||||
* Do NOT to use the automatic FPU state preservation and
|
||||
* do NOT to use the FPU lazy stacking.
|
||||
*
|
||||
* NOTE:
|
||||
* Use the following setting when FPU is used in ONE task only and not
|
||||
* in any ISR. This setting is very efficient, but if more than one task
|
||||
* (or ISR) start using the FPU, this can lead to corruption of the
|
||||
* FPU registers. This option should be used with CAUTION.
|
||||
*/
|
||||
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
|
||||
#endif
|
||||
|
||||
GPIO_InitTypeDef GPIO_struct;
|
||||
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
*/
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* Explictily Disable the automatic FPU state preservation as well as
|
||||
* the FPU lazy stacking
|
||||
*/
|
||||
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
|
||||
|
||||
/* Initialize thr port for the LEDs */
|
||||
RCC_AHB1PeriphClockCmd(LED_GPIO_CLK , ENABLE);
|
||||
|
||||
/* GPIO Configuration for the LEDs... */
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED3_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED4_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED5_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED6_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */
|
||||
|
||||
/* Initialize thr port for Button */
|
||||
RCC_AHB1PeriphClockCmd(BTN_GPIO_CLK , ENABLE);
|
||||
|
||||
/* GPIO Configuration for the Button... */
|
||||
GPIO_struct.GPIO_Pin = BTN_B1;
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(BTN_GPIO_PORT, &GPIO_struct);
|
||||
|
||||
/* seed the random number generator */
|
||||
BSP_randomSeed(1234U);
|
||||
|
||||
if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */
|
||||
Q_ERROR();
|
||||
}
|
||||
QS_OBJ_DICTIONARY(&l_SysTick);
|
||||
QS_USR_DICTIONARY(PHILO_STAT);
|
||||
QS_USR_DICTIONARY(COMMAND_STAT);
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPhilStat(uint8_t n, char const *stat) {
|
||||
(void)n;
|
||||
|
||||
if (stat[0] == 'h') {
|
||||
LED_GPIO_PORT->BSRRL = LED3_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */
|
||||
}
|
||||
if (stat[0] == 'e') {
|
||||
LED_GPIO_PORT->BSRRL = LED5_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED on */
|
||||
}
|
||||
|
||||
QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */
|
||||
QS_U8(1, n); /* Philosopher number */
|
||||
QS_STR(stat); /* Philosopher status */
|
||||
QS_END() /* application-specific record end */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPaused(uint8_t paused) {
|
||||
if (paused) {
|
||||
LED_GPIO_PORT->BSRRL = LED4_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED on */
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */
|
||||
uint32_t rnd;
|
||||
|
||||
/* exercise the FPU with some floating point computations */
|
||||
/* NOTE: this code can be only called from a task that created with
|
||||
* the option OS_TASK_OPT_SAVE_FP.
|
||||
*/
|
||||
float volatile x = 3.1415926F;
|
||||
x = x + 2.7182818F;
|
||||
|
||||
/* "Super-Duper" Linear Congruential Generator (LCG)
|
||||
* LCG(2^32, 3*7*11*13*23, 0, seed)
|
||||
*/
|
||||
rnd = l_rnd * (3U*7U*11U*13U*23U);
|
||||
l_rnd = rnd; /* set for the next time */
|
||||
|
||||
return (rnd >> 8);
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_randomSeed(uint32_t seed) {
|
||||
l_rnd = seed;
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_terminate(int16_t result) {
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* QF callbacks ============================================================*/
|
||||
void QF_onStartup(void) {
|
||||
/* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */
|
||||
SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
|
||||
|
||||
/* assing all priority bits for preemption-prio. and none to sub-prio. */
|
||||
NVIC_SetPriorityGrouping(0U);
|
||||
|
||||
/* set priorities of ALL ISRs used in the system, see NOTE00
|
||||
*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority().
|
||||
* DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE!
|
||||
*/
|
||||
NVIC_SetPriority(USART2_IRQn, USART2_PRIO);
|
||||
NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO);
|
||||
/* ... */
|
||||
|
||||
/* enable IRQs... */
|
||||
#ifdef Q_SPY
|
||||
NVIC_EnableIRQ(USART2_IRQn); /* USART2 interrupt used for QS-RX */
|
||||
#endif
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QF_onCleanup(void) {
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE01 */
|
||||
LED_GPIO_PORT->BSRRL = LED6_PIN; /* turn LED on */
|
||||
__NOP(); /* wait a little to actually see the LED glow */
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */
|
||||
|
||||
#ifdef Q_SPY
|
||||
QF_INT_ENABLE();
|
||||
QS_rxParse(); /* parse all the received bytes */
|
||||
|
||||
if ((USART2->SR & USART_FLAG_TXE) != 0) { /* is TXE empty? */
|
||||
uint16_t b;
|
||||
|
||||
QF_INT_DISABLE();
|
||||
b = QS_getByte();
|
||||
QF_INT_ENABLE();
|
||||
|
||||
if (b != QS_EOD) { /* not End-Of-Data? */
|
||||
USART2->DR = (b & 0xFFU); /* 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-M3 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.
|
||||
*/
|
||||
//QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */
|
||||
QF_INT_ENABLE(); /* just enable interrupts */
|
||||
#else
|
||||
QF_INT_ENABLE(); /* just enable interrupts */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
void Q_onAssert(char const *module, int loc) {
|
||||
/*
|
||||
* NOTE: add here your application-specific error handling
|
||||
*/
|
||||
(void)module;
|
||||
(void)loc;
|
||||
QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/* QS callbacks ============================================================*/
|
||||
#ifdef Q_SPY
|
||||
/*..........................................................................*/
|
||||
uint8_t QS_onStartup(void const *arg) {
|
||||
static uint8_t qsBuf[2*1024]; /* buffer for QS-TX channel */
|
||||
static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */
|
||||
GPIO_InitTypeDef GPIO_struct;
|
||||
USART_InitTypeDef USART_struct;
|
||||
|
||||
(void)arg; /* avoid the "unused parameter" compiler warning */
|
||||
QS_initBuf(qsBuf, sizeof(qsBuf));
|
||||
QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf));
|
||||
|
||||
/* enable peripheral clock for USART2 */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
|
||||
/* GPIOA clock enable */
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||
|
||||
/* GPIOA Configuration: USART2 TX on PA2 and RX on PA3 */
|
||||
GPIO_struct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP ;
|
||||
GPIO_Init(GPIOA, &GPIO_struct);
|
||||
|
||||
/* Connect USART2 pins to AF2 */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); /* TX = PA2 */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); /* RX = PA3 */
|
||||
|
||||
USART_struct.USART_BaudRate = 115200;
|
||||
USART_struct.USART_WordLength = USART_WordLength_8b;
|
||||
USART_struct.USART_StopBits = USART_StopBits_1;
|
||||
USART_struct.USART_Parity = USART_Parity_No;
|
||||
USART_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
USART_Init(USART2, &USART_struct);
|
||||
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* enable RX interrupt */
|
||||
USART_Cmd(USART2, ENABLE); /* enable USART2 */
|
||||
|
||||
QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC;
|
||||
QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */
|
||||
|
||||
/* setup the QS filters... */
|
||||
QS_FILTER_ON(QS_SM_RECORDS); /* state machine records */
|
||||
QS_FILTER_ON(QS_AO_RECORDS); /* active object records */
|
||||
QS_FILTER_ON(QS_UA_RECORDS); /* all user records */
|
||||
|
||||
return (uint8_t)1; /* return success */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onCleanup(void) {
|
||||
}
|
||||
/*..........................................................................*/
|
||||
QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */
|
||||
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */
|
||||
return QS_tickTime_ - (QSTimeCtr)SysTick->VAL;
|
||||
}
|
||||
else { /* the rollover occured, but the SysTick_ISR did not run yet */
|
||||
return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL;
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onFlush(void) {
|
||||
uint16_t b;
|
||||
|
||||
QF_INT_DISABLE();
|
||||
while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */
|
||||
QF_INT_ENABLE();
|
||||
while ((USART2->SR & USART_FLAG_TXE) == 0) { /* while TXE not empty */
|
||||
}
|
||||
USART2->DR = (b & 0xFFU); /* put into the DR register */
|
||||
QF_INT_DISABLE();
|
||||
}
|
||||
QF_INT_ENABLE();
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onReset(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onCommand(uint8_t cmdId,
|
||||
uint32_t param1, uint32_t param2, uint32_t param3)
|
||||
{
|
||||
void assert_failed(char const *module, int loc);
|
||||
(void)cmdId;
|
||||
(void)param1;
|
||||
(void)param2;
|
||||
(void)param3;
|
||||
QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */
|
||||
QS_U8(2, cmdId);
|
||||
QS_U32(8, param1);
|
||||
QS_U32(8, param2);
|
||||
QS_U32(8, param3);
|
||||
QS_END()
|
||||
|
||||
if (cmdId == 10U) {
|
||||
Q_ERROR();
|
||||
}
|
||||
else if (cmdId == 11U) {
|
||||
assert_failed("QS_onCommand", 123);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Q_SPY */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*****************************************************************************
|
||||
* NOTE00:
|
||||
* 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.
|
||||
*
|
||||
* NOTE01:
|
||||
* The QK_onIdle() callback is called with interrupts enabled.
|
||||
*
|
||||
* NOTE02:
|
||||
* One of the LEDs is used to visualize the idle loop activity. The brightness
|
||||
* of the LED is proportional to the frequency of invcations 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.
|
||||
*/
|
327
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/Makefile
Normal file
327
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/Makefile
Normal file
@ -0,0 +1,327 @@
|
||||
##############################################################################
|
||||
# Product: DPP on STM32F4-Discovery, QV, GNU-ARM gnutoolchains.com/arm-eabi
|
||||
# Last Updated for Version: 5.9.1
|
||||
# Date of the Last Update: 2017-06-01
|
||||
#
|
||||
# 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
|
||||
##############################################################################
|
||||
# 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 := dpp-qv
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# project directories
|
||||
#
|
||||
|
||||
# location of the QP/C framework (if not provided in an environemnt var.)
|
||||
ifeq ($(QPC),)
|
||||
QPC := ../../../../..
|
||||
endif
|
||||
|
||||
# QP port used in this project
|
||||
QP_PORT_DIR := $(QPC)/ports/arm-cm/qv/gnu
|
||||
|
||||
# list of all source directories used by this project
|
||||
VPATH = \
|
||||
.. \
|
||||
../.. \
|
||||
$(QPC)/src/qf \
|
||||
$(QPC)/src/qv \
|
||||
$(QPC)/src/qs \
|
||||
$(QP_PORT_DIR) \
|
||||
$(QPC)/3rd_party/stm32f4-discovery \
|
||||
$(QPC)/3rd_party/stm32f4-discovery/src \
|
||||
$(QPC)/3rd_party/stm32f4-discovery/gnu
|
||||
|
||||
# list of all include directories needed by this project
|
||||
INCLUDES = \
|
||||
-I../.. \
|
||||
-I$(QPC)/include \
|
||||
-I$(QPC)/src \
|
||||
-I$(QP_PORT_DIR) \
|
||||
-I$(QPC)/3rd_party/CMSIS/Include \
|
||||
-I$(QPC)/3rd_party/stm32f4-discovery \
|
||||
-I$(QPC)/3rd_party/stm32f4-discovery/inc
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# files
|
||||
#
|
||||
|
||||
# assembler source files
|
||||
ASM_SRCS :=
|
||||
|
||||
# C source files
|
||||
C_SRCS := \
|
||||
bsp.c \
|
||||
main.c \
|
||||
philo.c \
|
||||
table.c \
|
||||
system_stm32f4xx.c \
|
||||
startup_stm32f4xx.c \
|
||||
stm32f4xx_gpio.c \
|
||||
stm32f4xx_rcc.c \
|
||||
stm32f4xx_usart.c
|
||||
|
||||
# C++ source files
|
||||
CPP_SRCS :=
|
||||
|
||||
OUTPUT := $(PROJECT)
|
||||
LD_SCRIPT := $(PROJECT).ld
|
||||
|
||||
QP_SRCS := \
|
||||
qep_hsm.c \
|
||||
qep_msm.c \
|
||||
qf_act.c \
|
||||
qf_actq.c \
|
||||
qf_defer.c \
|
||||
qf_dyn.c \
|
||||
qf_mem.c \
|
||||
qf_ps.c \
|
||||
qf_qact.c \
|
||||
qf_qeq.c \
|
||||
qf_qmact.c \
|
||||
qf_time.c \
|
||||
qv.c \
|
||||
qv_port.c
|
||||
|
||||
QP_ASMS :=
|
||||
|
||||
QS_SRCS := \
|
||||
qs.c \
|
||||
qs_rx.c \
|
||||
qs_fp.c
|
||||
|
||||
LIB_DIRS :=
|
||||
LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES :=
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!)
|
||||
# ARM_FPU: [ | vfp]
|
||||
# FLOAT_ABI: [ | soft | softfp | hard]
|
||||
#
|
||||
ARM_CPU := -mcpu=cortex-m4
|
||||
ARM_ARCH := 7 # NOTE: must match the ARM_CPU!
|
||||
ARM_FPU := -mfpu=vfp
|
||||
FLOAT_ABI := -mfloat-abi=softfp
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-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-eabi-gcc
|
||||
CPP := $(GNU_ARM)/bin/arm-eabi-g++
|
||||
AS := $(GNU_ARM)/bin/arm-eabi-as
|
||||
LINK := $(GNU_ARM)/bin/arm-eabi-gcc
|
||||
BIN := $(GNU_ARM)/bin/arm-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 soruces...
|
||||
C_SRCS += $(QP_SRCS)
|
||||
ASM_SRCS += $(QP_ASMS)
|
||||
|
||||
# add the pre-defined symbol for ARM architecture
|
||||
DEFINES += -D__ARM_ARCH=$(ARM_ARCH)
|
||||
ASM_CPU += -defsym=__ARM_ARCH=$(ARM_ARCH)
|
||||
|
||||
# add the pre-defined symbol __FPU_PRESENT if needed...
|
||||
ifneq (,$(ARM_FPU))
|
||||
DEFINES += -D__FPU_PRESENT
|
||||
ASM_FPU += -defsym=__FPU_PRESENT=1
|
||||
endif
|
||||
|
||||
ifeq (rel, $(CONF)) # Release configuration ..................................
|
||||
|
||||
BIN_DIR := rel
|
||||
|
||||
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
|
||||
|
||||
CFLAGS = $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
|
||||
|
||||
CPPFLAGS = $(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
|
||||
|
||||
C_SRCS += $(QS_SRCS)
|
||||
|
||||
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
|
||||
|
||||
CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O $(INCLUDES) $(DEFINES) -DQ_SPY
|
||||
|
||||
CPPFLAGS = -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 = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O $(INCLUDES) $(DEFINES)
|
||||
|
||||
CPPFLAGS = -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 -nostdlib \
|
||||
-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)
|
||||
$(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -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) -c $< -o $@
|
||||
|
||||
$(BIN_DIR)/%.o : %.cpp
|
||||
$(CPP) $(CPPFLAGS) -c $< -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)
|
71
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/README.txt
Normal file
71
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/README.txt
Normal file
@ -0,0 +1,71 @@
|
||||
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 recommened 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 used in this project is located in the "3rd_party" folder
|
||||
in the following location:
|
||||
|
||||
3rd_party\<board>\gcc\startup_<mcu>.c
|
||||
|
||||
The file startup_<mcu>.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.
|
||||
***
|
135
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/dpp-qv.ld
Normal file
135
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/dpp-qv.ld
Normal file
@ -0,0 +1,135 @@
|
||||
/*****************************************************************************
|
||||
* Product: Linker script for STM32F407VG, GNU-ARM linker
|
||||
* Last Updated for Version: 5.9.1
|
||||
* Date of the Last Update: 2017-06-01
|
||||
*
|
||||
* 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 Tiva TM4C123GH6PM */
|
||||
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
/* The size of the stack used by the application. NOTE: you need to adjust */
|
||||
STACK_SIZE = 1024;
|
||||
|
||||
/* 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
|
||||
|
||||
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 ( * )
|
||||
}
|
||||
}
|
33
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/flash.bat
Normal file
33
examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/flash.bat
Normal file
@ -0,0 +1,33 @@
|
||||
::============================================================================
|
||||
:: Batch file to load the DPP program to the flash of STM32 boards
|
||||
::
|
||||
:: NOTE: requires the ST-LINK utlity from ST, see:
|
||||
:: http://www.st.com/en/embedded-software/stsw-link004.html
|
||||
::
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
@echo Load the program to the flash of STM32 board
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set STLINK="C:\tools\ST\ST-LINK\ST-LINK Utility\ST-LINK_CLI.exe"
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
if [%1] NEQ [] set BUILD_DIR=%1
|
||||
@echo on
|
||||
|
||||
%STLINK% -P %BUILD_DIR%\dpp-qv.bin 0x08000000
|
||||
|
||||
@echo.
|
||||
@echo.
|
||||
@echo Reset the target to start running your program!
|
||||
|
||||
@echo off
|
||||
endlocal
|
4213
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewd
Normal file
4213
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewd
Normal file
File diff suppressed because it is too large
Load Diff
3188
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewp
Normal file
3188
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewp
Normal file
File diff suppressed because it is too large
Load Diff
10
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.eww
Normal file
10
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.eww
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\dpp-qv.ewp</path>
|
||||
</project>
|
||||
<batchBuild/>
|
||||
</workspace>
|
||||
|
||||
|
35
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.icf
Normal file
35
examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.icf
Normal file
@ -0,0 +1,35 @@
|
||||
/*###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__ = 0x08000000;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 1024;
|
||||
define symbol __ICFEDIT_size_heap__ = 0;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __region_RAM1_start__ = 0x10000000;
|
||||
define symbol __region_RAM1_end__ = 0x1000FFFF;
|
||||
|
||||
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 region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_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 in RAM_region { readwrite,
|
||||
block CSTACK, block HEAP };
|
||||
place in RAM1_region { section .sram };
|
93
examples/arm-cm/dpp_stm32f4-discovery/qv/main.c
Normal file
93
examples/arm-cm/dpp_stm32f4-discovery/qv/main.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*****************************************************************************
|
||||
* Product: DPP example
|
||||
* Last Updated for Version: 5.9.0
|
||||
* Date of the Last Update: 2017-03-13
|
||||
*
|
||||
* Q u a n t u m L e a P s
|
||||
* ---------------------------
|
||||
* innovating embedded systems
|
||||
*
|
||||
* Copyright (C) 2005-2017 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
static QTicker l_ticker0;
|
||||
QActive *the_Ticker0 = &l_ticker0;
|
||||
|
||||
/*..........................................................................*/
|
||||
int main() {
|
||||
static QEvt const *tableQueueSto[N_PHILO];
|
||||
static QEvt const *philoQueueSto[N_PHILO][N_PHILO];
|
||||
static QSubscrList subscrSto[MAX_PUB_SIG];
|
||||
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */
|
||||
uint8_t n;
|
||||
|
||||
Philo_ctor(); /* instantiate all Philosopher active objects */
|
||||
Table_ctor(); /* instantiate the Table active object */
|
||||
QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */
|
||||
|
||||
QF_init(); /* initialize the framework and the underlying RT kernel */
|
||||
BSP_init(); /* initialize the Board Support Package */
|
||||
|
||||
/* object dictionaries... */
|
||||
QS_OBJ_DICTIONARY(smlPoolSto);
|
||||
QS_OBJ_DICTIONARY(tableQueueSto);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[0]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[1]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[2]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[3]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[4]);
|
||||
|
||||
/* initialize publish-subscribe... */
|
||||
QF_psInit(subscrSto, Q_DIM(subscrSto));
|
||||
|
||||
/* initialize event pools... */
|
||||
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
|
||||
|
||||
QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0);
|
||||
|
||||
/* start the active objects... */
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
QACTIVE_START(AO_Philo[n], /* AO to start */
|
||||
(uint_fast8_t)(n + 2), /* QP priority of the AO */
|
||||
philoQueueSto[n], /* event queue storage */
|
||||
Q_DIM(philoQueueSto[n]), /* queue length [events] */
|
||||
(void *)0, /* stack storage (not used) */
|
||||
0U, /* size of the stack [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
}
|
||||
QACTIVE_START(AO_Table, /* AO to start */
|
||||
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */
|
||||
tableQueueSto, /* event queue storage */
|
||||
Q_DIM(tableQueueSto), /* queue length [events] */
|
||||
(void *)0, /* stack storage (not used) */
|
||||
0U, /* size of the stack [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
|
||||
return QF_run(); /* run the QF application */
|
||||
}
|
||||
|
24
examples/arm-cm/dpp_stm32f4-discovery/qxk/arm/README.txt
Normal file
24
examples/arm-cm/dpp_stm32f4-discovery/qxk/arm/README.txt
Normal file
@ -0,0 +1,24 @@
|
||||
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/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
|
||||
numberical value of the heap size (for most embedded projects
|
||||
yyy should be 0, as the using the heap is not recommended).
|
||||
|
||||
|
1294
examples/arm-cm/dpp_stm32f4-discovery/qxk/arm/dpp-qxk.uvoptx
Normal file
1294
examples/arm-cm/dpp_stm32f4-discovery/qxk/arm/dpp-qxk.uvoptx
Normal file
File diff suppressed because it is too large
Load Diff
1958
examples/arm-cm/dpp_stm32f4-discovery/qxk/arm/dpp-qxk.uvprojx
Normal file
1958
examples/arm-cm/dpp_stm32f4-discovery/qxk/arm/dpp-qxk.uvprojx
Normal file
File diff suppressed because it is too large
Load Diff
532
examples/arm-cm/dpp_stm32f4-discovery/qxk/bsp.c
Normal file
532
examples/arm-cm/dpp_stm32f4-discovery/qxk/bsp.c
Normal file
@ -0,0 +1,532 @@
|
||||
/*****************************************************************************
|
||||
* Product: "DPP" example on STM32F4-Discovery board, preemptive QK kernel
|
||||
* Last Updated for Version: 5.9.1
|
||||
* Date of the Last Update: 2017-06-01
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
#include "stm32f4xx.h" /* CMSIS-compliant header file for the MCU used */
|
||||
#include "stm32f4xx_exti.h"
|
||||
#include "stm32f4xx_gpio.h"
|
||||
#include "stm32f4xx_rcc.h"
|
||||
#include "stm32f4xx_usart.h"
|
||||
/* add other drivers if necessary... */
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority().
|
||||
* DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE!
|
||||
*/
|
||||
enum KernelUnawareISRs { /* see NOTE00 */
|
||||
USART2_PRIO,
|
||||
/* ... */
|
||||
MAX_KERNEL_UNAWARE_CMSIS_PRI /* keep always last */
|
||||
};
|
||||
/* "kernel-unaware" interrupts can't overlap "kernel-aware" interrupts */
|
||||
Q_ASSERT_COMPILE(MAX_KERNEL_UNAWARE_CMSIS_PRI <= QF_AWARE_ISR_CMSIS_PRI);
|
||||
|
||||
enum KernelAwareISRs {
|
||||
SYSTICK_PRIO = QF_AWARE_ISR_CMSIS_PRI, /* see NOTE00 */
|
||||
/* ... */
|
||||
MAX_KERNEL_AWARE_CMSIS_PRI /* keep always last */
|
||||
};
|
||||
/* "kernel-aware" interrupts should not overlap the PendSV priority */
|
||||
Q_ASSERT_COMPILE(MAX_KERNEL_AWARE_CMSIS_PRI <= (0xFF >>(8-__NVIC_PRIO_BITS)));
|
||||
|
||||
/* ISRs defined in this BSP ------------------------------------------------*/
|
||||
void SysTick_Handler(void);
|
||||
void USART2_IRQHandler(void);
|
||||
|
||||
/* Local-scope defines -----------------------------------------------------*/
|
||||
#define LED_GPIO_PORT GPIOD
|
||||
#define LED_GPIO_CLK RCC_AHB1Periph_GPIOD
|
||||
|
||||
#define LED4_PIN GPIO_Pin_12
|
||||
#define LED3_PIN GPIO_Pin_13
|
||||
#define LED5_PIN GPIO_Pin_14
|
||||
#define LED6_PIN GPIO_Pin_15
|
||||
|
||||
#define BTN_GPIO_PORT GPIOA
|
||||
#define BTN_GPIO_CLK RCC_AHB1Periph_GPIOA
|
||||
#define BTN_B1 GPIO_Pin_0
|
||||
|
||||
static unsigned l_rnd; /* random seed */
|
||||
static QXMutex l_rndMutex; /* mutex to protect the random seed */
|
||||
|
||||
#ifdef Q_SPY
|
||||
static QSTimeCtr QS_tickTime_;
|
||||
static QSTimeCtr QS_tickPeriod_;
|
||||
|
||||
/* event-source identifiers used for tracing */
|
||||
static uint8_t const l_SysTick;
|
||||
|
||||
enum AppRecords { /* application-specific trace records */
|
||||
PHILO_STAT = QS_USER,
|
||||
COMMAND_STAT
|
||||
};
|
||||
#endif
|
||||
|
||||
/* ISRs used in this project ===============================================*/
|
||||
void SysTick_Handler(void) {
|
||||
/* state of the button debouncing, see below */
|
||||
static struct ButtonsDebouncing {
|
||||
uint32_t depressed;
|
||||
uint32_t previous;
|
||||
} buttons = { 0U, 0U };
|
||||
uint32_t current;
|
||||
uint32_t tmp;
|
||||
|
||||
QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */
|
||||
|
||||
#ifdef Q_SPY
|
||||
{
|
||||
tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */
|
||||
QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */
|
||||
}
|
||||
#endif
|
||||
|
||||
QF_TICK_X(0U, &l_SysTick); /* process time events for 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.
|
||||
*/
|
||||
current = BTN_GPIO_PORT->IDR; /* read BTN GPIO */
|
||||
tmp = buttons.depressed; /* save the debounced 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 */
|
||||
if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */
|
||||
if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */
|
||||
static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U};
|
||||
QF_PUBLISH(&pauseEvt, &l_SysTick);
|
||||
}
|
||||
else { /* the button is released */
|
||||
static QEvt const serveEvt = { SERVE_SIG, 0U, 0U};
|
||||
QF_PUBLISH(&serveEvt, &l_SysTick);
|
||||
}
|
||||
}
|
||||
|
||||
QXK_ISR_EXIT(); /* inform QXK 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/QXK and is not disabled. Such ISRs don't need to call QXK_ISR_ENTRY/
|
||||
* QXK_ISR_EXIT and they cannot post or publish events.
|
||||
*/
|
||||
void USART2_IRQHandler(void) {
|
||||
if ((USART2->SR & USART_SR_RXNE) != 0) {
|
||||
uint32_t b = USART2->DR;
|
||||
QS_RX_PUT(b);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void USART2_IRQHandler(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/* BSP functions ===========================================================*/
|
||||
void BSP_init(void) {
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
*/
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* configure the FPU usage by choosing one of the options... */
|
||||
#if 1
|
||||
/* OPTION 1:
|
||||
* Use the automatic FPU state preservation and the FPU lazy stacking.
|
||||
*
|
||||
* NOTE:
|
||||
* Use the following setting when FPU is used in more than one task or
|
||||
* in any ISRs. This setting is the safest and recommended, but requires
|
||||
* extra stack space and CPU cycles.
|
||||
*/
|
||||
FPU->FPCCR |= (1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos);
|
||||
#else
|
||||
/* OPTION 2:
|
||||
* Do NOT to use the automatic FPU state preservation and
|
||||
* do NOT to use the FPU lazy stacking.
|
||||
*
|
||||
* NOTE:
|
||||
* Use the following setting when FPU is used in ONE task only and not
|
||||
* in any ISR. This setting is very efficient, but if more than one task
|
||||
* (or ISR) start using the FPU, this can lead to corruption of the
|
||||
* FPU registers. This option should be used with CAUTION.
|
||||
*/
|
||||
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
|
||||
#endif
|
||||
|
||||
GPIO_InitTypeDef GPIO_struct;
|
||||
|
||||
/* NOTE: SystemInit() already called from the startup code
|
||||
* but SystemCoreClock needs to be updated
|
||||
*/
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
/* Explictily Disable the automatic FPU state preservation as well as
|
||||
* the FPU lazy stacking
|
||||
*/
|
||||
FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
|
||||
|
||||
/* Initialize thr port for the LEDs */
|
||||
RCC_AHB1PeriphClockCmd(LED_GPIO_CLK , ENABLE);
|
||||
|
||||
/* GPIO Configuration for the LEDs... */
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED3_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED4_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED5_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */
|
||||
|
||||
GPIO_struct.GPIO_Pin = LED6_PIN;
|
||||
GPIO_Init(LED_GPIO_PORT, &GPIO_struct);
|
||||
LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */
|
||||
|
||||
/* Initialize thr port for Button */
|
||||
RCC_AHB1PeriphClockCmd(BTN_GPIO_CLK , ENABLE);
|
||||
|
||||
/* GPIO Configuration for the Button... */
|
||||
GPIO_struct.GPIO_Pin = BTN_B1;
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(BTN_GPIO_PORT, &GPIO_struct);
|
||||
|
||||
/* seed the random number generator */
|
||||
BSP_randomSeed(1234U);
|
||||
|
||||
if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */
|
||||
Q_ERROR();
|
||||
}
|
||||
QS_OBJ_DICTIONARY(&l_SysTick);
|
||||
QS_USR_DICTIONARY(PHILO_STAT);
|
||||
QS_USR_DICTIONARY(COMMAND_STAT);
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPhilStat(uint8_t n, char const *stat) {
|
||||
(void)n;
|
||||
|
||||
if (stat[0] == 'h') {
|
||||
LED_GPIO_PORT->BSRRL = LED3_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */
|
||||
}
|
||||
if (stat[0] == 'e') {
|
||||
LED_GPIO_PORT->BSRRL = LED5_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED on */
|
||||
}
|
||||
|
||||
QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */
|
||||
QS_U8(1, n); /* Philosopher number */
|
||||
QS_STR(stat); /* Philosopher status */
|
||||
QS_END() /* application-specific record end */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_displayPaused(uint8_t paused) {
|
||||
if (paused) {
|
||||
LED_GPIO_PORT->BSRRL = LED4_PIN; /* turn LED on */
|
||||
}
|
||||
else {
|
||||
LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED on */
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */
|
||||
uint32_t rnd;
|
||||
|
||||
/* Some flating point code is to exercise the VFP... */
|
||||
float volatile x = 3.1415926F;
|
||||
x = x + 2.7182818F;
|
||||
|
||||
QXMutex_lock(&l_rndMutex); /* lock the random-seed mutex */
|
||||
/* "Super-Duper" Linear Congruential Generator (LCG)
|
||||
* LCG(2^32, 3*7*11*13*23, 0, seed)
|
||||
*/
|
||||
rnd = l_rnd * (3U*7U*11U*13U*23U);
|
||||
l_rnd = rnd; /* set for the next time */
|
||||
QXMutex_unlock(&l_rndMutex); /* unlock the random-seed mutex */
|
||||
|
||||
return (rnd >> 8);
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_randomSeed(uint32_t seed) {
|
||||
l_rnd = seed;
|
||||
QXMutex_init(&l_rndMutex, N_PHILO); /* ceiling == max Philo priority */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void BSP_terminate(int16_t result) {
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* QF callbacks ============================================================*/
|
||||
void QF_onStartup(void) {
|
||||
/* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */
|
||||
SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC);
|
||||
|
||||
/* assing all priority bits for preemption-prio. and none to sub-prio. */
|
||||
NVIC_SetPriorityGrouping(0U);
|
||||
|
||||
/* set priorities of ALL ISRs used in the system, see NOTE00
|
||||
*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority().
|
||||
* DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE!
|
||||
*/
|
||||
NVIC_SetPriority(USART2_IRQn, USART2_PRIO);
|
||||
NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO);
|
||||
/* ... */
|
||||
|
||||
/* enable IRQs... */
|
||||
#ifdef Q_SPY
|
||||
NVIC_EnableIRQ(USART2_IRQn); /* USART2 interrupt used for QS-RX */
|
||||
#endif
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QF_onCleanup(void) {
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QXK_onIdle(void) {
|
||||
QF_INT_DISABLE();
|
||||
LED_GPIO_PORT->BSRRL = LED6_PIN; /* turn LED on */
|
||||
__NOP(); /* wait a little to actually see the LED glow */
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */
|
||||
QF_INT_ENABLE();
|
||||
|
||||
#ifdef Q_SPY
|
||||
QS_rxParse(); /* parse all the received bytes */
|
||||
|
||||
if ((USART2->SR & USART_FLAG_TXE) != 0) { /* TXE empty? */
|
||||
uint16_t b;
|
||||
|
||||
QF_INT_DISABLE();
|
||||
b = QS_getByte();
|
||||
QF_INT_ENABLE();
|
||||
|
||||
if (b != QS_EOD) { /* not End-Of-Data? */
|
||||
USART2->DR = (b & 0xFFU); /* 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.
|
||||
*/
|
||||
/* !!!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
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
void Q_onAssert(char const *module, int loc) {
|
||||
/*
|
||||
* NOTE: add here your application-specific error handling
|
||||
*/
|
||||
(void)module;
|
||||
(void)loc;
|
||||
QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/* QS callbacks ============================================================*/
|
||||
#ifdef Q_SPY
|
||||
/*..........................................................................*/
|
||||
uint8_t QS_onStartup(void const *arg) {
|
||||
static uint8_t qsBuf[2*1024]; /* buffer for QS-TX channel */
|
||||
static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */
|
||||
GPIO_InitTypeDef GPIO_struct;
|
||||
USART_InitTypeDef USART_struct;
|
||||
|
||||
(void)arg; /* avoid the "unused parameter" compiler warning */
|
||||
QS_initBuf(qsBuf, sizeof(qsBuf));
|
||||
QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf));
|
||||
|
||||
/* enable peripheral clock for USART2 */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
|
||||
/* GPIOA clock enable */
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||
|
||||
/* GPIOA Configuration: USART2 TX on PA2 and RX on PA3 */
|
||||
GPIO_struct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
|
||||
GPIO_struct.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_struct.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP ;
|
||||
GPIO_Init(GPIOA, &GPIO_struct);
|
||||
|
||||
/* Connect USART2 pins to AF2 */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); /* TX = PA2 */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); /* RX = PA3 */
|
||||
|
||||
USART_struct.USART_BaudRate = 115200;
|
||||
USART_struct.USART_WordLength = USART_WordLength_8b;
|
||||
USART_struct.USART_StopBits = USART_StopBits_1;
|
||||
USART_struct.USART_Parity = USART_Parity_No;
|
||||
USART_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
USART_Init(USART2, &USART_struct);
|
||||
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* enable RX interrupt */
|
||||
USART_Cmd(USART2, ENABLE); /* enable USART2 */
|
||||
|
||||
QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC;
|
||||
QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */
|
||||
|
||||
/* setup the QS filters... */
|
||||
QS_FILTER_ON(QS_SM_RECORDS); /* state machine records */
|
||||
QS_FILTER_ON(QS_AO_RECORDS); /* active object records */
|
||||
QS_FILTER_ON(QS_UA_RECORDS); /* all user records */
|
||||
|
||||
return (uint8_t)1; /* return success */
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onCleanup(void) {
|
||||
}
|
||||
/*..........................................................................*/
|
||||
QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */
|
||||
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */
|
||||
return QS_tickTime_ - (QSTimeCtr)SysTick->VAL;
|
||||
}
|
||||
else { /* the rollover occured, but the SysTick_ISR did not run yet */
|
||||
return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL;
|
||||
}
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onFlush(void) {
|
||||
uint16_t b;
|
||||
|
||||
QF_INT_DISABLE();
|
||||
while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */
|
||||
QF_INT_ENABLE();
|
||||
while ((USART2->SR & USART_FLAG_TXE) == 0) { /* while TXE not empty */
|
||||
}
|
||||
USART2->DR = (b & 0xFF); /* put into the DR register */
|
||||
QF_INT_DISABLE();
|
||||
}
|
||||
QF_INT_ENABLE();
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onReset(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
/*..........................................................................*/
|
||||
void QS_onCommand(uint8_t cmdId,
|
||||
uint32_t param1, uint32_t param2, uint32_t param3)
|
||||
{
|
||||
void assert_failed(char const *module, int loc);
|
||||
(void)cmdId;
|
||||
(void)param1;
|
||||
(void)param2;
|
||||
(void)param3;
|
||||
QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */
|
||||
QS_U8(2, cmdId);
|
||||
QS_U32(8, param1);
|
||||
QS_U32(8, param2);
|
||||
QS_U32(8, param3);
|
||||
QS_END()
|
||||
|
||||
if (cmdId == 10U) {
|
||||
Q_ERROR();
|
||||
}
|
||||
else if (cmdId == 11U) {
|
||||
assert_failed("QS_onCommand", 123);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Q_SPY */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*****************************************************************************
|
||||
* NOTE00:
|
||||
* 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.
|
||||
*
|
||||
* NOTE01:
|
||||
* 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.
|
||||
*
|
||||
* NOTE02:
|
||||
* One of the LEDs is used to visualize the idle loop activity. The brightness
|
||||
* of the LED is proportional to the frequency of invcations 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.
|
||||
*/
|
331
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/Makefile
Normal file
331
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/Makefile
Normal file
@ -0,0 +1,331 @@
|
||||
##############################################################################
|
||||
# Product: DPP on STM32F4-Discovery, QXK, GNU-ARM gnutoolchains.com/arm-eabi
|
||||
# Last Updated for Version: 5.9.1
|
||||
# Date of the Last Update: 2017-06-01
|
||||
#
|
||||
# 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
|
||||
##############################################################################
|
||||
# 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 := dpp-qxk
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# project directories
|
||||
#
|
||||
|
||||
# location of the QP/C framework (if not provided in an environemnt var.)
|
||||
ifeq ($(QPC),)
|
||||
QPC := ../../../../..
|
||||
endif
|
||||
|
||||
# QP port used in this project
|
||||
QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu
|
||||
|
||||
# list of all source directories used by this project
|
||||
VPATH = \
|
||||
.. \
|
||||
../.. \
|
||||
$(QPC)/src/qf \
|
||||
$(QPC)/src/qxk \
|
||||
$(QPC)/src/qs \
|
||||
$(QP_PORT_DIR) \
|
||||
$(QPC)/3rd_party/stm32f4-discovery \
|
||||
$(QPC)/3rd_party/stm32f4-discovery/src \
|
||||
$(QPC)/3rd_party/stm32f4-discovery/gnu
|
||||
|
||||
# list of all include directories needed by this project
|
||||
INCLUDES = \
|
||||
-I../.. \
|
||||
-I$(QPC)/include \
|
||||
-I$(QPC)/src \
|
||||
-I$(QP_PORT_DIR) \
|
||||
-I$(QPC)/3rd_party/CMSIS/Include \
|
||||
-I$(QPC)/3rd_party/stm32f4-discovery \
|
||||
-I$(QPC)/3rd_party/stm32f4-discovery/inc
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# files
|
||||
#
|
||||
|
||||
# assembler source files
|
||||
ASM_SRCS :=
|
||||
|
||||
# C source files
|
||||
C_SRCS := \
|
||||
bsp.c \
|
||||
main.c \
|
||||
philo.c \
|
||||
table.c \
|
||||
test.c \
|
||||
system_stm32f4xx.c \
|
||||
startup_stm32f4xx.c \
|
||||
stm32f4xx_gpio.c \
|
||||
stm32f4xx_rcc.c \
|
||||
stm32f4xx_usart.c
|
||||
|
||||
# C++ source files
|
||||
CPP_SRCS :=
|
||||
|
||||
OUTPUT := $(PROJECT)
|
||||
LD_SCRIPT := $(PROJECT).ld
|
||||
|
||||
QP_SRCS := \
|
||||
qep_hsm.c \
|
||||
qep_msm.c \
|
||||
qf_act.c \
|
||||
qf_actq.c \
|
||||
qf_defer.c \
|
||||
qf_dyn.c \
|
||||
qf_mem.c \
|
||||
qf_ps.c \
|
||||
qf_qact.c \
|
||||
qf_qeq.c \
|
||||
qf_qmact.c \
|
||||
qf_time.c \
|
||||
qxk.c \
|
||||
qxk_mutex.c \
|
||||
qxk_sema.c \
|
||||
qxk_xthr.c
|
||||
|
||||
QP_ASMS := \
|
||||
qxk_port.s
|
||||
|
||||
QS_SRCS := \
|
||||
qs.c \
|
||||
qs_rx.c \
|
||||
qs_fp.c
|
||||
|
||||
LIB_DIRS :=
|
||||
LIBS :=
|
||||
|
||||
# defines
|
||||
DEFINES :=
|
||||
|
||||
# ARM CPU, ARCH, FPU, and Float-ABI types...
|
||||
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
|
||||
# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!)
|
||||
# ARM_FPU: [ | vfp]
|
||||
# FLOAT_ABI: [ | soft | softfp | hard]
|
||||
#
|
||||
ARM_CPU := -mcpu=cortex-m4
|
||||
ARM_ARCH := 7 # NOTE: must match the ARM_CPU!
|
||||
ARM_FPU := -mfpu=vfp
|
||||
FLOAT_ABI := -mfloat-abi=softfp
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
|
||||
# see http://gnutoolchains.com/arm-eabi/
|
||||
#
|
||||
ifeq ($(GNU_ARM),)
|
||||
GNU_ARM := $(QTOOLS)/gnu_arm-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-eabi-gcc
|
||||
CPP := $(GNU_ARM)/bin/arm-eabi-g++
|
||||
AS := $(GNU_ARM)/bin/arm-eabi-as
|
||||
LINK := $(GNU_ARM)/bin/arm-eabi-gcc
|
||||
BIN := $(GNU_ARM)/bin/arm-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 soruces...
|
||||
C_SRCS += $(QP_SRCS)
|
||||
ASM_SRCS += $(QP_ASMS)
|
||||
|
||||
# add the pre-defined symbol for ARM architecture
|
||||
DEFINES += -D__ARM_ARCH=$(ARM_ARCH)
|
||||
ASM_CPU += -defsym=__ARM_ARCH=$(ARM_ARCH)
|
||||
|
||||
# add the pre-defined symbol __FPU_PRESENT if needed...
|
||||
ifneq (,$(ARM_FPU))
|
||||
DEFINES += -D__FPU_PRESENT
|
||||
ASM_FPU += -defsym=__FPU_PRESENT=1
|
||||
endif
|
||||
|
||||
ifeq (rel, $(CONF)) # Release configuration ..................................
|
||||
|
||||
BIN_DIR := rel
|
||||
|
||||
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
|
||||
|
||||
CFLAGS = $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
|
||||
|
||||
CPPFLAGS = $(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
|
||||
|
||||
C_SRCS += $(QS_SRCS)
|
||||
|
||||
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
|
||||
|
||||
CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O $(INCLUDES) $(DEFINES) -DQ_SPY
|
||||
|
||||
CPPFLAGS = -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 = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
|
||||
-ffunction-sections -fdata-sections \
|
||||
-O $(INCLUDES) $(DEFINES)
|
||||
|
||||
CPPFLAGS = -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 -nostdlib \
|
||||
-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)
|
||||
$(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -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) -c $< -o $@
|
||||
|
||||
$(BIN_DIR)/%.o : %.cpp
|
||||
$(CPP) $(CPPFLAGS) -c $< -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)
|
71
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/README.txt
Normal file
71
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/README.txt
Normal file
@ -0,0 +1,71 @@
|
||||
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 recommened 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 used in this project is located in the "3rd_party" folder
|
||||
in the following location:
|
||||
|
||||
3rd_party\<board>\gcc\startup_<mcu>.c
|
||||
|
||||
The file startup_<mcu>.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.
|
||||
***
|
135
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/dpp-qxk.ld
Normal file
135
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/dpp-qxk.ld
Normal file
@ -0,0 +1,135 @@
|
||||
/*****************************************************************************
|
||||
* Product: Linker script for STM32F407VG, GNU-ARM linker
|
||||
* Last Updated for Version: 5.9.1
|
||||
* Date of the Last Update: 2017-06-01
|
||||
*
|
||||
* 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 Tiva TM4C123GH6PM */
|
||||
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
/* The size of the stack used by the application. NOTE: you need to adjust */
|
||||
STACK_SIZE = 1024;
|
||||
|
||||
/* 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
|
||||
|
||||
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 ( * )
|
||||
}
|
||||
}
|
33
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/flash.bat
Normal file
33
examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/flash.bat
Normal file
@ -0,0 +1,33 @@
|
||||
::============================================================================
|
||||
:: Batch file to load the DPP program to the flash of STM32 boards
|
||||
::
|
||||
:: NOTE: requires the ST-LINK utlity from ST, see:
|
||||
:: http://www.st.com/en/embedded-software/stsw-link004.html
|
||||
::
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
@echo Load the program to the flash of STM32 board
|
||||
@echo usage: flash
|
||||
@echo usage: flash rel
|
||||
@echo usage: flash spy
|
||||
|
||||
::----------------------------------------------------------------------------
|
||||
:: NOTE: Adjust the following symbol to the location of the
|
||||
:: LMFlash utility on your machine
|
||||
::
|
||||
set STLINK="C:\tools\ST\ST-LINK\ST-LINK Utility\ST-LINK_CLI.exe"
|
||||
|
||||
:: set the build directory depending on the first parameter %1
|
||||
set BUILD_DIR=dbg
|
||||
if [%1] NEQ [] set BUILD_DIR=%1
|
||||
@echo on
|
||||
|
||||
%STLINK% -P %BUILD_DIR%\dpp-qxk.bin 0x08000000
|
||||
|
||||
@echo.
|
||||
@echo.
|
||||
@echo Reset the target to start running your program!
|
||||
|
||||
@echo off
|
||||
endlocal
|
4213
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewd
Normal file
4213
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewd
Normal file
File diff suppressed because it is too large
Load Diff
3212
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewp
Normal file
3212
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewp
Normal file
File diff suppressed because it is too large
Load Diff
10
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.eww
Normal file
10
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.eww
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\dpp-qxk.ewp</path>
|
||||
</project>
|
||||
<batchBuild/>
|
||||
</workspace>
|
||||
|
||||
|
35
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.icf
Normal file
35
examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.icf
Normal file
@ -0,0 +1,35 @@
|
||||
/*###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__ = 0x08000000;
|
||||
/*-Memory Regions-*/
|
||||
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
|
||||
define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF;
|
||||
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
|
||||
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
|
||||
/*-Sizes-*/
|
||||
define symbol __ICFEDIT_size_cstack__ = 1024;
|
||||
define symbol __ICFEDIT_size_heap__ = 0;
|
||||
/**** End of ICF editor section. ###ICF###*/
|
||||
|
||||
define symbol __region_RAM1_start__ = 0x10000000;
|
||||
define symbol __region_RAM1_end__ = 0x1000FFFF;
|
||||
|
||||
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 region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_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 in RAM_region { readwrite,
|
||||
block CSTACK, block HEAP };
|
||||
place in RAM1_region { section .sram };
|
121
examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c
Normal file
121
examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*****************************************************************************
|
||||
* Product: DPP example extened for the dual-mode QXK kernel
|
||||
* Last Updated for Version: 5.9.0
|
||||
* Date of the Last Update: 2017-04-13
|
||||
*
|
||||
* Q u a n t u m L e a P s
|
||||
* ---------------------------
|
||||
* innovating embedded systems
|
||||
*
|
||||
* Copyright (C) 2005-2017 Quantum Leaps, LLC. All Rigts 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
/*..........................................................................*/
|
||||
int main() {
|
||||
static QEvt const *tableQueueSto[N_PHILO];
|
||||
static QEvt const *philoQueueSto[N_PHILO][N_PHILO];
|
||||
static QSubscrList subscrSto[MAX_PUB_SIG];
|
||||
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */
|
||||
|
||||
/* stacks and queues for the extended test threads */
|
||||
static void const *test1QueueSto[5];
|
||||
static uint64_t test1StackSto[64];
|
||||
static void const *test2QueueSto[5];
|
||||
static uint64_t test2StackSto[64];
|
||||
|
||||
uint8_t n;
|
||||
|
||||
Philo_ctor(); /* instantiate all Philosopher active objects */
|
||||
Table_ctor(); /* instantiate the Table active object */
|
||||
Test1_ctor(); /* instantiate the Test1 extended thread */
|
||||
Test2_ctor(); /* instantiate the Test2 extended thread */
|
||||
|
||||
QF_init(); /* initialize the framework and the underlying RT kernel */
|
||||
|
||||
/* initialize publish-subscribe... */
|
||||
QF_psInit(subscrSto, Q_DIM(subscrSto));
|
||||
|
||||
/* initialize event pools... */
|
||||
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
|
||||
|
||||
/* initialize the Board Support Package
|
||||
* NOTE: BSP_init() is called *after* initializing publish-subscribe and
|
||||
* event pools, to make the system ready to accept SysTick interrupts.
|
||||
* Unfortunately, the STM32Cube code that must be called from BSP,
|
||||
* configures and starts SysTick.
|
||||
*/
|
||||
BSP_init();
|
||||
|
||||
/* object dictionaries... */
|
||||
QS_OBJ_DICTIONARY(smlPoolSto);
|
||||
QS_OBJ_DICTIONARY(tableQueueSto);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[0]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[1]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[2]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[3]);
|
||||
QS_OBJ_DICTIONARY(philoQueueSto[4]);
|
||||
|
||||
|
||||
/* start the extended thread */
|
||||
QXTHREAD_START(&XT_Test1->super, /* Thread to start */
|
||||
(uint_fast8_t)1U, /* QP priority of the thread */
|
||||
test1QueueSto, /* message queue storage */
|
||||
Q_DIM(test1QueueSto), /* message length [events] */
|
||||
test1StackSto, /* stack storage */
|
||||
sizeof(test1StackSto), /* stack size [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
|
||||
/* start the Philo active objects... */
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
QACTIVE_START(AO_Philo[n], /* AO to start */
|
||||
(uint_fast8_t)(n + 2), /* QP priority of the AO */
|
||||
philoQueueSto[n], /* event queue storage */
|
||||
Q_DIM(philoQueueSto[n]), /* queue length [events] */
|
||||
(void *)0, /* stack storage (not used) */
|
||||
0U, /* size of the stack [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
}
|
||||
QXTHREAD_START(&XT_Test2->super, /* Thread to start */
|
||||
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the thread */
|
||||
test2QueueSto, /* message queue storage */
|
||||
Q_DIM(test2QueueSto), /* message length [events] */
|
||||
test2StackSto, /* stack storage */
|
||||
sizeof(test2StackSto), /* stack size [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
|
||||
QACTIVE_START(AO_Table, /* AO to start */
|
||||
(uint_fast8_t)(N_PHILO + 3), /* QP priority of the AO */
|
||||
tableQueueSto, /* event queue storage */
|
||||
Q_DIM(tableQueueSto), /* queue length [events] */
|
||||
(void *)0, /* stack storage (not used) */
|
||||
0U, /* size of the stack [bytes] */
|
||||
(QEvt *)0); /* initialization event */
|
||||
|
||||
return QF_run(); /* run the QF application */
|
||||
}
|
||||
|
117
examples/arm-cm/dpp_stm32f4-discovery/qxk/test.c
Normal file
117
examples/arm-cm/dpp_stm32f4-discovery/qxk/test.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*****************************************************************************
|
||||
* Product: DPP example
|
||||
* Last Updated for Version: 5.8.2
|
||||
* Date of the Last Update: 2017-01-28
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
/* local "naked" thread object .............................................*/
|
||||
static QXThread l_test1;
|
||||
static QXThread l_test2;
|
||||
static QXMutex l_mutex;
|
||||
static QXSemaphore l_sema;
|
||||
|
||||
/* global pointer to the test thread .......................................*/
|
||||
QXThread * const XT_Test1 = &l_test1;
|
||||
QXThread * const XT_Test2 = &l_test2;
|
||||
|
||||
/*..........................................................................*/
|
||||
static void Thread1_run(QXThread * const me) {
|
||||
|
||||
QXMutex_init(&l_mutex, 3U);
|
||||
|
||||
(void)me;
|
||||
for (;;) {
|
||||
float volatile x;
|
||||
|
||||
/* wait on a semaphore (BLOCK with timeout) */
|
||||
(void)QXSemaphore_wait(&l_sema, BSP_TICKS_PER_SEC, 0U);
|
||||
//BSP_ledOn();
|
||||
|
||||
QXMutex_lock(&l_mutex); /* exercise the mutex */
|
||||
/* some flating point code to exercise the VFP... */
|
||||
x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
QXMutex_unlock(&l_mutex);
|
||||
|
||||
QXThread_delay(BSP_TICKS_PER_SEC/7, 0U); /* BLOCK */
|
||||
|
||||
/* publish to thread2 */
|
||||
QF_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1);
|
||||
}
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
void Test1_ctor(void) {
|
||||
QXThread_ctor(&l_test1, Q_XTHREAD_CAST(&Thread1_run), 0U);
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
static void Thread2_run(QXThread * const me) {
|
||||
|
||||
/* subscribe to the test signal */
|
||||
QActive_subscribe(&me->super, TEST_SIG);
|
||||
|
||||
/* initialize the semaphore before using it
|
||||
* NOTE: the semaphore is initialized in the highest-priority thread
|
||||
* that uses it. Alternatively, the semaphore can be initialized
|
||||
* before any thread runs.
|
||||
*/
|
||||
QXSemaphore_init(&l_sema, 0U); /* start with zero count */
|
||||
|
||||
for (;;) {
|
||||
QEvt const *e;
|
||||
|
||||
/* some flating point code to exercise the VFP... */
|
||||
float volatile x;
|
||||
x = 1.4142135F;
|
||||
x = x * 1.4142135F;
|
||||
|
||||
/* wait on the internal event queue (BLOCK) with timeout */
|
||||
e = QXThread_queueGet(BSP_TICKS_PER_SEC/2, 0U);
|
||||
//BSP_ledOff();
|
||||
|
||||
if (e != (QEvt *)0) { /* event actually delivered? */
|
||||
QF_gc(e); /* recycle the event manually! */
|
||||
}
|
||||
else {
|
||||
QXThread_delay(BSP_TICKS_PER_SEC/2, 0U); /* wait more (BLOCK) */
|
||||
QXSemaphore_signal(&l_sema); /* signal Thread1 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*..........................................................................*/
|
||||
void Test2_ctor(void) {
|
||||
QXThread_ctor(&l_test2, Q_XTHREAD_CAST(&Thread2_run), 0U);
|
||||
}
|
296
examples/arm-cm/dpp_stm32f4-discovery/table.c
Normal file
296
examples/arm-cm/dpp_stm32f4-discovery/table.c
Normal file
@ -0,0 +1,296 @@
|
||||
/*****************************************************************************
|
||||
* Model: dpp.qm
|
||||
* File: ./table.c
|
||||
*
|
||||
* This code has been generated by QM tool (see state-machine.com/qm).
|
||||
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
/*${.::table.c} ............................................................*/
|
||||
#include "qpc.h"
|
||||
#include "dpp.h"
|
||||
#include "bsp.h"
|
||||
|
||||
Q_DEFINE_THIS_FILE
|
||||
|
||||
/* Active object class -----------------------------------------------------*/
|
||||
|
||||
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
|
||||
#error qpc version 5.8.0 or higher required
|
||||
#endif
|
||||
|
||||
/*${AOs::Table} ............................................................*/
|
||||
typedef struct {
|
||||
/* protected: */
|
||||
QActive super;
|
||||
|
||||
/* private: */
|
||||
uint8_t fork[N_PHILO];
|
||||
uint8_t isHungry[N_PHILO];
|
||||
} Table;
|
||||
|
||||
/* protected: */
|
||||
static QState Table_initial(Table * const me, QEvt const * const e);
|
||||
static QState Table_active(Table * const me, QEvt const * const e);
|
||||
static QState Table_serving(Table * const me, QEvt const * const e);
|
||||
static QState Table_paused(Table * const me, QEvt const * const e);
|
||||
|
||||
|
||||
#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO))
|
||||
#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO))
|
||||
#define FREE ((uint8_t)0)
|
||||
#define USED ((uint8_t)1)
|
||||
|
||||
/* Local objects -----------------------------------------------------------*/
|
||||
static Table l_table; /* the single instance of the Table active object */
|
||||
|
||||
/* Global-scope objects ----------------------------------------------------*/
|
||||
QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */
|
||||
|
||||
/*..........................................................................*/
|
||||
/*${AOs::Table_ctor} .......................................................*/
|
||||
void Table_ctor(void) {
|
||||
uint8_t n;
|
||||
Table *me = &l_table;
|
||||
|
||||
QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial));
|
||||
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
me->fork[n] = FREE;
|
||||
me->isHungry[n] = 0U;
|
||||
}
|
||||
}
|
||||
/*${AOs::Table} ............................................................*/
|
||||
/*${AOs::Table::SM} ........................................................*/
|
||||
static QState Table_initial(Table * const me, QEvt const * const e) {
|
||||
/* ${AOs::Table::SM::initial} */
|
||||
uint8_t n;
|
||||
(void)e; /* suppress the compiler warning about unused parameter */
|
||||
|
||||
QS_OBJ_DICTIONARY(&l_table);
|
||||
QS_FUN_DICTIONARY(&QHsm_top);
|
||||
QS_FUN_DICTIONARY(&Table_initial);
|
||||
QS_FUN_DICTIONARY(&Table_active);
|
||||
QS_FUN_DICTIONARY(&Table_serving);
|
||||
QS_FUN_DICTIONARY(&Table_paused);
|
||||
|
||||
QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */
|
||||
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
|
||||
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
|
||||
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
|
||||
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
|
||||
|
||||
QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */
|
||||
|
||||
QActive_subscribe(&me->super, DONE_SIG);
|
||||
QActive_subscribe(&me->super, PAUSE_SIG);
|
||||
QActive_subscribe(&me->super, SERVE_SIG);
|
||||
QActive_subscribe(&me->super, TEST_SIG);
|
||||
|
||||
for (n = 0U; n < N_PHILO; ++n) {
|
||||
me->fork[n] = FREE;
|
||||
me->isHungry[n] = 0U;
|
||||
BSP_displayPhilStat(n, "thinking");
|
||||
}
|
||||
return Q_TRAN(&Table_serving);
|
||||
}
|
||||
/*${AOs::Table::SM::active} ................................................*/
|
||||
static QState Table_active(Table * const me, QEvt const * const e) {
|
||||
QState status_;
|
||||
switch (e->sig) {
|
||||
/* ${AOs::Table::SM::active::TEST} */
|
||||
case TEST_SIG: {
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::EAT} */
|
||||
case EAT_SIG: {
|
||||
Q_ERROR();
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
status_ = Q_SUPER(&QHsm_top);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
/*${AOs::Table::SM::active::serving} .......................................*/
|
||||
static QState Table_serving(Table * const me, QEvt const * const e) {
|
||||
QState status_;
|
||||
switch (e->sig) {
|
||||
/* ${AOs::Table::SM::active::serving} */
|
||||
case Q_ENTRY_SIG: {
|
||||
uint8_t n;
|
||||
for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */
|
||||
if ((me->isHungry[n] != 0U)
|
||||
&& (me->fork[LEFT(n)] == FREE)
|
||||
&& (me->fork[n] == FREE))
|
||||
{
|
||||
TableEvt *te;
|
||||
|
||||
me->fork[LEFT(n)] = USED;
|
||||
me->fork[n] = USED;
|
||||
te = Q_NEW(TableEvt, EAT_SIG);
|
||||
te->philoNum = n;
|
||||
QF_PUBLISH(&te->super, me);
|
||||
me->isHungry[n] = 0U;
|
||||
BSP_displayPhilStat(n, "eating ");
|
||||
}
|
||||
}
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::serving::HUNGRY} */
|
||||
case HUNGRY_SIG: {
|
||||
uint8_t n, m;
|
||||
|
||||
n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* phil ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
|
||||
BSP_displayPhilStat(n, "hungry ");
|
||||
m = LEFT(n);
|
||||
/* ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */
|
||||
if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) {
|
||||
TableEvt *pe;
|
||||
me->fork[m] = USED;
|
||||
me->fork[n] = USED;
|
||||
pe = Q_NEW(TableEvt, EAT_SIG);
|
||||
pe->philoNum = n;
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
BSP_displayPhilStat(n, "eating ");
|
||||
status_ = Q_HANDLED();
|
||||
}
|
||||
/* ${AOs::Table::SM::active::serving::HUNGRY::[else]} */
|
||||
else {
|
||||
me->isHungry[n] = 1U;
|
||||
status_ = Q_HANDLED();
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::serving::DONE} */
|
||||
case DONE_SIG: {
|
||||
uint8_t n, m;
|
||||
TableEvt *pe;
|
||||
|
||||
n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* phil ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
|
||||
BSP_displayPhilStat(n, "thinking");
|
||||
m = LEFT(n);
|
||||
/* both forks of Phil[n] must be used */
|
||||
Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
|
||||
|
||||
me->fork[m] = FREE;
|
||||
me->fork[n] = FREE;
|
||||
m = RIGHT(n); /* check the right neighbor */
|
||||
|
||||
if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) {
|
||||
me->fork[n] = USED;
|
||||
me->fork[m] = USED;
|
||||
me->isHungry[m] = 0U;
|
||||
pe = Q_NEW(TableEvt, EAT_SIG);
|
||||
pe->philoNum = m;
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
BSP_displayPhilStat(m, "eating ");
|
||||
}
|
||||
m = LEFT(n); /* check the left neighbor */
|
||||
n = LEFT(m); /* left fork of the left neighbor */
|
||||
if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) {
|
||||
me->fork[m] = USED;
|
||||
me->fork[n] = USED;
|
||||
me->isHungry[m] = 0U;
|
||||
pe = Q_NEW(TableEvt, EAT_SIG);
|
||||
pe->philoNum = m;
|
||||
QF_PUBLISH(&pe->super, me);
|
||||
BSP_displayPhilStat(m, "eating ");
|
||||
}
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::serving::EAT} */
|
||||
case EAT_SIG: {
|
||||
Q_ERROR();
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::serving::PAUSE} */
|
||||
case PAUSE_SIG: {
|
||||
status_ = Q_TRAN(&Table_paused);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
status_ = Q_SUPER(&Table_active);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
/*${AOs::Table::SM::active::paused} ........................................*/
|
||||
static QState Table_paused(Table * const me, QEvt const * const e) {
|
||||
QState status_;
|
||||
switch (e->sig) {
|
||||
/* ${AOs::Table::SM::active::paused} */
|
||||
case Q_ENTRY_SIG: {
|
||||
BSP_displayPaused(1U);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::paused} */
|
||||
case Q_EXIT_SIG: {
|
||||
BSP_displayPaused(0U);
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::paused::SERVE} */
|
||||
case SERVE_SIG: {
|
||||
status_ = Q_TRAN(&Table_serving);
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::paused::HUNGRY} */
|
||||
case HUNGRY_SIG: {
|
||||
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* philo ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
me->isHungry[n] = 1U;
|
||||
BSP_displayPhilStat(n, "hungry ");
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
/* ${AOs::Table::SM::active::paused::DONE} */
|
||||
case DONE_SIG: {
|
||||
uint8_t n, m;
|
||||
|
||||
n = Q_EVT_CAST(TableEvt)->philoNum;
|
||||
/* phil ID must be in range and he must be not hungry */
|
||||
Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U));
|
||||
|
||||
BSP_displayPhilStat(n, "thinking");
|
||||
m = LEFT(n);
|
||||
/* both forks of Phil[n] must be used */
|
||||
Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
|
||||
|
||||
me->fork[m] = FREE;
|
||||
me->fork[n] = FREE;
|
||||
status_ = Q_HANDLED();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
status_ = Q_SUPER(&Table_active);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status_;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user