diff --git a/3rd_party/stm32f4-discovery/iar/startup_stm32f4xx_threadx.s b/3rd_party/stm32f4-discovery/iar/startup_stm32f4xx_threadx.s deleted file mode 100644 index 9f3853b1..00000000 --- a/3rd_party/stm32f4-discovery/iar/startup_stm32f4xx_threadx.s +++ /dev/null @@ -1,452 +0,0 @@ -;/***************************************************************************/ -; * @file startup_stm32f4xx.s for ThreadX; IAR ARM assembler -; * @brief CMSIS Cortex-M4F Core Device Startup File for STM32F40xx devices -; * @version CMSIS 4.3.0 -; * @date 20 August 2015 -; * -; * @description -; * Created from the CMSIS template for the specified device -; * Quantum Leaps, www.state-machine.com -; * -; * @attention -; * Adapted for ThreadX STM32demo library, which is NOT CMSIS-compiliant. -; * Specifically, the standard Cortex-M exception names required by -; * ThreadX are different than prescribed by CMSIS. -; * -; * @note -; * The function assert_failed defined at the end of this file defines -; * the error/assertion handling policy for the application and might -; * need to be customized for each project. This function is defined in -; * assembly to re-set the stack pointer, in case it is corrupted by the -; * time assert_failed is called. -; * -; ***************************************************************************/ -;/* Copyright (c) 2012 ARM LIMITED -; -; All rights reserved. -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; - Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; - Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; - Neither the name of ARM nor the names of its contributors may be used -; to endorse or promote products derived from this software without -; specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; POSSIBILITY OF SUCH DAMAGE. -;---------------------------------------------------------------------------*/ - - MODULE ?cstartup - - ;; Forward declaration of sections. - SECTION CSTACK:DATA:NOROOT(3) - - SECTION .intvec:CODE:NOROOT(2) - - PUBLIC __vector_table - PUBLIC __Vectors - PUBLIC __Vectors_End - PUBLIC __Vectors_Size - - ;; QL: added for ThreadX - PUBLIC __tx_vectors - EXTERN __tx_SVCallHandler - EXTERN __tx_PendSVHandler - EXTERN __tx_SysTickHandler - - -;****************************************************************************** -; - DATA -__vector_table -__tx_vectors - DCD sfe(CSTACK) - DCD Reset_Handler ; Reset Handler - DCD NMI_Handler ; NMI Handler - DCD HardFault_Handler ; Hard Fault Handler - DCD MemManage_Handler ; The MPU fault handler - DCD BusFault_Handler ; The bus fault handler - DCD UsageFault_Handler ; The usage fault handler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD __tx_SVCallHandler ; QL: SVCall handler (ThreadX) !!! - DCD DebugMon_Handler ; Debug monitor handler - DCD 0 ; Reserved - DCD __tx_PendSVHandler ; QL: PendSV handler (ThreadX) !!! - DCD __tx_SysTickHandler ; QL: SysTick handler (ThreadX) !!! - - ; IRQ handlers... - DCD WWDG_IRQHandler ; Window WatchDog - DCD PVD_IRQHandler ; PVD through EXTI Line detection - DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line - DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line - DCD FLASH_IRQHandler ; FLASH - DCD RCC_IRQHandler ; RCC - DCD EXTI0_IRQHandler ; EXTI Line0 - DCD EXTI1_IRQHandler ; EXTI Line1 - DCD EXTI2_IRQHandler ; EXTI Line2 - DCD EXTI3_IRQHandler ; EXTI Line3 - DCD EXTI4_IRQHandler ; EXTI Line4 - DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0 - DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1 - DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2 - DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3 - DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4 - DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5 - DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6 - DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s - DCD CAN1_TX_IRQHandler ; CAN1 TX - DCD CAN1_RX0_IRQHandler ; CAN1 RX0 - DCD CAN1_RX1_IRQHandler ; CAN1 RX1 - DCD CAN1_SCE_IRQHandler ; CAN1 SCE - DCD EXTI9_5_IRQHandler ; External Line[9:5]s - DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9 - DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10 - DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11 - DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare - DCD TIM2_IRQHandler ; TIM2 - DCD TIM3_IRQHandler ; TIM3 - DCD TIM4_IRQHandler ; TIM4 - DCD I2C1_EV_IRQHandler ; I2C1 Event - DCD I2C1_ER_IRQHandler ; I2C1 Error - DCD I2C2_EV_IRQHandler ; I2C2 Event - DCD I2C2_ER_IRQHandler ; I2C2 Error - DCD SPI1_IRQHandler ; SPI1 - DCD SPI2_IRQHandler ; SPI2 - DCD USART1_IRQHandler ; USART1 - DCD USART2_IRQHandler ; USART2 - DCD USART3_IRQHandler ; USART3 - DCD EXTI15_10_IRQHandler ; External Line[15:10]s - DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line - DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line - DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12 - DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13 - DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14 - DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare - DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7 - DCD FSMC_IRQHandler ; FSMC - DCD SDIO_IRQHandler ; SDIO - DCD TIM5_IRQHandler ; TIM5 - DCD SPI3_IRQHandler ; SPI3 - DCD UART4_IRQHandler ; UART4 - DCD UART5_IRQHandler ; UART5 - DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors - DCD TIM7_IRQHandler ; TIM7 - DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0 - DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1 - DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2 - DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3 - DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4 - DCD ETH_IRQHandler ; Ethernet - DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line - DCD CAN2_TX_IRQHandler ; CAN2 TX - DCD CAN2_RX0_IRQHandler ; CAN2 RX0 - DCD CAN2_RX1_IRQHandler ; CAN2 RX1 - DCD CAN2_SCE_IRQHandler ; CAN2 SCE - DCD OTG_FS_IRQHandler ; USB OTG FS - DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5 - DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6 - DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7 - DCD USART6_IRQHandler ; USART6 - DCD I2C3_EV_IRQHandler ; I2C3 event - DCD I2C3_ER_IRQHandler ; I2C3 error - DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out - DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In - DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI - DCD OTG_HS_IRQHandler ; USB OTG HS - DCD DCMI_IRQHandler ; DCMI - DCD CRYP_IRQHandler ; CRYP crypto - DCD HASH_RNG_IRQHandler ; Hash and Rng - DCD FPU_IRQHandler ; FPU - -__Vectors_End - -__Vectors EQU __vector_table -__Vectors_Size EQU __Vectors_End - __Vectors - -;****************************************************************************** -; -; Weak fault handlers... -; - SECTION .text:CODE:REORDER:NOROOT(2) - -;............................................................................. - PUBWEAK Reset_Handler - EXTERN SystemInit - EXTERN __iar_program_start -Reset_Handler - BL SystemInit ; CMSIS system initialization - BL __iar_program_start ; IAR startup code -;............................................................................. - PUBWEAK NMI_Handler -NMI_Handler - MOVS r0,#0 - MOVS r1,#2 ; NMI exception number - B assert_failed -;............................................................................. - PUBWEAK HardFault_Handler -HardFault_Handler - MOVS r0,#0 - MOVS r1,#3 ; HardFault exception number - B assert_failed -;............................................................................. - PUBWEAK MemManage_Handler -MemManage_Handler - MOVS r0,#0 - MOVS r1,#4 ; MemManage exception number - B assert_failed -;............................................................................. - PUBWEAK BusFault_Handler -BusFault_Handler - MOVS r0,#0 - MOVS r1,#5 ; BusFault exception number - B assert_failed -;............................................................................. - PUBWEAK UsageFault_Handler -UsageFault_Handler - MOVS r0,#0 - MOVS r1,#6 ; UsageFault exception number - B assert_failed - - -;****************************************************************************** -; -; Weak non-fault handlers... -; - - PUBWEAK SVC_Handler -SVC_Handler - MOVS r0,#0 - MOVS r1,#11 ; SVCall exception number - B assert_failed -;............................................................................. - PUBWEAK DebugMon_Handler -DebugMon_Handler - MOVS r0,#0 - MOVS r1,#12 ; DebugMon exception number - B assert_failed -;............................................................................. - PUBWEAK PendSV_Handler -PendSV_Handler - MOVS r0,#0 - MOVS r1,#14 ; PendSV exception number - B assert_failed -;............................................................................. - PUBWEAK SysTick_Handler -SysTick_Handler - MOVS r0,#0 - MOVS r1,#15 ; SysTick exception number - B assert_failed - - -;****************************************************************************** -; -; Weak IRQ handlers... -; - - PUBWEAK WWDG_IRQHandler - PUBWEAK PVD_IRQHandler - PUBWEAK TAMP_STAMP_IRQHandler - PUBWEAK RTC_WKUP_IRQHandler - PUBWEAK FLASH_IRQHandler - PUBWEAK RCC_IRQHandler - PUBWEAK EXTI0_IRQHandler - PUBWEAK EXTI1_IRQHandler - PUBWEAK EXTI2_IRQHandler - PUBWEAK EXTI3_IRQHandler - PUBWEAK EXTI4_IRQHandler - PUBWEAK DMA1_Stream0_IRQHandler - PUBWEAK DMA1_Stream1_IRQHandler - PUBWEAK DMA1_Stream2_IRQHandler - PUBWEAK DMA1_Stream3_IRQHandler - PUBWEAK DMA1_Stream4_IRQHandler - PUBWEAK DMA1_Stream5_IRQHandler - PUBWEAK DMA1_Stream6_IRQHandler - PUBWEAK ADC_IRQHandler - PUBWEAK CAN1_TX_IRQHandler - PUBWEAK CAN1_RX0_IRQHandler - PUBWEAK CAN1_RX1_IRQHandler - PUBWEAK CAN1_SCE_IRQHandler - PUBWEAK EXTI9_5_IRQHandler - PUBWEAK TIM1_BRK_TIM9_IRQHandler - PUBWEAK TIM1_UP_TIM10_IRQHandler - PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler - PUBWEAK TIM1_CC_IRQHandler - PUBWEAK TIM2_IRQHandler - PUBWEAK TIM3_IRQHandler - PUBWEAK TIM4_IRQHandler - PUBWEAK I2C1_EV_IRQHandler - PUBWEAK I2C1_ER_IRQHandler - PUBWEAK I2C2_EV_IRQHandler - PUBWEAK I2C2_ER_IRQHandler - PUBWEAK SPI1_IRQHandler - PUBWEAK SPI2_IRQHandler - PUBWEAK USART1_IRQHandler - PUBWEAK USART2_IRQHandler - PUBWEAK USART3_IRQHandler - PUBWEAK EXTI15_10_IRQHandler - PUBWEAK RTC_Alarm_IRQHandler - PUBWEAK OTG_FS_WKUP_IRQHandler - PUBWEAK TIM8_BRK_TIM12_IRQHandler - PUBWEAK TIM8_UP_TIM13_IRQHandler - PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler - PUBWEAK TIM8_CC_IRQHandler - PUBWEAK DMA1_Stream7_IRQHandler - PUBWEAK FSMC_IRQHandler - PUBWEAK SDIO_IRQHandler - PUBWEAK TIM5_IRQHandler - PUBWEAK SPI3_IRQHandler - PUBWEAK UART4_IRQHandler - PUBWEAK UART5_IRQHandler - PUBWEAK TIM6_DAC_IRQHandler - PUBWEAK TIM7_IRQHandler - PUBWEAK DMA2_Stream0_IRQHandler - PUBWEAK DMA2_Stream1_IRQHandler - PUBWEAK DMA2_Stream2_IRQHandler - PUBWEAK DMA2_Stream3_IRQHandler - PUBWEAK DMA2_Stream4_IRQHandler - PUBWEAK ETH_IRQHandler - PUBWEAK ETH_WKUP_IRQHandler - PUBWEAK CAN2_TX_IRQHandler - PUBWEAK CAN2_RX0_IRQHandler - PUBWEAK CAN2_RX1_IRQHandler - PUBWEAK CAN2_SCE_IRQHandler - PUBWEAK OTG_FS_IRQHandler - PUBWEAK DMA2_Stream5_IRQHandler - PUBWEAK DMA2_Stream6_IRQHandler - PUBWEAK DMA2_Stream7_IRQHandler - PUBWEAK USART6_IRQHandler - PUBWEAK I2C3_EV_IRQHandler - PUBWEAK I2C3_ER_IRQHandler - PUBWEAK OTG_HS_EP1_OUT_IRQHandler - PUBWEAK OTG_HS_EP1_IN_IRQHandler - PUBWEAK OTG_HS_WKUP_IRQHandler - PUBWEAK OTG_HS_IRQHandler - PUBWEAK DCMI_IRQHandler - PUBWEAK CRYP_IRQHandler - PUBWEAK HASH_RNG_IRQHandler - PUBWEAK FPU_IRQHandler - -WWDG_IRQHandler -PVD_IRQHandler -TAMP_STAMP_IRQHandler -RTC_WKUP_IRQHandler -FLASH_IRQHandler -RCC_IRQHandler -EXTI0_IRQHandler -EXTI1_IRQHandler -EXTI2_IRQHandler -EXTI3_IRQHandler -EXTI4_IRQHandler -DMA1_Stream0_IRQHandler -DMA1_Stream1_IRQHandler -DMA1_Stream2_IRQHandler -DMA1_Stream3_IRQHandler -DMA1_Stream4_IRQHandler -DMA1_Stream5_IRQHandler -DMA1_Stream6_IRQHandler -ADC_IRQHandler -CAN1_TX_IRQHandler -CAN1_RX0_IRQHandler -CAN1_RX1_IRQHandler -CAN1_SCE_IRQHandler -EXTI9_5_IRQHandler -TIM1_BRK_TIM9_IRQHandler -TIM1_UP_TIM10_IRQHandler -TIM1_TRG_COM_TIM11_IRQHandler -TIM1_CC_IRQHandler -TIM2_IRQHandler -TIM3_IRQHandler -TIM4_IRQHandler -I2C1_EV_IRQHandler -I2C1_ER_IRQHandler -I2C2_EV_IRQHandler -I2C2_ER_IRQHandler -SPI1_IRQHandler -SPI2_IRQHandler -USART1_IRQHandler -USART2_IRQHandler -USART3_IRQHandler -EXTI15_10_IRQHandler -RTC_Alarm_IRQHandler -OTG_FS_WKUP_IRQHandler -TIM8_BRK_TIM12_IRQHandler -TIM8_UP_TIM13_IRQHandler -TIM8_TRG_COM_TIM14_IRQHandler -TIM8_CC_IRQHandler -DMA1_Stream7_IRQHandler -FSMC_IRQHandler -SDIO_IRQHandler -TIM5_IRQHandler -SPI3_IRQHandler -UART4_IRQHandler -UART5_IRQHandler -TIM6_DAC_IRQHandler -TIM7_IRQHandler -DMA2_Stream0_IRQHandler -DMA2_Stream1_IRQHandler -DMA2_Stream2_IRQHandler -DMA2_Stream3_IRQHandler -DMA2_Stream4_IRQHandler -ETH_IRQHandler -ETH_WKUP_IRQHandler -CAN2_TX_IRQHandler -CAN2_RX0_IRQHandler -CAN2_RX1_IRQHandler -CAN2_SCE_IRQHandler -OTG_FS_IRQHandler -DMA2_Stream5_IRQHandler -DMA2_Stream6_IRQHandler -DMA2_Stream7_IRQHandler -USART6_IRQHandler -I2C3_EV_IRQHandler -I2C3_ER_IRQHandler -OTG_HS_EP1_OUT_IRQHandler -OTG_HS_EP1_IN_IRQHandler -OTG_HS_WKUP_IRQHandler -OTG_HS_IRQHandler -DCMI_IRQHandler -CRYP_IRQHandler -HASH_RNG_IRQHandler -FPU_IRQHandler - MOV r0,#0 - MOV r1,#-1 ; 0xFFFFFFF - B assert_failed - -;****************************************************************************** -; -; The function assert_failed defines the error/assertion handling policy -; for the application. After making sure that the stack is OK, this function -; calls Q_onAssert, which should NOT return (typically reset the CPU). -; -; NOTE: the function Q_onAssert should NOT return. -; -; The C proptotype of the assert_failed() and Q_onAssert() functions are: -; void assert_failed(char const *file, int line); -; void Q_onAssert (char const *file, int line); -;****************************************************************************** - PUBLIC assert_failed - EXTERN Q_onAssert -assert_failed - LDR sp,=sfe(CSTACK) ; re-set the SP in case of stack overflow - BL Q_onAssert ; call the application-specific handler - - B . ; should not be reached, but just in case... - - - END ; end of module - diff --git a/3rd_party/threadx/readme_threadx.txt b/3rd_party/threadx/readme_threadx.txt deleted file mode 100644 index 3087d6c1..00000000 --- a/3rd_party/threadx/readme_threadx.txt +++ /dev/null @@ -1,258 +0,0 @@ - Express Logic's ThreadX for STM3240G-EVAL (Cortex-M4 FPU) Evaluation Board - - Using the IAR Tools - - - *** DEMO VERSION *** - - -0. About This Version - -This version of ThreadX is for demonstration purposes only and may not -be used for any product development, either directly or indirectly. In -addition, this demonstration may not be used for any competitive purpose. - - -1. Installation - -ThreadX for the Cortex-M4 is delivered on a single CD-ROM compatible disk. -The entire distribution can be found in the sub-directory: - -\threadx - -To install ThreadX to your hard-disk, either run the supplied installer -program Setup.exe or copy the distribution from the CD manually. - -To copy the ThreadX distribution manually, make a ThreadX directory on your -hard-disk (we recommend c:\threadx\stm3240g-eval\iar) and copy all the contents -of the ThreadX sub-directory on the distribution disk. The following -is an example MS-DOS copy command from the distribution directory -(assuming source is d: and c: is your hard-drive): - - -d:\threadx> xcopy /S *.* c:\threadx\stm3240g-eval\iar - - -2. Building the ThreadX run-time Library - -This demonstration version contains a pre-built ThreadX library, tx.a. The library is -intended for demonstration purposes only and thus has the following limitations: - - 10 Threads - 9 Timers - 2 Event Flag Groups - 2 Mutexes - 3 Queues - 2 Semaphores - 1 Block Pool - 1 Byte Pool - - - -3. Demonstration System - -The ThreadX demonstration is designed to execute under the IAR debugger on the -STM3240G-EVAL evaluation board (STM32F407 processor). - -Building the demonstration is easy; simply open the threadx.www workspace file, -make the demo_threadx.ewp project the "active project" in the IAR Embedded -Workbench, and select the "Make" button. - -You should observe the compilation of demo_threadx.c (which is the demonstration -application) and linking with tx.a. The resulting file demo_threadx.out is a -binary ELF file that can be downloaded to flash and executed on the STM3240G-EVAL -evaluation board connected via a USB cable to the IAR J-Link JTAG probe. - - -4. System Initialization - -The entry point in ThreadX for the Cortex-M4 using IAR tools is at label -__iar_program_start. This is defined within the IAR compiler's startup code. -In addition, this is where all static and global preset C variable -initialization processing takes place. - -The ThreadX tx_initialize_low_level.s file is responsible for setting up -various system data structures, and a periodic timer interrupt source. -By default, the vector area is defined at the top of startup_stm32f40x.s, -which is a slightly modified from the base ST/IAR file. - -The _tx_initialize_low_level function inside of tx_initialize_low_level.s -also determines the first available address for use by the application, which -is supplied as the sole input parameter to your application definition function, -tx_application_define. To accomplish this, a section is created in -tx_initialize_low_level.s called FREE_MEM, which must be located after all -other RAM sections in memory. - - -5. Register Usage and Stack Frames - -The following defines the saved context stack frames for context switches -that occur as a result of interrupt handling or from thread-level API calls. -All suspended threads have the same stack frame in the Cortex-M4 version of -ThreadX. The top of the suspended thread's stack is pointed to by -tx_thread_stack_ptr in the associated thread control block TX_THREAD. - - -Non-FPU Stack Frame: - - Stack Offset Stack Contents - - 0x00 r4 - 0x04 r5 - 0x08 r6 - 0x0C r7 - 0x10 r8 - 0x14 r9 - 0x18 r10 (sl) - 0x1C r11 - 0x20 r0 (Hardware stack starts here!!) - 0x24 r1 - 0x28 r2 - 0x2C r3 - 0x30 r12 - 0x34 lr - 0x38 pc - 0x3C xPSR - -FPU Stack Frame (only interrupted thread with FPU enabled): - - Stack Offset Stack Contents - - 0x00 s0 - 0x04 s1 - 0x08 s2 - 0x0C s3 - 0x10 s4 - 0x14 s5 - 0x18 s6 - 0x1C s7 - 0x20 s8 - 0x24 s9 - 0x28 s10 - 0x2C s11 - 0x30 s12 - 0x34 s13 - 0x38 s14 - 0x3C s15 - 0x40 s16 - 0x44 s17 - 0x48 s18 - 0x4C s19 - 0x50 s20 - 0x54 s21 - 0x58 s22 - 0x5C s23 - 0x60 s24 - 0x64 s25 - 0x68 s26 - 0x6C s27 - 0x70 s28 - 0x74 s29 - 0x78 s30 - 0x7C s31 - 0x80 fpscr - 0x84 r4 - 0x88 r5 - 0x8C r6 - 0x90 r7 - 0x94 r8 - 0x98 r9 - 0x9C r10 (sl) - 0xA0 r11 - 0xA4 r0 (Hardware stack starts here!!) - 0xA8 r1 - 0xAC r2 - 0xB0 r3 - 0xB4 r12 - 0xB8 lr - 0xBC pc - 0xC0 xPSR - - -6. Improving Performance - -The distribution version of ThreadX is built without any compiler -optimizations. This makes it easy to debug because you can trace or set -breakpoints inside of ThreadX itself. Of course, this costs some -performance. To make it run faster, you can change the ThreadX library -project to enable various compiler optimizations. - -In addition, you can eliminate the ThreadX basic API error checking by -compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING -defined. - - -7. Interrupt Handling - -ThreadX provides complete and high-performance interrupt handling for Cortex-M4 -targets. There are a certain set of requirements that are defined in the -following sub-sections: - - -7.1 Vector Area - -The Cortex-M4 vectors start at the label __tx_vectors and is defined in cstartup_M.s. -The application may modify the vector area according to its needs. - - -7.2 Managed Interrupts - -A ThreadX managed interrupt is defined below. By following these conventions, the -application ISR is then allowed access to various ThreadX services from the ISR. -Here is the standard template for managed ISRs in ThreadX: - - - PUBLIC __tx_IntHandler -__tx_IntHandler: -; VOID InterruptHandler (VOID) -; { - PUSH {lr} - BL _tx_thread_context_save - -; /* Do interrupt handler work here */ -; /* .... */ - - B _tx_thread_context_restore -; } - - -8. IAR Thread-safe Library Support - -Thread-safe support for the IAR tools is easily enabled by building the ThreadX library -and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file -should have the following line added (if not already in place): - -initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application - - -9. FPU Support - -By default, FPU support is disabled for each thread. If saving the context of the FPU registers -is needed, the following API call must be made from the context of the application thread - before -the FPU usage: - -void tx_thread_fpu_enable(void); - -After this API is called in the application, FPU registers will be saved/restored for this thread if it -is preempted via an interrupt. All other suspension of the this thread will not require the FPU registers -to be saved/restored. - -To disable FPU register context saving, simply call the following API: - -void tx_thread_fpu_disable(void); - - -9. Revision History - -01/24/2012 Initial ThreadX demo version for ST's STM3240G-EVAL board using IAR's ARM tools. - - -Copyright(c) 1996-2012 Express Logic, Inc. - - -Express Logic, Inc. -11423 West Bernardo Court -San Diego, CA 92127 - -www.expresslogic.com - diff --git a/3rd_party/threadx/stm32f4xx_iar/readme_threadx.txt b/3rd_party/threadx/stm32f4xx_iar/readme_threadx.txt new file mode 100644 index 00000000..8d7e6605 --- /dev/null +++ b/3rd_party/threadx/stm32f4xx_iar/readme_threadx.txt @@ -0,0 +1,248 @@ + Express Logic's ThreadX for ST's STM32F4 Discovery Evaluation Board (Cortex-M4) + + Using the IAR Tools + + + *** DEMO VERSION *** + + +0. About This Version + +This version of ThreadX is for demonstration purposes only and may not +be used for any product development, either directly or indirectly. In +addition, this demonstration may not be used for any competitive purpose. + + +1. Installation + +ThreadX for ST's STM32F4 Discovery (Cortex-M4) is pre-installed in the evaluation +package. + + +2. Building the ThreadX run-time Library + +This demonstration version contains a pre-built ThreadX library, tx.a. The library is +intended for demonstration purposes only and thus has the following limitations: + + 10 Threads + 10 Timers + 10 Event Flag Groups + 10 Mutexes + 10 Queues + 10 Semaphores + 10 Block Pool + 10 Byte Pool + + +3. Demonstration System + +The ThreadX demonstration is designed to execute on the STM32F4 Discovery evaluation +board under the IAR Windows-based debugger. + +Building the demonstration is easy; simply make the demo_threadx.ewp project +the "active project" in the IAR Embedded Workbench and select the "Make" button. + +You should observe the compilation of demo_threadx.c (which is the demonstration +application) and linking with tx.a. The resulting file demo_threadx.out is a binary +file that can be downloaded and executed on the STM32F4 Discovery evaluation board using +the IAR debugger. + + +4. System Initialization + +The entry point in ThreadX for the (Cortex-M4) using IAR tools is at label +Reset_Handler. This is defined within the STM32 startup code, namely +the file startup_stm32f429xx.s. From this entry point, the IAR startup code +at __iar_program_start is called. This is where all static and global preset +C variable initialization processing takes place. + +The ThreadX tx_initialize_low_level.s file is responsible for setting up +various system data structures, and a periodic timer interrupt source. + +The _tx_initialize_low_level function inside of tx_initialize_low_level.s +also determines the first available address for use by the application, which +is supplied as the sole input parameter to your application definition function, +tx_application_define. To accomplish this, a section is created in +tx_initialize_low_level.s called FREE_MEM, which must be located after all +other RAM sections in memory. + + +5. Register Usage and Stack Frames + +The following defines the saved context stack frames for context switches +that occur as a result of interrupt handling or from thread-level API calls. +All suspended threads have the same stack frame in the Cortex-M4 version of +ThreadX. The top of the suspended thread's stack is pointed to by +tx_thread_stack_ptr in the associated thread control block TX_THREAD. + +Non-FPU Stack Frame: + + Stack Offset Stack Contents + + 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x04 r4 + 0x08 r5 + 0x0C r6 + 0x10 r7 + 0x14 r8 + 0x18 r9 + 0x1C r10 (sl) + 0x20 r11 + 0x24 r0 (Hardware stack starts here!!) + 0x28 r1 + 0x2C r2 + 0x30 r3 + 0x34 r12 + 0x38 lr + 0x3C pc + 0x40 xPSR + +FPU Stack Frame (only interrupted thread with FPU enabled): + + Stack Offset Stack Contents + + 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x04 s0 + 0x08 s1 + 0x0C s2 + 0x10 s3 + 0x14 s4 + 0x18 s5 + 0x1C s6 + 0x20 s7 + 0x24 s8 + 0x28 s9 + 0x2C s10 + 0x30 s11 + 0x34 s12 + 0x38 s13 + 0x3C s14 + 0x40 s15 + 0x44 s16 + 0x48 s17 + 0x4C s18 + 0x50 s19 + 0x54 s20 + 0x58 s21 + 0x5C s22 + 0x60 s23 + 0x64 s24 + 0x68 s25 + 0x6C s26 + 0x70 s27 + 0x74 s28 + 0x78 s29 + 0x7C s30 + 0x80 s31 + 0x84 fpscr + 0x88 r4 + 0x8C r5 + 0x90 r6 + 0x94 r7 + 0x98 r8 + 0x9C r9 + 0xA0 r10 (sl) + 0xA4 r11 + 0xA8 r0 (Hardware stack starts here!!) + 0xAC r1 + 0xB0 r2 + 0xB4 r3 + 0xB8 r12 + 0xBC lr + 0xC0 pc + 0xC4 xPSR + +6. Improving Performance + +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by +compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING +defined. + + +7. Interrupt Handling + +The Cortex-M4 vectors start at the label __vector_table and is defined in cstartup_M.s. +The application may modify the vector area according to its needs. + + +7.2 Managed Interrupts + +From version 5.6 going forward, ISRs for Cortex-M using the IAR tools can be written +completely in C (or assembly language) without any calls to _tx_thread_context_save or +_tx_thread_context_restore. These ISRs are allowed access to the ThreadX API that is +available to ISRs. + +ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): + +void your_C_isr(void) +{ + + /* ISR processing goes here, including any needed function calls. */ +} + +ISRs written in assembly language will take the form: + + PUBLIC your_assembly_isr +your_assembly_isr: + + PUSH {lr} + + ; ISR processing goes here, including any needed function calls. + + POP {lr} + BX lr + +Backward compatibility to the previous style assembly ISRs is maintained, which was of +the form: + + PUBLIC __legacy_isr_handler +__legacy_isr_handler: + PUSH {lr} + BL _tx_thread_context_save + +; /* Do interrupt handler work here */ +; /* .... */ + + B _tx_thread_context_restore + + +8. IAR Thread-safe Library Support + +Thread-safe support for the IAR tools is easily enabled by building the ThreadX library +and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file +should have the following line added (if not already in place): + +initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application + +The project options "General Options -> Library Configuration" should also have the +"Enable thread support in library" box selected. + + +9. VFP Support + +When applicable, ThreadX for the STM32F4 Discovery (Cortex-M4) supports lazy VFP support, which +means that applications threads can simply use the VFP and ThreadX automatically maintains +the VFP registers as part of the thread context - no additional setup by the application +is required. + + +10. Revision History + +08/01/2017 Initial ThreadX version for STM32F4 Discovery (Cortex-M4) using IAR's ARM tools. + + +Copyright(c) 1996-2017 Express Logic, Inc. + + +Express Logic, Inc. +11323 West Bernardo Court +San Diego, CA 92127 + +www.expresslogic.com + diff --git a/3rd_party/threadx/stm32f4xx_iar/tx_port.h b/3rd_party/threadx/stm32f4xx_iar/tx_port.h new file mode 100644 index 00000000..d5a6aad8 --- /dev/null +++ b/3rd_party/threadx/stm32f4xx_iar/tx_port.h @@ -0,0 +1,431 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 1996-2017 by Express Logic Inc. */ +/* */ +/* This software is copyrighted by and is the sole property of Express */ +/* Logic, Inc. All rights, title, ownership, or other interests */ +/* in the software remain the property of Express Logic, Inc. This */ +/* software may only be used in accordance with the corresponding */ +/* license agreement. Any unauthorized use, duplication, transmission, */ +/* distribution, or disclosure of this software is expressly forbidden. */ +/* */ +/* This Copyright notice may not be removed or modified without prior */ +/* written consent of Express Logic, Inc. */ +/* */ +/* Express Logic, Inc. reserves the right to modify this software */ +/* without notice. */ +/* */ +/* Express Logic, Inc. info@expresslogic.com */ +/* 11423 West Bernardo Court http://www.expresslogic.com */ +/* San Diego, CA 92127 */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h Cortex-M4/IAR */ +/* 5.6 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Express Logic, Inc. */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-10-2010 William E. Lamie Initial Cortex-M4 IAR */ +/* Support Version 5.0 */ +/* 07-15-2011 William E. Lamie Modified comment(s), added */ +/* IAR thread-safe library */ +/* support, and updated */ +/* version string, resulting */ +/* in version 5.1 */ +/* 04-15-2012 William E. Lamie Modified comment(s), added */ +/* FPU enable/disable function */ +/* prototypes, and updated */ +/* version string, resulting */ +/* in version 5.2 */ +/* 01-01-2014 William E. Lamie Modified comment(s), added */ +/* FPU enable/disable struct */ +/* member, and updated */ +/* version string, resulting */ +/* in version 5.3 */ +/* 04-15-2014 William E. Lamie Modified comment(s), and */ +/* updated version string, */ +/* resulting in version 5.4 */ +/* 09-01-2014 William E. Lamie Modified comment(s), and */ +/* updated version string, */ +/* resulting in version 5.5 */ +/* 06-01-2017 William E. Lamie Modified comment(s), added */ +/* support for new thread-safe */ +/* IAR libraries, removed */ +/* unneeded VFP enable flag, */ +/* added logic to remove the */ +/* need for context */ +/* save/restore calls in ISRs, */ +/* modified code for MISRA */ +/* compliance, and updated */ +/* version string, resulting */ +/* in version 5.6 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + + +/* Determine if the optional ThreadX user define file should be used. */ + +#ifdef TX_INCLUDE_USER_DEFINE_FILE + +/* Yes, include the user defines in tx_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "tx_user.h" +#endif + + +/* Define compiler library include files. */ + +#include +#include +#include +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif + + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef short SHORT; +typedef unsigned short USHORT; + +/*enable execution profile*/ +#define TX_ENABLE_EXECUTION_CHANGE_NOTIFY + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + + +/* Define various constants for the ThreadX Cortex-M3 port. */ + +#define TX_INT_DISABLE 1 /* Disable interrupts */ +#define TX_INT_ENABLE 0 /* Enable interrupts */ + + +/* Define the clock source for trace event entry time stamp. The following two item are port specific. + For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock + source constants would be: + +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) +#define TX_TRACE_TIME_MASK 0x0000FFFFUL + +*/ + +#ifndef TX_MISRA_ENABLE +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) +#endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else +#define TX_INLINE_INITIALIZATION +#endif + + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +#ifndef TX_MISRA_ENABLE +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif +#endif + + +/* Define the TX_THREAD control block extensions for this port. The main reason + for the multiple macros is so that backward compatibility can be maintained with + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_QUEUE_EXTENSION +#define TX_SEMAPHORE_EXTENSION +#define TX_TIMER_EXTENSION + + +/* Define the user extension field of the thread control block. Nothing + additional is needed for this port so it is defined as white space. */ + +#ifndef TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION +#endif + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + + +/* Define the get system state macro. */ + +#ifndef TX_THREAD_GET_SYSTEM_STATE +#ifndef TX_MISRA_ENABLE +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) +#else +ULONG _tx_misra_ipsr_get(VOID); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) +#endif +#endif + + +/* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ + +#ifndef TX_THREAD_SYSTEM_RETURN_CHECK +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#endif + + +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to + prevent early scheduling on Cortex-M parts. */ + +#define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; + + +/* Determine if the ARM architecture has the CLZ instruction. This is available on + architectures v5 and above. If available, redefine the macro for calculating the + lowest bit set. */ + +#ifndef TX_DISABLE_INLINE + +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ + b = (UINT) __CLZ(m); \ + b = 31 - b; +#endif + + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + +#ifdef TX_DISABLE_INLINE + +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); + +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); + +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); + +#else + +#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save; +#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();}; +#define TX_RESTORE {__set_interrupt_state(interrupt_save);}; + +#define _tx_thread_system_return _tx_thread_system_return_inline + +static void _tx_thread_system_return_inline(void) +{ +__istate_t interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_IPSR() == 0) + { + interrupt_save = __get_interrupt_state(); + __enable_interrupt(); + __set_interrupt_state(interrupt_save); + } +} + +#endif + + +/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing + thread. These are no longer needed, but are preserved for backward compatibility only. */ + +void tx_thread_fpu_enable(void); +void tx_thread_fpu_disable(void); + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* Define the version ID of ThreadX. This may be utilized by the application. */ + +#ifdef TX_THREAD_INIT +CHAR _tx_version_id[] = + "Copyright (c) 1996-2017 Express Logic Inc. * ThreadX Cortex-M4/IAR Version G5.8.5.6 SN: X-WARE_PLATFORM_STM32F4_DISCOVERY_EVALUATION_VERSION_08-01-2017 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; +#else +extern CHAR _tx_version_id[]; +#endif +#endif + + +#endif + + + diff --git a/3rd_party/threadx/tm4c123xx_iar/readme_threadx.txt b/3rd_party/threadx/tm4c123xx_iar/readme_threadx.txt new file mode 100644 index 00000000..ff8f3434 --- /dev/null +++ b/3rd_party/threadx/tm4c123xx_iar/readme_threadx.txt @@ -0,0 +1,247 @@ + Express Logic's ThreadX for EK-TM4C123GXL Evaluation Board (Cortex-M4) + + Using the IAR Tools + + + *** DEMO VERSION *** + + +0. About This Version + +This version of ThreadX is for demonstration purposes only and may not +be used for any product development, either directly or indirectly. In +addition, this demonstration may not be used for any competitive purpose. + + +1. Installation + +ThreadX for EK-TM4C123GXL (Cortex-M4) is pre-installed in the evaluation package. + + +2. Building the ThreadX run-time Library + +This demonstration version contains a pre-built ThreadX library, tx.a. The library is +intended for demonstration purposes only and thus has the following limitations: + + 10 Threads + 10 Timers + 10 Event Flag Groups + 10 Mutexes + 10 Queues + 10 Semaphores + 10 Block Pool + 10 Byte Pool + + +3. Demonstration System + +The ThreadX demonstration is designed to execute on the EK-TM4C123GXL evaluation +board under the IAR Windows-based debugger. + +Building the demonstration is easy; simply make the demo_threadx.ewp project +the "active project" in the IAR Embedded Workbench and select the "Make" button. + +You should observe the compilation of demo_threadx.c (which is the demonstration +application) and linking with tx.a. The resulting file demo_threadx.out is a binary +file that can be downloaded and executed on the EK-TM4C123GXL evaluation board using +the IAR debugger. + + +4. System Initialization + +The entry point in ThreadX for the (Cortex-M4) using IAR tools is at label +__Reset_Handler. This is defined within the EK-TM4C123GXL startup code, namely +the file startup_ewarm.s. From this entry point, the IAR startup code +at __iar_program_start is called. This is where all static and global preset +C variable initialization processing takes place. + +The ThreadX tx_initialize_low_level.s file is responsible for setting up +various system data structures, and a periodic timer interrupt source. + +The _tx_initialize_low_level function inside of tx_initialize_low_level.s +also determines the first available address for use by the application, which +is supplied as the sole input parameter to your application definition function, +tx_application_define. To accomplish this, a section is created in +tx_initialize_low_level.s called FREE_MEM, which must be located after all +other RAM sections in memory. + + +5. Register Usage and Stack Frames + +The following defines the saved context stack frames for context switches +that occur as a result of interrupt handling or from thread-level API calls. +All suspended threads have the same stack frame in the Cortex-M4 version of +ThreadX. The top of the suspended thread's stack is pointed to by +tx_thread_stack_ptr in the associated thread control block TX_THREAD. + +Non-FPU Stack Frame: + + Stack Offset Stack Contents + + 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x04 r4 + 0x08 r5 + 0x0C r6 + 0x10 r7 + 0x14 r8 + 0x18 r9 + 0x1C r10 (sl) + 0x20 r11 + 0x24 r0 (Hardware stack starts here!!) + 0x28 r1 + 0x2C r2 + 0x30 r3 + 0x34 r12 + 0x38 lr + 0x3C pc + 0x40 xPSR + +FPU Stack Frame (only interrupted thread with FPU enabled): + + Stack Offset Stack Contents + + 0x00 LR Interrupted LR (LR at time of PENDSV) + 0x04 s0 + 0x08 s1 + 0x0C s2 + 0x10 s3 + 0x14 s4 + 0x18 s5 + 0x1C s6 + 0x20 s7 + 0x24 s8 + 0x28 s9 + 0x2C s10 + 0x30 s11 + 0x34 s12 + 0x38 s13 + 0x3C s14 + 0x40 s15 + 0x44 s16 + 0x48 s17 + 0x4C s18 + 0x50 s19 + 0x54 s20 + 0x58 s21 + 0x5C s22 + 0x60 s23 + 0x64 s24 + 0x68 s25 + 0x6C s26 + 0x70 s27 + 0x74 s28 + 0x78 s29 + 0x7C s30 + 0x80 s31 + 0x84 fpscr + 0x88 r4 + 0x8C r5 + 0x90 r6 + 0x94 r7 + 0x98 r8 + 0x9C r9 + 0xA0 r10 (sl) + 0xA4 r11 + 0xA8 r0 (Hardware stack starts here!!) + 0xAC r1 + 0xB0 r2 + 0xB4 r3 + 0xB8 r12 + 0xBC lr + 0xC0 pc + 0xC4 xPSR + +6. Improving Performance + +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by +compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING +defined. + + +7. Interrupt Handling + +The Cortex-M4 vectors start at the label __vector_table and is defined in cstartup_M.s. +The application may modify the vector area according to its needs. + + +7.2 Managed Interrupts + +From version 5.6 going forward, ISRs for Cortex-M using the IAR tools can be written +completely in C (or assembly language) without any calls to _tx_thread_context_save or +_tx_thread_context_restore. These ISRs are allowed access to the ThreadX API that is +available to ISRs. + +ISRs written in C will take the form (where "your_C_isr" is an entry in the vector table): + +void your_C_isr(void) +{ + + /* ISR processing goes here, including any needed function calls. */ +} + +ISRs written in assembly language will take the form: + + PUBLIC your_assembly_isr +your_assembly_isr: + + PUSH {lr} + + ; ISR processing goes here, including any needed function calls. + + POP {lr} + BX lr + +Backward compatibility to the previous style assembly ISRs is maintained, which was of +the form: + + PUBLIC __legacy_isr_handler +__legacy_isr_handler: + PUSH {lr} + BL _tx_thread_context_save + +; /* Do interrupt handler work here */ +; /* .... */ + + B _tx_thread_context_restore + + +8. IAR Thread-safe Library Support + +Thread-safe support for the IAR tools is easily enabled by building the ThreadX library +and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file +should have the following line added (if not already in place): + +initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application + +The project options "General Options -> Library Configuration" should also have the +"Enable thread support in library" box selected. + + +9. VFP Support + +When applicable, ThreadX for the EK-TM4C123GXL (Cortex-M4) supports lazy VFP support, which +means that applications threads can simply use the VFP and ThreadX automatically maintains +the VFP registers as part of the thread context - no additional setup by the application +is required. + + +10. Revision History + +08/01/2017 Initial ThreadX version for EK-TM4C123GXL (Cortex-M4) using IAR's ARM tools. + + +Copyright(c) 1996-2017 Express Logic, Inc. + + +Express Logic, Inc. +11323 West Bernardo Court +San Diego, CA 92127 + +www.expresslogic.com + diff --git a/3rd_party/threadx/tx_port.h b/3rd_party/threadx/tm4c123xx_iar/tx_port.h similarity index 69% rename from 3rd_party/threadx/tx_port.h rename to 3rd_party/threadx/tm4c123xx_iar/tx_port.h index f9a65157..f8605352 100644 --- a/3rd_party/threadx/tx_port.h +++ b/3rd_party/threadx/tm4c123xx_iar/tx_port.h @@ -1,6 +1,6 @@ /**************************************************************************/ /* */ -/* Copyright (c) 1996-2011 by Express Logic Inc. */ +/* Copyright (c) 1996-2017 by Express Logic Inc. */ /* */ /* This software is copyrighted by and is the sole property of Express */ /* Logic, Inc. All rights, title, ownership, or other interests */ @@ -38,7 +38,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_port.h Cortex-M4/IAR */ -/* 5.1 */ +/* 5.6 */ /* */ /* AUTHOR */ /* */ @@ -66,6 +66,33 @@ /* support, and updated */ /* version string, resulting */ /* in version 5.1 */ +/* 04-15-2012 William E. Lamie Modified comment(s), added */ +/* FPU enable/disable function */ +/* prototypes, and updated */ +/* version string, resulting */ +/* in version 5.2 */ +/* 01-01-2014 William E. Lamie Modified comment(s), added */ +/* FPU enable/disable struct */ +/* member, and updated */ +/* version string, resulting */ +/* in version 5.3 */ +/* 04-15-2014 William E. Lamie Modified comment(s), and */ +/* updated version string, */ +/* resulting in version 5.4 */ +/* 09-01-2014 William E. Lamie Modified comment(s), and */ +/* updated version string, */ +/* resulting in version 5.5 */ +/* 06-01-2017 William E. Lamie Modified comment(s), added */ +/* support for new thread-safe */ +/* IAR libraries, removed */ +/* unneeded VFP enable flag, */ +/* added logic to remove the */ +/* need for context */ +/* save/restore calls in ISRs, */ +/* modified code for MISRA */ +/* compliance, and updated */ +/* version string, resulting */ +/* in version 5.6 */ /* */ /**************************************************************************/ @@ -73,14 +100,6 @@ #define TX_PORT_H -/* Define default parameters for the Cortex-M4 build for smaller footprint. */ - -#define TX_TIMER_PROCESS_IN_ISR -#define TX_DISABLE_PREEMPTION_THRESHOLD -#define TX_DISABLE_NOTIFY_CALLBACKS -#define TX_DISABLE_ERROR_CHECKING - - /* Determine if the optional ThreadX user define file should be used. */ #ifdef TX_INCLUDE_USER_DEFINE_FILE @@ -158,9 +177,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -169,14 +194,18 @@ typedef unsigned short USHORT; /* Define the port specific options for the _tx_build_options variable. This variable indicates how the ThreadX library was built. */ -#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0 +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (0) /* Define the in-line initialization constant so that modules with in-line initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif /* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is @@ -185,9 +214,11 @@ typedef unsigned short USHORT; define is negated, thereby forcing the stack fill which is necessary for the stack checking logic. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#endif /* Define the TX_THREAD control block extensions for this port. The main reason @@ -196,11 +227,16 @@ typedef unsigned short USHORT; #define TX_THREAD_EXTENSION_0 #define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT -#define TX_THREAD_EXTENSION_3 VOID *tx_thread_iar_tls_pointer; +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; #else +#define TX_THREAD_EXTENSION_2 +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; #endif @@ -228,11 +264,22 @@ typedef unsigned short USHORT; #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) #define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else #define TX_THREAD_CREATE_EXTENSION(thread_ptr) #define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif @@ -262,13 +309,44 @@ typedef unsigned short USHORT; #define TX_TIMER_DELETE_EXTENSION(timer_ptr) +/* Define the get system state macro. */ + +#ifndef TX_THREAD_GET_SYSTEM_STATE +#ifndef TX_MISRA_ENABLE +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) +#else +ULONG _tx_misra_ipsr_get(VOID); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) +#endif +#endif + + +/* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ + +#ifndef TX_THREAD_SYSTEM_RETURN_CHECK +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#endif + + +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to + prevent early scheduling on Cortex-M parts. */ + +#define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; + + /* Determine if the ARM architecture has the CLZ instruction. This is available on architectures v5 and above. If available, redefine the macro for calculating the lowest bit set. */ +#ifndef TX_DISABLE_INLINE + #define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ b = (UINT) __CLZ(m); \ b = 31 - b; +#endif /* Define ThreadX interrupt lockout and restore macros for protection on @@ -278,21 +356,16 @@ typedef unsigned short USHORT; is used to define a local function save area for the disable and restore macros. */ -/* The embedded assembler blocks are design so as to be inlinable by the - armlink linker inlining. This requires them to consist of either a - single 32-bit instruction, or either one or two 16-bit instructions - followed by a "BX lr". Note that to reduce the critical region size, the - 16-bit "CPSID i" instruction is preceeded by a 16-bit NOP */ - #ifdef TX_DISABLE_INLINE -unsigned int _tx_thread_interrupt_control(unsigned int new_posture); +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA register int interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); #else @@ -300,11 +373,27 @@ unsigned int _tx_thread_interrupt_control(uns #define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();}; #define TX_RESTORE {__set_interrupt_state(interrupt_save);}; +#define _tx_thread_system_return _tx_thread_system_return_inline + +static void _tx_thread_system_return_inline(void) +{ +__istate_t interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_IPSR() == 0) + { + interrupt_save = __get_interrupt_state(); + __enable_interrupt(); + __set_interrupt_state(interrupt_save); + } +} + #endif /* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing - thread. */ + thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); void tx_thread_fpu_disable(void); @@ -324,10 +413,17 @@ void tx_thread_fpu_disable(void); #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "Copyright (c) 1996-2012 Express Logic Inc. * ThreadX Cortex-M4/IAR Version G5.5.5.1 SN: Evaluation_Only_Version_012012 *"; + "Copyright (c) 1996-2017 Express Logic Inc. * ThreadX Cortex-M4/IAR Version G5.8.5.6 SN: X-WARE_PLATFORM_EK-TM4C123GXL_LaunchPad_Evaluation_Version_08-01-2017 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif +#endif #endif + + + diff --git a/3rd_party/threadx/tx_api.h b/3rd_party/threadx/tx_api.h index 9fb03858..52a1307e 100644 --- a/3rd_party/threadx/tx_api.h +++ b/3rd_party/threadx/tx_api.h @@ -1,6 +1,6 @@ /**************************************************************************/ /* */ -/* Copyright (c) 1996-2011 by Express Logic Inc. */ +/* Copyright (c) 1996-2017 by Express Logic Inc. */ /* */ /* This software is copyrighted by and is the sole property of Express */ /* Logic, Inc. All rights, title, ownership, or other interests */ @@ -16,7 +16,7 @@ /* without notice. */ /* */ /* Express Logic, Inc. info@expresslogic.com */ -/* 11423 West Bernardo Court http://www.expresslogic.com */ +/* 11423 West Bernardo Court www.expresslogic.com */ /* San Diego, CA 92127 */ /* */ /**************************************************************************/ @@ -38,7 +38,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* tx_api.h PORTABLE C */ -/* 5.5 */ +/* 5.8 */ /* AUTHOR */ /* */ /* William E. Lamie, Express Logic, Inc. */ @@ -91,6 +91,35 @@ /* threshold mutex structure */ /* member, resulting in */ /* version 5.5 */ +/* 11-01-2012 William E. Lamie Modified comment(s), and */ +/* modified minor version */ +/* define, resulting in */ +/* version 5.6 */ +/* 05-01-2015 William E. Lamie Modified comment(s), modified */ +/* code for MISRA compliance, */ +/* modified minor version */ +/* define, added thread start */ +/* macro for performing port */ +/* and/or user specified */ +/* processing when a thread */ +/* starts, and added constant */ +/* TX_TIMER_TICKS_PER_SECOND */ +/* for use by other middleware */ +/* components as a common time */ +/* reference, resulting in */ +/* version 5.7 */ +/* 06-01-2017 William E. Lamie Modified comment(s), changed */ +/* minor version constant, */ +/* added suspension sequence to*/ +/* verify cleanup is still */ +/* necessary, made MISRA */ +/* compatibility changes, */ +/* added alignment type for */ +/* memory pools, corrected */ +/* compiler warnings in macro */ +/* definitions, added support */ +/* for optional extensions, */ +/* resulting in version 5.8 */ /* */ /**************************************************************************/ @@ -120,103 +149,108 @@ extern "C" { /* Define the major/minor version information that can be used by the application and the ThreadX source as well. */ -#define __PRODUCT_THREADX__ -#define __THREADX_MAJOR_VERSION 5 -#define __THREADX_MINOR_VERSION 5 +#define EL_PRODUCT_THREADX +#define THREADX_MAJOR_VERSION 5 +#define THREADX_MINOR_VERSION 8 /* API input parameters and general constants. */ -#define TX_NO_WAIT 0 -#define TX_WAIT_FOREVER ((ULONG) 0xFFFFFFFF) -#define TX_AND 2 -#define TX_AND_CLEAR 3 -#define TX_OR 0 -#define TX_OR_CLEAR 1 -#define TX_1_ULONG 1 -#define TX_2_ULONG 2 -#define TX_4_ULONG 4 -#define TX_8_ULONG 8 -#define TX_16_ULONG 16 -#define TX_NO_TIME_SLICE 0 -#define TX_AUTO_START 1 -#define TX_DONT_START 0 -#define TX_AUTO_ACTIVATE 1 -#define TX_NO_ACTIVATE 0 -#define TX_TRUE 1 -#define TX_FALSE 0 -#define TX_NULL (void *) 0 -#define TX_LOOP_FOREVER 1 -#define TX_INHERIT 1 -#define TX_NO_INHERIT 0 -#define TX_THREAD_ENTRY 0 -#define TX_THREAD_EXIT 1 -#define TX_STACK_FILL ((ULONG) 0xEFEFEFEF) +#define TX_NO_WAIT ((ULONG) 0) +#define TX_WAIT_FOREVER ((ULONG) 0xFFFFFFFFUL) +#define TX_AND ((UINT) 2) +#define TX_AND_CLEAR ((UINT) 3) +#define TX_OR ((UINT) 0) +#define TX_OR_CLEAR ((UINT) 1) +#define TX_1_ULONG ((UINT) 1) +#define TX_2_ULONG ((UINT) 2) +#define TX_4_ULONG ((UINT) 4) +#define TX_8_ULONG ((UINT) 8) +#define TX_16_ULONG ((UINT) 16) +#define TX_NO_TIME_SLICE ((ULONG) 0) +#define TX_AUTO_START ((UINT) 1) +#define TX_DONT_START ((UINT) 0) +#define TX_AUTO_ACTIVATE ((UINT) 1) +#define TX_NO_ACTIVATE ((UINT) 0) +#define TX_TRUE ((UINT) 1) +#define TX_FALSE ((UINT) 0) +#define TX_NULL ((void *) 0) +#define TX_INHERIT ((UINT) 1) +#define TX_NO_INHERIT ((UINT) 0) +#define TX_THREAD_ENTRY ((UINT) 0) +#define TX_THREAD_EXIT ((UINT) 1) +#define TX_NO_SUSPENSIONS ((UINT) 0) +#define TX_NO_MESSAGES ((UINT) 0) +#define TX_EMPTY ((ULONG) 0) +#define TX_CLEAR_ID ((ULONG) 0) +#define TX_STACK_FILL ((ULONG) 0xEFEFEFEFUL) /* Thread execution state values. */ -#define TX_READY 0 -#define TX_COMPLETED 1 -#define TX_TERMINATED 2 -#define TX_SUSPENDED 3 -#define TX_SLEEP 4 -#define TX_QUEUE_SUSP 5 -#define TX_SEMAPHORE_SUSP 6 -#define TX_EVENT_FLAG 7 -#define TX_BLOCK_MEMORY 8 -#define TX_BYTE_MEMORY 9 -#define TX_IO_DRIVER 10 -#define TX_FILE 11 -#define TX_TCP_IP 12 -#define TX_MUTEX_SUSP 13 +#define TX_READY ((UINT) 0) +#define TX_COMPLETED ((UINT) 1) +#define TX_TERMINATED ((UINT) 2) +#define TX_SUSPENDED ((UINT) 3) +#define TX_SLEEP ((UINT) 4) +#define TX_QUEUE_SUSP ((UINT) 5) +#define TX_SEMAPHORE_SUSP ((UINT) 6) +#define TX_EVENT_FLAG ((UINT) 7) +#define TX_BLOCK_MEMORY ((UINT) 8) +#define TX_BYTE_MEMORY ((UINT) 9) +#define TX_IO_DRIVER ((UINT) 10) +#define TX_FILE ((UINT) 11) +#define TX_TCP_IP ((UINT) 12) +#define TX_MUTEX_SUSP ((UINT) 13) /* API return values. */ -#define TX_SUCCESS 0x00 -#define TX_DELETED 0x01 -#define TX_NO_MEMORY 0x10 -#define TX_POOL_ERROR 0x02 -#define TX_PTR_ERROR 0x03 -#define TX_WAIT_ERROR 0x04 -#define TX_SIZE_ERROR 0x05 -#define TX_GROUP_ERROR 0x06 -#define TX_NO_EVENTS 0x07 -#define TX_OPTION_ERROR 0x08 -#define TX_QUEUE_ERROR 0x09 -#define TX_QUEUE_EMPTY 0x0A -#define TX_QUEUE_FULL 0x0B -#define TX_SEMAPHORE_ERROR 0x0C -#define TX_NO_INSTANCE 0x0D -#define TX_THREAD_ERROR 0x0E -#define TX_PRIORITY_ERROR 0x0F -#define TX_START_ERROR 0x10 -#define TX_DELETE_ERROR 0x11 -#define TX_RESUME_ERROR 0x12 -#define TX_CALLER_ERROR 0x13 -#define TX_SUSPEND_ERROR 0x14 -#define TX_TIMER_ERROR 0x15 -#define TX_TICK_ERROR 0x16 -#define TX_ACTIVATE_ERROR 0x17 -#define TX_THRESH_ERROR 0x18 -#define TX_SUSPEND_LIFTED 0x19 -#define TX_WAIT_ABORTED 0x1A -#define TX_WAIT_ABORT_ERROR 0x1B -#define TX_MUTEX_ERROR 0x1C -#define TX_NOT_AVAILABLE 0x1D -#define TX_NOT_OWNED 0x1E -#define TX_INHERIT_ERROR 0x1F -#define TX_NOT_DONE 0x20 -#define TX_CEILING_EXCEEDED 0x21 -#define TX_INVALID_CEILING 0x22 -#define TX_FEATURE_NOT_ENABLED 0xFF +#define TX_SUCCESS ((UINT) 0x00) +#define TX_DELETED ((UINT) 0x01) +#define TX_NO_MEMORY ((UINT) 0x10) +#define TX_POOL_ERROR ((UINT) 0x02) +#define TX_PTR_ERROR ((UINT) 0x03) +#define TX_WAIT_ERROR ((UINT) 0x04) +#define TX_SIZE_ERROR ((UINT) 0x05) +#define TX_GROUP_ERROR ((UINT) 0x06) +#define TX_NO_EVENTS ((UINT) 0x07) +#define TX_OPTION_ERROR ((UINT) 0x08) +#define TX_QUEUE_ERROR ((UINT) 0x09) +#define TX_QUEUE_EMPTY ((UINT) 0x0A) +#define TX_QUEUE_FULL ((UINT) 0x0B) +#define TX_SEMAPHORE_ERROR ((UINT) 0x0C) +#define TX_NO_INSTANCE ((UINT) 0x0D) +#define TX_THREAD_ERROR ((UINT) 0x0E) +#define TX_PRIORITY_ERROR ((UINT) 0x0F) +#define TX_START_ERROR ((UINT) 0x10) +#define TX_DELETE_ERROR ((UINT) 0x11) +#define TX_RESUME_ERROR ((UINT) 0x12) +#define TX_CALLER_ERROR ((UINT) 0x13) +#define TX_SUSPEND_ERROR ((UINT) 0x14) +#define TX_TIMER_ERROR ((UINT) 0x15) +#define TX_TICK_ERROR ((UINT) 0x16) +#define TX_ACTIVATE_ERROR ((UINT) 0x17) +#define TX_THRESH_ERROR ((UINT) 0x18) +#define TX_SUSPEND_LIFTED ((UINT) 0x19) +#define TX_WAIT_ABORTED ((UINT) 0x1A) +#define TX_WAIT_ABORT_ERROR ((UINT) 0x1B) +#define TX_MUTEX_ERROR ((UINT) 0x1C) +#define TX_NOT_AVAILABLE ((UINT) 0x1D) +#define TX_NOT_OWNED ((UINT) 0x1E) +#define TX_INHERIT_ERROR ((UINT) 0x1F) +#define TX_NOT_DONE ((UINT) 0x20) +#define TX_CEILING_EXCEEDED ((UINT) 0x21) +#define TX_INVALID_CEILING ((UINT) 0x22) +#define TX_FEATURE_NOT_ENABLED ((UINT) 0xFF) -/* Define the TX_MEMSET macro to the standard library function, if not already defined. */ +/* Define the common timer tick reference for use by other middleware components. The default + value is 10ms, but may be replaced by a port specific version in tx_port.h or by the user + as a compilation option. */ -#ifndef TX_MEMSET -#define TX_MEMSET(a,b,c) memset(a,b,c) +#ifndef TX_TIMER_TICKS_PER_SECOND +#define TX_TIMER_TICKS_PER_SECOND ((ULONG) 100) #endif @@ -226,30 +260,39 @@ extern "C" { FileX events: 200-299 NetX events: 300-599 USBX events: 600-999 + GUIX events: 1000-1500 User-defined event numbers start at 4096 and continue through 65535, as defined by the constants TX_TRACE_USER_EVENT_START and TX_TRACE_USER_EVENT_END, respectively. User events should be based on these constants in case the user event number assignment is changed in future releases. */ -#define TX_TRACE_USER_EVENT_START 4096 /* I1, I2, I3, I4 are user defined */ -#define TX_TRACE_USER_EVENT_END 65535 /* I1, I2, I3, I4 are user defined */ +#define TX_TRACE_USER_EVENT_START 4096 /* I1, I2, I3, I4 are user defined */ +#define TX_TRACE_USER_EVENT_END 65535 /* I1, I2, I3, I4 are user defined */ /* Define event filters that can be used to selectively disable certain events or groups of events. */ -#define TX_TRACE_ALL_EVENTS 0x000007FF /* All ThreadX events */ -#define TX_TRACE_INTERNAL_EVENTS 0x00000001 /* ThreadX internal events */ -#define TX_TRACE_BLOCK_POOL_EVENTS 0x00000002 /* ThreadX Block Pool events */ -#define TX_TRACE_BYTE_POOL_EVENTS 0x00000004 /* ThreadX Byte Pool events */ -#define TX_TRACE_EVENT_FLAGS_EVENTS 0x00000008 /* ThreadX Event Flags events */ -#define TX_TRACE_INTERRUPT_CONTROL_EVENT 0x00000010 /* ThreadX Interrupt Control events */ -#define TX_TRACE_MUTEX_EVENTS 0x00000020 /* ThreadX Mutex events */ -#define TX_TRACE_QUEUE_EVENTS 0x00000040 /* ThreadX Queue events */ -#define TX_TRACE_SEMAPHORE_EVENTS 0x00000080 /* ThreadX Semaphore events */ -#define TX_TRACE_THREAD_EVENTS 0x00000100 /* ThreadX Thread events */ -#define TX_TRACE_TIME_EVENTS 0x00000200 /* ThreadX Time events */ -#define TX_TRACE_TIMER_EVENTS 0x00000400 /* ThreadX Timer events */ -#define TX_TRACE_USER_EVENTS 0x80000000 /* ThreadX User Events */ +#define TX_TRACE_ALL_EVENTS 0x000007FF /* All ThreadX events */ +#define TX_TRACE_INTERNAL_EVENTS 0x00000001 /* ThreadX internal events */ +#define TX_TRACE_BLOCK_POOL_EVENTS 0x00000002 /* ThreadX Block Pool events */ +#define TX_TRACE_BYTE_POOL_EVENTS 0x00000004 /* ThreadX Byte Pool events */ +#define TX_TRACE_EVENT_FLAGS_EVENTS 0x00000008 /* ThreadX Event Flags events */ +#define TX_TRACE_INTERRUPT_CONTROL_EVENT 0x00000010 /* ThreadX Interrupt Control events */ +#define TX_TRACE_MUTEX_EVENTS 0x00000020 /* ThreadX Mutex events */ +#define TX_TRACE_QUEUE_EVENTS 0x00000040 /* ThreadX Queue events */ +#define TX_TRACE_SEMAPHORE_EVENTS 0x00000080 /* ThreadX Semaphore events */ +#define TX_TRACE_THREAD_EVENTS 0x00000100 /* ThreadX Thread events */ +#define TX_TRACE_TIME_EVENTS 0x00000200 /* ThreadX Time events */ +#define TX_TRACE_TIMER_EVENTS 0x00000400 /* ThreadX Timer events */ +#define TX_TRACE_USER_EVENTS 0x80000000UL /* ThreadX User Events */ + + +/* Define basic alignment type used in block and byte pool operations. This data type must + be at least 32-bits in size and also be large enough to hold a pointer type. */ + +#ifndef ALIGN_TYPE_DEFINED +#define ALIGN_TYPE ULONG +#endif /* Define the control block definitions for all system objects. */ @@ -258,6 +301,14 @@ extern "C" { /* Define the basic timer management structures. These are the structures used to manage thread sleep, timeout, and user timer requests. */ +/* Determine if the internal timer control block has an extension defined. If not, + define the extension to whitespace. */ + +#ifndef TX_TIMER_INTERNAL_EXTENSION +#define TX_TIMER_INTERNAL_EXTENSION +#endif + + /* Define the common internal timer control block. */ typedef struct TX_TIMER_INTERNAL_STRUCT @@ -268,7 +319,7 @@ typedef struct TX_TIMER_INTERNAL_STRUCT ULONG tx_timer_internal_re_initialize_ticks; /* Define the timeout function and timeout function parameter. */ - VOID (*tx_timer_internal_timeout_function)(ULONG); + VOID (*tx_timer_internal_timeout_function)(ULONG id); ULONG tx_timer_internal_timeout_param; @@ -281,9 +332,21 @@ typedef struct TX_TIMER_INTERNAL_STRUCT /* Keep track of the pointer to the head of this list as well. */ struct TX_TIMER_INTERNAL_STRUCT **tx_timer_internal_list_head; + + /* Define optional extension to internal timer control block. */ + TX_TIMER_INTERNAL_EXTENSION + } TX_TIMER_INTERNAL; +/* Determine if the timer control block has an extension defined. If not, + define the extension to whitespace. */ + +#ifndef TX_TIMER_EXTENSION +#define TX_TIMER_EXTENSION +#endif + + /* Define the timer structure utilized by the application. */ typedef struct TX_TIMER_STRUCT @@ -304,6 +367,9 @@ typedef struct TX_TIMER_STRUCT *tx_timer_created_next, *tx_timer_created_previous; + /* Define optional extension to timer control block. */ + TX_TIMER_EXTENSION + #ifdef TX_TIMER_ENABLE_PERFORMANCE_INFO /* Define the number of timer activations. */ @@ -319,7 +385,7 @@ typedef struct TX_TIMER_STRUCT ULONG tx_timer_performance_expiration_count; /* Define the total number of timer expiration adjustments. */ - ULONG tx_timer_performance_expiration_adjust_count; + ULONG tx_timer_performance__expiration_adjust_count; #endif } TX_TIMER; @@ -366,7 +432,7 @@ typedef struct TX_THREAD_STRUCT /* Define the thread schedule hook. The usage of this is port/application specific, but when used, the function pointer designated is called whenever the thread is scheduled and unscheduled. */ - VOID (*tx_thread_schedule_hook)(struct TX_THREAD_STRUCT *, ULONG); + VOID (*tx_thread_schedule_hook)(struct TX_THREAD_STRUCT *thread_ptr, ULONG id); /* Nothing after this point is referenced by the target-specific assembly language. Hence, information after this point can @@ -374,7 +440,7 @@ typedef struct TX_THREAD_STRUCT is recompiled. */ /* Define the thread's entry point and input parameter. */ - VOID (*tx_thread_entry)(ULONG); + VOID (*tx_thread_entry)(ULONG id); ULONG tx_thread_entry_parameter; /* Define the thread's timer block. This is used for thread @@ -385,7 +451,7 @@ typedef struct TX_THREAD_STRUCT is used to cleanup various data structures when a thread suspension is lifted or terminated either by the user or a timeout. */ - VOID (*tx_thread_suspend_cleanup)(struct TX_THREAD_STRUCT *); + VOID (*tx_thread_suspend_cleanup)(struct TX_THREAD_STRUCT *thread_ptr, ULONG suspension_sequence); VOID *tx_thread_suspend_control_block; struct TX_THREAD_STRUCT *tx_thread_suspended_next, @@ -418,6 +484,8 @@ typedef struct TX_THREAD_STRUCT UINT tx_thread_user_priority; UINT tx_thread_user_preempt_threshold; UINT tx_thread_inherit_priority; + + /* Define the owned mutex count and list head pointer. */ UINT tx_thread_owned_mutex_count; struct TX_MUTEX_STRUCT *tx_thread_owned_mutex_list; @@ -467,13 +535,17 @@ typedef struct TX_THREAD_STRUCT /* Define the application callback routine used to notify the application when the thread is entered or exits. */ - VOID (*tx_thread_entry_exit_notify)(struct TX_THREAD_STRUCT *, UINT); + VOID (*tx_thread_entry_exit_notify)(struct TX_THREAD_STRUCT *thread_ptr, UINT type); #endif /* Define the fourth port extension in the thread control block. This is typically defined to whitespace in tx_port.h. */ TX_THREAD_EXTENSION_3 + /* Define suspension sequence number. This is used to ensure suspension is still valid when + cleanup routine executes. */ + ULONG tx_thread_suspension_sequence; + /* Define the user extension field. This typically is defined to white space, but some ports of ThreadX may need to have additional fields in the thread control block. This is @@ -545,6 +617,22 @@ typedef struct TX_BLOCK_POOL_STRUCT } TX_BLOCK_POOL; +/* Determine if the byte allocate extension is defined. If not, define the + extension to whitespace. */ + +#ifndef TX_BYTE_ALLOCATE_EXTENSION +#define TX_BYTE_ALLOCATE_EXTENSION +#endif + + +/* Determine if the byte release extension is defined. If not, define the + extension to whitespace. */ + +#ifndef TX_BYTE_RELEASE_EXTENSION +#define TX_BYTE_RELEASE_EXTENSION +#endif + + /* Define the byte memory pool structure utilized by the application. */ typedef struct TX_BYTE_POOL_STRUCT @@ -663,20 +751,20 @@ typedef struct TX_EVENT_FLAGS_GROUP_STRUCT ULONG tx_event_flags_group_performance_set_count; /* Define the number of event flag gets. */ - ULONG tx_event_flags_group_performance_get_count; + ULONG tx_event_flags_group__performance_get_count; /* Define the number of event flag suspensions. */ - ULONG tx_event_flags_group_performance_suspension_count; + ULONG tx_event_flags_group___performance_suspension_count; /* Define the number of event flag timeouts. */ - ULONG tx_event_flags_group_performance_timeout_count; + ULONG tx_event_flags_group____performance_timeout_count; #endif #ifndef TX_DISABLE_NOTIFY_CALLBACKS /* Define the application callback routine used to notify the application when an event flag is set. */ - VOID (*tx_event_flags_group_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *); + VOID (*tx_event_flags_group_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr); #endif /* Define the port extension in the event flags group control block. This @@ -686,6 +774,30 @@ typedef struct TX_EVENT_FLAGS_GROUP_STRUCT } TX_EVENT_FLAGS_GROUP; +/* Determine if the mutex put extension 1 is defined. If not, define the + extension to whitespace. */ + +#ifndef TX_MUTEX_PUT_EXTENSION_1 +#define TX_MUTEX_PUT_EXTENSION_1 +#endif + + +/* Determine if the mutex put extension 2 is defined. If not, define the + extension to whitespace. */ + +#ifndef TX_MUTEX_PUT_EXTENSION_2 +#define TX_MUTEX_PUT_EXTENSION_2 +#endif + + +/* Determine if the mutex priority change extension is defined. If not, define the + extension to whitespace. */ + +#ifndef TX_MUTEX_PRIORITY_CHANGE_EXTENSION +#define TX_MUTEX_PRIORITY_CHANGE_EXTENSION +#endif + + /* Define the mutex structure utilized by the application. */ typedef struct TX_MUTEX_STRUCT @@ -749,7 +861,7 @@ typedef struct TX_MUTEX_STRUCT ULONG tx_mutex_performance_priority_inversion_count; /* Define the total number of priority inheritance conditions. */ - ULONG tx_mutex_performance_priority_inheritance_count; + ULONG tx_mutex_performance__priority_inheritance_count; #endif /* Define the port extension in the mutex control block. This @@ -828,7 +940,7 @@ typedef struct TX_QUEUE_STRUCT /* Define the application callback routine used to notify the application when the a message is sent to the queue. */ - VOID (*tx_queue_send_notify)(struct TX_QUEUE_STRUCT *); + VOID (*tx_queue_send_notify)(struct TX_QUEUE_STRUCT *queue_ptr); #endif /* Define the port extension in the queue control block. This @@ -883,7 +995,7 @@ typedef struct TX_SEMAPHORE_STRUCT /* Define the application callback routine used to notify the application when the a semaphore is put. */ - VOID (*tx_semaphore_put_notify)(struct TX_SEMAPHORE_STRUCT *); + VOID (*tx_semaphore_put_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr); #endif /* Define the port extension in the semaphore control block. This @@ -1038,7 +1150,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); /* Services with MULTI runtime error checking ThreadX. */ #define tx_block_allocate _txr_block_allocate -#define tx_block_pool_create(p,n,b,s,l) _txr_block_pool_create(p,n,b,s,l,sizeof(TX_BLOCK_POOL)) +#define tx_block_pool_create(p,n,b,s,l) _txr_block_pool_create((p),(n),(b),(s),(l),(sizeof(TX_BLOCK_POOL))) #define tx_block_pool_delete _txr_block_pool_delete #define tx_block_pool_info_get _txr_block_pool_info_get #define tx_block_pool_performance_info_get _tx_block_pool_performance_info_get @@ -1047,7 +1159,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_block_release _txr_block_release #define tx_byte_allocate _txr_byte_allocate -#define tx_byte_pool_create(p,n,s,l) _txr_byte_pool_create(p,n,s,l,sizeof(TX_BYTE_POOL)) +#define tx_byte_pool_create(p,n,s,l) _txr_byte_pool_create((p),(n),(s),(l),(sizeof(TX_BYTE_POOL))) #define tx_byte_pool_delete _txr_byte_pool_delete #define tx_byte_pool_info_get _txr_byte_pool_info_get #define tx_byte_pool_performance_info_get _tx_byte_pool_performance_info_get @@ -1055,7 +1167,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_byte_pool_prioritize _txr_byte_pool_prioritize #define tx_byte_release _txr_byte_release -#define tx_event_flags_create(g,n) _txr_event_flags_create(g,n,sizeof(TX_EVENT_FLAGS_GROUP)) +#define tx_event_flags_create(g,n) _txr_event_flags_create((g),(n),(sizeof(TX_EVENT_FLAGS_GROUP))) #define tx_event_flags_delete _txr_event_flags_delete #define tx_event_flags_get _txr_event_flags_get #define tx_event_flags_info_get _txr_event_flags_info_get @@ -1076,7 +1188,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #endif #endif -#define tx_mutex_create(m,n,i) _txr_mutex_create(m,n,i,sizeof(TX_MUTEX)) +#define tx_mutex_create(m,n,i) _txr_mutex_create((m),(n),(i),(sizeof(TX_MUTEX))) #define tx_mutex_delete _txr_mutex_delete #define tx_mutex_get _txr_mutex_get #define tx_mutex_info_get _txr_mutex_info_get @@ -1085,7 +1197,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_mutex_prioritize _txr_mutex_prioritize #define tx_mutex_put _txr_mutex_put -#define tx_queue_create(q,n,m,s,l) _txr_queue_create(q,n,m,s,l,sizeof(TX_QUEUE)) +#define tx_queue_create(q,n,m,s,l) _txr_queue_create((q),(n),(m),(s),(l),(sizeof(TX_QUEUE))) #define tx_queue_delete _txr_queue_delete #define tx_queue_flush _txr_queue_flush #define tx_queue_info_get _txr_queue_info_get @@ -1098,7 +1210,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_queue_prioritize _txr_queue_prioritize #define tx_semaphore_ceiling_put _txr_semaphore_ceiling_put -#define tx_semaphore_create(s,n,i) _txr_semaphore_create(s,n,i,sizeof(TX_SEMAPHORE)) +#define tx_semaphore_create(s,n,i) _txr_semaphore_create((s),(n),(i),(sizeof(TX_SEMAPHORE))) #define tx_semaphore_delete _txr_semaphore_delete #define tx_semaphore_get _txr_semaphore_get #define tx_semaphore_info_get _txr_semaphore_info_get @@ -1108,7 +1220,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_semaphore_put _txr_semaphore_put #define tx_semaphore_put_notify _txr_semaphore_put_notify -#define tx_thread_create(t,n,e,i,s,l,p,r,c,a) _txr_thread_create(t,n,e,i,s,l,p,r,c,a,sizeof(TX_THREAD)) +#define tx_thread_create(t,n,e,i,s,l,p,r,c,a) _txr_thread_create((t),(n),(e),(i),(s),(l),(p),(r),(c),(a),(sizeof(TX_THREAD))) #define tx_thread_delete _txr_thread_delete #define tx_thread_entry_exit_notify _txr_thread_entry_exit_notify #define tx_thread_identify _tx_thread_identify @@ -1131,7 +1243,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_time_set _tx_time_set #define tx_timer_activate _txr_timer_activate #define tx_timer_change _txr_timer_change -#define tx_timer_create(t,n,e,i,c,r,a) _txr_timer_create(t,n,e,i,c,r,a,sizeof(TX_TIMER)) +#define tx_timer_create(t,n,e,i,c,r,a) _txr_timer_create((t),(n),(e),(i),(c),(r),(a),(sizeof(TX_TIMER))) #define tx_timer_deactivate _txr_timer_deactivate #define tx_timer_delete _txr_timer_delete #define tx_timer_info_get _txr_timer_info_get @@ -1150,7 +1262,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #else #define tx_block_allocate _txe_block_allocate -#define tx_block_pool_create(p,n,b,s,l) _txe_block_pool_create(p,n,b,s,l,sizeof(TX_BLOCK_POOL)) +#define tx_block_pool_create(p,n,b,s,l) _txe_block_pool_create((p),(n),(b),(s),(l),(sizeof(TX_BLOCK_POOL))) #define tx_block_pool_delete _txe_block_pool_delete #define tx_block_pool_info_get _txe_block_pool_info_get #define tx_block_pool_performance_info_get _tx_block_pool_performance_info_get @@ -1159,7 +1271,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_block_release _txe_block_release #define tx_byte_allocate _txe_byte_allocate -#define tx_byte_pool_create(p,n,s,l) _txe_byte_pool_create(p,n,s,l,sizeof(TX_BYTE_POOL)) +#define tx_byte_pool_create(p,n,s,l) _txe_byte_pool_create((p),(n),(s),(l),(sizeof(TX_BYTE_POOL))) #define tx_byte_pool_delete _txe_byte_pool_delete #define tx_byte_pool_info_get _txe_byte_pool_info_get #define tx_byte_pool_performance_info_get _tx_byte_pool_performance_info_get @@ -1167,7 +1279,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_byte_pool_prioritize _txe_byte_pool_prioritize #define tx_byte_release _txe_byte_release -#define tx_event_flags_create(g,n) _txe_event_flags_create(g,n,sizeof(TX_EVENT_FLAGS_GROUP)) +#define tx_event_flags_create(g,n) _txe_event_flags_create((g),(n),(sizeof(TX_EVENT_FLAGS_GROUP))) #define tx_event_flags_delete _txe_event_flags_delete #define tx_event_flags_get _txe_event_flags_get #define tx_event_flags_info_get _txe_event_flags_info_get @@ -1181,14 +1293,13 @@ UINT _tx_el_interrupt_control(UINT new_posture); #define tx_interrupt_control _tx_el_interrupt_control #else #ifdef TX_ENABLE_EVENT_TRACE -UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_interrupt_control _tx_trace_interrupt_control #else #define tx_interrupt_control _tx_thread_interrupt_control #endif #endif -#define tx_mutex_create(m,n,i) _txe_mutex_create(m,n,i,sizeof(TX_MUTEX)) +#define tx_mutex_create(m,n,i) _txe_mutex_create((m),(n),(i),(sizeof(TX_MUTEX))) #define tx_mutex_delete _txe_mutex_delete #define tx_mutex_get _txe_mutex_get #define tx_mutex_info_get _txe_mutex_info_get @@ -1197,7 +1308,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_mutex_prioritize _txe_mutex_prioritize #define tx_mutex_put _txe_mutex_put -#define tx_queue_create(q,n,m,s,l) _txe_queue_create(q,n,m,s,l,sizeof(TX_QUEUE)) +#define tx_queue_create(q,n,m,s,l) _txe_queue_create((q),(n),(m),(s),(l),(sizeof(TX_QUEUE))) #define tx_queue_delete _txe_queue_delete #define tx_queue_flush _txe_queue_flush #define tx_queue_info_get _txe_queue_info_get @@ -1210,7 +1321,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_queue_prioritize _txe_queue_prioritize #define tx_semaphore_ceiling_put _txe_semaphore_ceiling_put -#define tx_semaphore_create(s,n,i) _txe_semaphore_create(s,n,i,sizeof(TX_SEMAPHORE)) +#define tx_semaphore_create(s,n,i) _txe_semaphore_create((s),(n),(i),(sizeof(TX_SEMAPHORE))) #define tx_semaphore_delete _txe_semaphore_delete #define tx_semaphore_get _txe_semaphore_get #define tx_semaphore_info_get _txe_semaphore_info_get @@ -1220,7 +1331,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_semaphore_put _txe_semaphore_put #define tx_semaphore_put_notify _txe_semaphore_put_notify -#define tx_thread_create(t,n,e,i,s,l,p,r,c,a) _txe_thread_create(t,n,e,i,s,l,p,r,c,a,sizeof(TX_THREAD)) +#define tx_thread_create(t,n,e,i,s,l,p,r,c,a) _txe_thread_create((t),(n),(e),(i),(s),(l),(p),(r),(c),(a),(sizeof(TX_THREAD))) #define tx_thread_delete _txe_thread_delete #define tx_thread_entry_exit_notify _txe_thread_entry_exit_notify #define tx_thread_identify _tx_thread_identify @@ -1243,7 +1354,7 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #define tx_time_set _tx_time_set #define tx_timer_activate _txe_timer_activate #define tx_timer_change _txe_timer_change -#define tx_timer_create(t,n,e,i,c,r,a) _txe_timer_create(t,n,e,i,c,r,a,sizeof(TX_TIMER)) +#define tx_timer_create(t,n,e,i,c,r,a) _txe_timer_create((t),(n),(e),(i),(c),(r),(a),(sizeof(TX_TIMER))) #define tx_timer_deactivate _txe_timer_deactivate #define tx_timer_delete _txe_timer_delete #define tx_timer_info_get _txe_timer_info_get @@ -1262,248 +1373,617 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #endif #endif +#endif + /* Declare the tx_application_define function as having C linkage. */ -VOID tx_application_define(VOID *); - - -/* Define the ThreadX entry function that is typically called from the application's main() function. */ - -VOID tx_kernel_enter(VOID); +VOID tx_application_define(VOID *first_unused_memory); /* Define the function prototypes of the ThreadX API. */ -UINT tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option); -#ifdef TX_DISABLE_ERROR_CHECKING + +/* Define block memory pool management function prototypes. */ + +UINT _tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option); UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, VOID *pool_start, ULONG pool_size); -#else -#ifdef TX_ENABLE_MULTI_ERROR_CHECKING -UINT _txr_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, - VOID *pool_start, ULONG pool_size, UINT pool_control_block_size); -#else -UINT _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, - VOID *pool_start, ULONG pool_size, UINT pool_control_block_size); -#endif -#endif -UINT tx_block_pool_delete(TX_BLOCK_POOL *pool_ptr); -UINT tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks, +UINT _tx_block_pool_delete(TX_BLOCK_POOL *pool_ptr); +UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks, ULONG *total_blocks, TX_THREAD **first_suspended, ULONG *suspended_count, TX_BLOCK_POOL **next_pool); -UINT tx_block_pool_performance_info_get(TX_BLOCK_POOL *pool_ptr, ULONG *allocates, ULONG *releases, +UINT _tx_block_pool_performance_info_get(TX_BLOCK_POOL *pool_ptr, ULONG *allocates, ULONG *releases, ULONG *suspensions, ULONG *timeouts); -UINT tx_block_pool_performance_system_info_get(ULONG *allocates, ULONG *releases, +UINT _tx_block_pool_performance_system_info_get(ULONG *allocates, ULONG *releases, ULONG *suspensions, ULONG *timeouts); -UINT tx_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr); -UINT tx_block_release(VOID *block_ptr); +UINT _tx_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr); +UINT _tx_block_release(VOID *block_ptr); -UINT tx_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option); +UINT _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, + VOID *pool_start, ULONG pool_size, UINT pool_control_block_size); +UINT _txe_block_pool_delete(TX_BLOCK_POOL *pool_ptr); +UINT _txe_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks, + ULONG *total_blocks, TX_THREAD **first_suspended, + ULONG *suspended_count, TX_BLOCK_POOL **next_pool); +UINT _txe_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr); +UINT _txe_block_release(VOID *block_ptr); +#ifdef TX_ENABLE_MULTI_ERROR_CHECKING +UINT _txr_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option); +UINT _txr_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, + VOID *pool_start, ULONG pool_size, UINT pool_control_block_size); +UINT _txr_block_pool_delete(TX_BLOCK_POOL *pool_ptr); +UINT _txr_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks, + ULONG *total_blocks, TX_THREAD **first_suspended, + ULONG *suspended_count, TX_BLOCK_POOL **next_pool); +UINT _txr_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr); +UINT _txr_block_release(VOID *block_ptr); +#endif + + +/* Define byte memory pool management function prototypes. */ + +UINT _tx_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, ULONG wait_option); -#ifdef TX_DISABLE_ERROR_CHECKING UINT _tx_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, ULONG pool_size); -#else -#ifdef TX_ENABLE_MULTI_ERROR_CHECKING -UINT _txr_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, - ULONG pool_size, UINT pool_control_block_size); -#else -UINT _txe_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, - ULONG pool_size, UINT pool_control_block_size); -#endif -#endif -UINT tx_byte_pool_delete(TX_BYTE_POOL *pool_ptr); -UINT tx_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes, +UINT _tx_byte_pool_delete(TX_BYTE_POOL *pool_ptr); +UINT _tx_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes, ULONG *fragments, TX_THREAD **first_suspended, ULONG *suspended_count, TX_BYTE_POOL **next_pool); -UINT tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases, +UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases, ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts); -UINT tx_byte_pool_performance_system_info_get(ULONG *allocates, ULONG *releases, +UINT _tx_byte_pool_performance_system_info_get(ULONG *allocates, ULONG *releases, ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts); -UINT tx_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr); -UINT tx_byte_release(VOID *memory_ptr); +UINT _tx_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr); +UINT _tx_byte_release(VOID *memory_ptr); -#ifdef TX_DISABLE_ERROR_CHECKING -UINT _tx_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr); -#else + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, + ULONG wait_option); +UINT _txe_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, + ULONG pool_size, UINT pool_control_block_size); +UINT _txe_byte_pool_delete(TX_BYTE_POOL *pool_ptr); +UINT _txe_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes, + ULONG *fragments, TX_THREAD **first_suspended, + ULONG *suspended_count, TX_BYTE_POOL **next_pool); +UINT _txe_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr); +UINT _txe_byte_release(VOID *memory_ptr); #ifdef TX_ENABLE_MULTI_ERROR_CHECKING -UINT _txr_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size); -#else -UINT _txe_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size); +UINT _txr_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, + ULONG wait_option); +UINT _txr_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, + ULONG pool_size, UINT pool_control_block_size); +UINT _txr_byte_pool_delete(TX_BYTE_POOL *pool_ptr); +UINT _txr_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes, + ULONG *fragments, TX_THREAD **first_suspended, + ULONG *suspended_count, TX_BYTE_POOL **next_pool); +UINT _txr_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr); +UINT _txr_byte_release(VOID *memory_ptr); #endif -#endif -UINT tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr); -UINT tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags, + + +/* Define event flags management function prototypes. */ + +UINT _tx_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr); +UINT _tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr); +UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags, UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option); -UINT tx_event_flags_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR **name, ULONG *current_flags, +UINT _tx_event_flags_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR **name, ULONG *current_flags, TX_THREAD **first_suspended, ULONG *suspended_count, TX_EVENT_FLAGS_GROUP **next_group); -UINT tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets, +UINT _tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets, ULONG *suspensions, ULONG *timeouts); -UINT tx_event_flags_performance_system_info_get(ULONG *sets, ULONG *gets, +UINT _tx_event_flags_performance_system_info_get(ULONG *sets, ULONG *gets, ULONG *suspensions, ULONG *timeouts); -UINT tx_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, +UINT _tx_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, UINT set_option); -UINT tx_event_flags_set_notify(TX_EVENT_FLAGS_GROUP *group_ptr, VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *)); +UINT _tx_event_flags_set_notify(TX_EVENT_FLAGS_GROUP *group_ptr, VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); -UINT tx_interrupt_control(UINT new_posture); -#ifdef TX_DISABLE_ERROR_CHECKING -UINT _tx_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit); -#else +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size); +UINT _txe_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr); +UINT _txe_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags, + UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option); +UINT _txe_event_flags_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR **name, ULONG *current_flags, + TX_THREAD **first_suspended, ULONG *suspended_count, + TX_EVENT_FLAGS_GROUP **next_group); +UINT _txe_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, + UINT set_option); +UINT _txe_event_flags_set_notify(TX_EVENT_FLAGS_GROUP *group_ptr, VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); #ifdef TX_ENABLE_MULTI_ERROR_CHECKING -UINT _txr_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size); -#else -UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size); +UINT _txr_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size); +UINT _txr_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr); +UINT _txr_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags, + UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option); +UINT _txr_event_flags_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR **name, ULONG *current_flags, + TX_THREAD **first_suspended, ULONG *suspended_count, + TX_EVENT_FLAGS_GROUP **next_group); +UINT _txr_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, + UINT set_option); +UINT _txr_event_flags_set_notify(TX_EVENT_FLAGS_GROUP *group_ptr, VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); #endif -#endif -UINT tx_mutex_delete(TX_MUTEX *mutex_ptr); -UINT tx_mutex_get(TX_MUTEX *mutex_ptr, ULONG wait_option); -UINT tx_mutex_info_get(TX_MUTEX *mutex_ptr, CHAR **name, ULONG *count, TX_THREAD **owner, + + +/* Define initialization function prototypes. */ + +VOID _tx_initialize_kernel_enter(VOID); + + +/* Define mutex management function prototypes. */ + +UINT _tx_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit); +UINT _tx_mutex_delete(TX_MUTEX *mutex_ptr); +UINT _tx_mutex_get(TX_MUTEX *mutex_ptr, ULONG wait_option); +UINT _tx_mutex_info_get(TX_MUTEX *mutex_ptr, CHAR **name, ULONG *count, TX_THREAD **owner, TX_THREAD **first_suspended, ULONG *suspended_count, TX_MUTEX **next_mutex); -UINT tx_mutex_performance_info_get(TX_MUTEX *mutex_ptr, ULONG *puts, ULONG *gets, +UINT _tx_mutex_performance_info_get(TX_MUTEX *mutex_ptr, ULONG *puts, ULONG *gets, ULONG *suspensions, ULONG *timeouts, ULONG *inversions, ULONG *inheritances); -UINT tx_mutex_performance_system_info_get(ULONG *puts, ULONG *gets, ULONG *suspensions, ULONG *timeouts, +UINT _tx_mutex_performance_system_info_get(ULONG *puts, ULONG *gets, ULONG *suspensions, ULONG *timeouts, ULONG *inversions, ULONG *inheritances); -UINT tx_mutex_prioritize(TX_MUTEX *mutex_ptr); -UINT tx_mutex_put(TX_MUTEX *mutex_ptr); +UINT _tx_mutex_prioritize(TX_MUTEX *mutex_ptr); +UINT _tx_mutex_put(TX_MUTEX *mutex_ptr); + + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size); +UINT _txe_mutex_delete(TX_MUTEX *mutex_ptr); +UINT _txe_mutex_get(TX_MUTEX *mutex_ptr, ULONG wait_option); +UINT _txe_mutex_info_get(TX_MUTEX *mutex_ptr, CHAR **name, ULONG *count, TX_THREAD **owner, + TX_THREAD **first_suspended, ULONG *suspended_count, + TX_MUTEX **next_mutex); +UINT _txe_mutex_prioritize(TX_MUTEX *mutex_ptr); +UINT _txe_mutex_put(TX_MUTEX *mutex_ptr); +#ifdef TX_ENABLE_MULTI_ERROR_CHECKING +UINT _txr_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size); +UINT _txr_mutex_delete(TX_MUTEX *mutex_ptr); +UINT _txr_mutex_get(TX_MUTEX *mutex_ptr, ULONG wait_option); +UINT _txr_mutex_info_get(TX_MUTEX *mutex_ptr, CHAR **name, ULONG *count, TX_THREAD **owner, + TX_THREAD **first_suspended, ULONG *suspended_count, + TX_MUTEX **next_mutex); +UINT _txr_mutex_prioritize(TX_MUTEX *mutex_ptr); +UINT _txr_mutex_put(TX_MUTEX *mutex_ptr); +#endif + + +/* Define queue management function prototypes. */ -#ifdef TX_DISABLE_ERROR_CHECKING UINT _tx_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, VOID *queue_start, ULONG queue_size); -#else +UINT _tx_queue_delete(TX_QUEUE *queue_ptr); +UINT _tx_queue_flush(TX_QUEUE *queue_ptr); +UINT _tx_queue_info_get(TX_QUEUE *queue_ptr, CHAR **name, ULONG *enqueued, ULONG *available_storage, + TX_THREAD **first_suspended, ULONG *suspended_count, TX_QUEUE **next_queue); +UINT _tx_queue_performance_info_get(TX_QUEUE *queue_ptr, ULONG *messages_sent, ULONG *messages_received, + ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts); +UINT _tx_queue_performance_system_info_get(ULONG *messages_sent, ULONG *messages_received, + ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts); +UINT _tx_queue_prioritize(TX_QUEUE *queue_ptr); +UINT _tx_queue_receive(TX_QUEUE *queue_ptr, VOID *destination_ptr, ULONG wait_option); +UINT _tx_queue_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); +UINT _tx_queue_send_notify(TX_QUEUE *queue_ptr, VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); +UINT _tx_queue_front_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); + + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, + VOID *queue_start, ULONG queue_size, UINT queue_control_block_size); +UINT _txe_queue_delete(TX_QUEUE *queue_ptr); +UINT _txe_queue_flush(TX_QUEUE *queue_ptr); +UINT _txe_queue_info_get(TX_QUEUE *queue_ptr, CHAR **name, ULONG *enqueued, ULONG *available_storage, + TX_THREAD **first_suspended, ULONG *suspended_count, TX_QUEUE **next_queue); +UINT _txe_queue_prioritize(TX_QUEUE *queue_ptr); +UINT _txe_queue_receive(TX_QUEUE *queue_ptr, VOID *destination_ptr, ULONG wait_option); +UINT _txe_queue_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); +UINT _txe_queue_send_notify(TX_QUEUE *queue_ptr, VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); +UINT _txe_queue_front_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); #ifdef TX_ENABLE_MULTI_ERROR_CHECKING UINT _txr_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, VOID *queue_start, ULONG queue_size, UINT queue_control_block_size); -#else -UINT _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, - VOID *queue_start, ULONG queue_size, UINT queue_control_block_size); -#endif -#endif -UINT tx_queue_delete(TX_QUEUE *queue_ptr); -UINT tx_queue_flush(TX_QUEUE *queue_ptr); -UINT tx_queue_info_get(TX_QUEUE *queue_ptr, CHAR **name, ULONG *enqueued, ULONG *available_storage, +UINT _txr_queue_delete(TX_QUEUE *queue_ptr); +UINT _txr_queue_flush(TX_QUEUE *queue_ptr); +UINT _txr_queue_info_get(TX_QUEUE *queue_ptr, CHAR **name, ULONG *enqueued, ULONG *available_storage, TX_THREAD **first_suspended, ULONG *suspended_count, TX_QUEUE **next_queue); -UINT tx_queue_performance_info_get(TX_QUEUE *queue_ptr, ULONG *messages_sent, ULONG *messages_received, - ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts); -UINT tx_queue_performance_system_info_get(ULONG *messages_sent, ULONG *messages_received, - ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts); -UINT tx_queue_receive(TX_QUEUE *queue_ptr, VOID *destination_ptr, ULONG wait_option); -UINT tx_queue_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); -UINT tx_queue_send_notify(TX_QUEUE *queue_ptr, VOID (*queue_send_notify)(TX_QUEUE *)); -UINT tx_queue_front_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); -UINT tx_queue_prioritize(TX_QUEUE *queue_ptr); +UINT _txr_queue_prioritize(TX_QUEUE *queue_ptr); +UINT _txr_queue_receive(TX_QUEUE *queue_ptr, VOID *destination_ptr, ULONG wait_option); +UINT _txr_queue_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); +UINT _txr_queue_send_notify(TX_QUEUE *queue_ptr, VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); +UINT _txr_queue_front_send(TX_QUEUE *queue_ptr, VOID *source_ptr, ULONG wait_option); +#endif -UINT tx_semaphore_ceiling_put(TX_SEMAPHORE *semaphore_ptr, ULONG ceiling); -#ifdef TX_DISABLE_ERROR_CHECKING + +/* Define semaphore management function prototypes. */ + +UINT _tx_semaphore_ceiling_put(TX_SEMAPHORE *semaphore_ptr, ULONG ceiling); UINT _tx_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count); -#else -#ifdef TX_ENABLE_MULTI_ERROR_CHECKING -UINT _txr_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size); -#else -UINT _txe_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size); -#endif -#endif -UINT tx_semaphore_delete(TX_SEMAPHORE *semaphore_ptr); -UINT tx_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option); -UINT tx_semaphore_info_get(TX_SEMAPHORE *semaphore_ptr, CHAR **name, ULONG *current_value, +UINT _tx_semaphore_delete(TX_SEMAPHORE *semaphore_ptr); +UINT _tx_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option); +UINT _tx_semaphore_info_get(TX_SEMAPHORE *semaphore_ptr, CHAR **name, ULONG *current_value, TX_THREAD **first_suspended, ULONG *suspended_count, TX_SEMAPHORE **next_semaphore); -UINT tx_semaphore_performance_info_get(TX_SEMAPHORE *semaphore_ptr, ULONG *puts, ULONG *gets, +UINT _tx_semaphore_performance_info_get(TX_SEMAPHORE *semaphore_ptr, ULONG *puts, ULONG *gets, ULONG *suspensions, ULONG *timeouts); -UINT tx_semaphore_performance_system_info_get(ULONG *puts, ULONG *gets, - ULONG *suspensions, ULONG *timeouts); -UINT tx_semaphore_prioritize(TX_SEMAPHORE *semaphore_ptr); -UINT tx_semaphore_put(TX_SEMAPHORE *semaphore_ptr); -UINT tx_semaphore_put_notify(TX_SEMAPHORE *semaphore_ptr, VOID (*semaphore_put_notify)(TX_SEMAPHORE *)); +UINT _tx_semaphore_performance_system_info_get(ULONG *puts, ULONG *gets, ULONG *suspensions, ULONG *timeouts); +UINT _tx_semaphore_prioritize(TX_SEMAPHORE *semaphore_ptr); +UINT _tx_semaphore_put(TX_SEMAPHORE *semaphore_ptr); +UINT _tx_semaphore_put_notify(TX_SEMAPHORE *semaphore_ptr, VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); -#ifdef TX_DISABLE_ERROR_CHECKING + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_semaphore_ceiling_put(TX_SEMAPHORE *semaphore_ptr, ULONG ceiling); +UINT _txe_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size); +UINT _txe_semaphore_delete(TX_SEMAPHORE *semaphore_ptr); +UINT _txe_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option); +UINT _txe_semaphore_info_get(TX_SEMAPHORE *semaphore_ptr, CHAR **name, ULONG *current_value, + TX_THREAD **first_suspended, ULONG *suspended_count, + TX_SEMAPHORE **next_semaphore); +UINT _txe_semaphore_prioritize(TX_SEMAPHORE *semaphore_ptr); +UINT _txe_semaphore_put(TX_SEMAPHORE *semaphore_ptr); +UINT _txe_semaphore_put_notify(TX_SEMAPHORE *semaphore_ptr, VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); +#ifdef TX_ENABLE_MULTI_ERROR_CHECKING +UINT _txr_semaphore_ceiling_put(TX_SEMAPHORE *semaphore_ptr, ULONG ceiling); +UINT _txr_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size); +UINT _txr_semaphore_delete(TX_SEMAPHORE *semaphore_ptr); +UINT _txr_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option); +UINT _txr_semaphore_info_get(TX_SEMAPHORE *semaphore_ptr, CHAR **name, ULONG *current_value, + TX_THREAD **first_suspended, ULONG *suspended_count, + TX_SEMAPHORE **next_semaphore); +UINT _txr_semaphore_prioritize(TX_SEMAPHORE *semaphore_ptr); +UINT _txr_semaphore_put(TX_SEMAPHORE *semaphore_ptr); +UINT _txr_semaphore_put_notify(TX_SEMAPHORE *semaphore_ptr, VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); +#endif + + +/* Define thread control function prototypes. */ + +VOID _tx_thread_context_save(VOID); +VOID _tx_thread_context_restore(VOID); UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, - VOID (*entry_function)(ULONG), ULONG entry_input, - VOID *stack_start, ULONG stack_size, - UINT priority, UINT preempt_threshold, - ULONG time_slice, UINT auto_start); -#else + VOID (*entry_function)(ULONG entry_input), ULONG entry_input, + VOID *stack_start, ULONG stack_size, + UINT priority, UINT preempt_threshold, + ULONG time_slice, UINT auto_start); +UINT _tx_thread_delete(TX_THREAD *thread_ptr); +UINT _tx_thread_entry_exit_notify(TX_THREAD *thread_ptr, VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT type)); +TX_THREAD *_tx_thread_identify(VOID); +UINT _tx_thread_info_get(TX_THREAD *thread_ptr, CHAR **name, UINT *state, ULONG *run_count, + UINT *priority, UINT *preemption_threshold, ULONG *time_slice, + TX_THREAD **next_thread, TX_THREAD **next_suspended_thread); +UINT _tx_thread_interrupt_control(UINT new_posture); +UINT _tx_thread_performance_info_get(TX_THREAD *thread_ptr, ULONG *resumptions, ULONG *suspensions, + ULONG *solicited_preemptions, ULONG *interrupt_preemptions, ULONG *priority_inversions, + ULONG *time_slices, ULONG *relinquishes, ULONG *timeouts, ULONG *wait_aborts, TX_THREAD **last_preempted_by); +UINT _tx_thread_performance_system_info_get(ULONG *resumptions, ULONG *suspensions, + ULONG *solicited_preemptions, ULONG *interrupt_preemptions, ULONG *priority_inversions, + ULONG *time_slices, ULONG *relinquishes, ULONG *timeouts, ULONG *wait_aborts, + ULONG *non_idle_returns, ULONG *idle_returns); +UINT _tx_thread_preemption_change(TX_THREAD *thread_ptr, UINT new_threshold, + UINT *old_threshold); +UINT _tx_thread_priority_change(TX_THREAD *thread_ptr, UINT new_priority, + UINT *old_priority); +VOID _tx_thread_relinquish(VOID); +UINT _tx_thread_reset(TX_THREAD *thread_ptr); +UINT _tx_thread_resume(TX_THREAD *thread_ptr); +UINT _tx_thread_sleep(ULONG timer_ticks); +UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr)); +UINT _tx_thread_suspend(TX_THREAD *thread_ptr); +UINT _tx_thread_terminate(TX_THREAD *thread_ptr); +UINT _tx_thread_time_slice_change(TX_THREAD *thread_ptr, ULONG new_time_slice, ULONG *old_time_slice); +UINT _tx_thread_wait_abort(TX_THREAD *thread_ptr); + + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, + VOID (*entry_function)(ULONG entry_input), ULONG entry_input, + VOID *stack_start, ULONG stack_size, + UINT priority, UINT preempt_threshold, + ULONG time_slice, UINT auto_start, UINT thread_control_block_size); +UINT _txe_thread_delete(TX_THREAD *thread_ptr); +UINT _txe_thread_entry_exit_notify(TX_THREAD *thread_ptr, VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT type)); +UINT _txe_thread_info_get(TX_THREAD *thread_ptr, CHAR **name, UINT *state, ULONG *run_count, + UINT *priority, UINT *preemption_threshold, ULONG *time_slice, + TX_THREAD **next_thread, TX_THREAD **next_suspended_thread); +UINT _txe_thread_preemption_change(TX_THREAD *thread_ptr, UINT new_threshold, + UINT *old_threshold); +UINT _txe_thread_priority_change(TX_THREAD *thread_ptr, UINT new_priority, + UINT *old_priority); +VOID _txe_thread_relinquish(VOID); +UINT _txe_thread_reset(TX_THREAD *thread_ptr); +UINT _txe_thread_resume(TX_THREAD *thread_ptr); +UINT _txe_thread_suspend(TX_THREAD *thread_ptr); +UINT _txe_thread_terminate(TX_THREAD *thread_ptr); +UINT _txe_thread_time_slice_change(TX_THREAD *thread_ptr, ULONG new_time_slice, ULONG *old_time_slice); +UINT _txe_thread_wait_abort(TX_THREAD *thread_ptr); #ifdef TX_ENABLE_MULTI_ERROR_CHECKING UINT _txr_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, - VOID (*entry_function)(ULONG), ULONG entry_input, - VOID *stack_start, ULONG stack_size, - UINT priority, UINT preempt_threshold, - ULONG time_slice, UINT auto_start, UINT thread_control_block_size); -#else -UINT _txe_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, - VOID (*entry_function)(ULONG), ULONG entry_input, - VOID *stack_start, ULONG stack_size, - UINT priority, UINT preempt_threshold, - ULONG time_slice, UINT auto_start, UINT thread_control_block_size); + VOID (*entry_function)(ULONG entry_input), ULONG entry_input, + VOID *stack_start, ULONG stack_size, + UINT priority, UINT preempt_threshold, + ULONG time_slice, UINT auto_start, UINT thread_control_block_size); +UINT _txr_thread_delete(TX_THREAD *thread_ptr); +UINT _txr_thread_entry_exit_notify(TX_THREAD *thread_ptr, VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT type)); +UINT _txr_thread_info_get(TX_THREAD *thread_ptr, CHAR **name, UINT *state, ULONG *run_count, + UINT *priority, UINT *preemption_threshold, ULONG *time_slice, + TX_THREAD **next_thread, TX_THREAD **next_suspended_thread); +UINT _txr_thread_preemption_change(TX_THREAD *thread_ptr, UINT new_threshold, + UINT *old_threshold); +UINT _txr_thread_priority_change(TX_THREAD *thread_ptr, UINT new_priority, + UINT *old_priority); +UINT _txr_thread_reset(TX_THREAD *thread_ptr); +UINT _txr_thread_resume(TX_THREAD *thread_ptr); +UINT _txr_thread_suspend(TX_THREAD *thread_ptr); +UINT _txr_thread_terminate(TX_THREAD *thread_ptr); +UINT _txr_thread_time_slice_change(TX_THREAD *thread_ptr, ULONG new_time_slice, ULONG *old_time_slice); +UINT _txr_thread_wait_abort(TX_THREAD *thread_ptr); #endif -#endif -UINT tx_thread_delete(TX_THREAD *thread_ptr); -UINT tx_thread_entry_exit_notify(TX_THREAD *thread_ptr, VOID (*thread_entry_exit_notify)(TX_THREAD *, UINT)); -TX_THREAD *tx_thread_identify(VOID); -UINT tx_thread_info_get(TX_THREAD *thread_ptr, CHAR **name, UINT *state, ULONG *run_count, - UINT *priority, UINT *preemption_threshold, ULONG *time_slice, - TX_THREAD **next_thread, TX_THREAD **next_suspended_thread); -UINT tx_thread_performance_info_get(TX_THREAD *thread_ptr, ULONG *resumptions, ULONG *suspensions, - ULONG *solicited_preemptions, ULONG *interrupt_preemptions, ULONG *priority_inversions, - ULONG *time_slices, ULONG *relinquishes, ULONG *timeouts, ULONG *wait_aborts, TX_THREAD **last_preempted_by); -UINT tx_thread_performance_system_info_get(ULONG *resumptions, ULONG *suspensions, - ULONG *solicited_preemptions, ULONG *interrupt_preemptions, ULONG *priority_inversions, - ULONG *time_slices, ULONG *relinquishes, ULONG *timeouts, ULONG *wait_aborts, - ULONG *non_idle_returns, ULONG *idle_returns); -UINT tx_thread_preemption_change(TX_THREAD *thread_ptr, UINT new_threshold, - UINT *old_threshold); -UINT tx_thread_priority_change(TX_THREAD *thread_ptr, UINT new_priority, - UINT *old_priority); -VOID tx_thread_relinquish(VOID); -UINT tx_thread_reset(TX_THREAD *thread_ptr); -UINT tx_thread_resume(TX_THREAD *thread_ptr); -UINT tx_thread_sleep(ULONG timer_ticks); -UINT tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *)); -UINT tx_thread_suspend(TX_THREAD *thread_ptr); -UINT tx_thread_terminate(TX_THREAD *thread_ptr); -UINT tx_thread_time_slice_change(TX_THREAD *thread_ptr, ULONG new_time_slice, ULONG *old_time_slice); -UINT tx_thread_wait_abort(TX_THREAD *thread_ptr); -ULONG tx_time_get(VOID); -VOID tx_time_set(ULONG new_time); -UINT tx_timer_activate(TX_TIMER *timer_ptr); -UINT tx_timer_change(TX_TIMER *timer_ptr, ULONG initial_ticks, ULONG reschedule_ticks); -#ifdef TX_DISABLE_ERROR_CHECKING +/* Define timer management function prototypes. */ + +UINT _tx_timer_activate(TX_TIMER *timer_ptr); +UINT _tx_timer_change(TX_TIMER *timer_ptr, ULONG initial_ticks, ULONG reschedule_ticks); UINT _tx_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr, - VOID (*expiration_function)(ULONG), ULONG expiration_input, ULONG initial_ticks, - ULONG reschedule_ticks, UINT auto_activate); -#else -#ifdef TX_ENABLE_MULTI_ERROR_CHECKING -UINT _txr_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr, - VOID (*expiration_function)(ULONG), ULONG expiration_input, ULONG initial_ticks, - ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size); -#else -UINT _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr, - VOID (*expiration_function)(ULONG), ULONG expiration_input, ULONG initial_ticks, - ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size); -#endif -#endif -UINT tx_timer_deactivate(TX_TIMER *timer_ptr); -UINT tx_timer_delete(TX_TIMER *timer_ptr); -UINT tx_timer_info_get(TX_TIMER *timer_ptr, CHAR **name, UINT *active, ULONG *remaining_ticks, - ULONG *reschedule_ticks, TX_TIMER **next_timer); -UINT tx_timer_performance_info_get(TX_TIMER *timer_ptr, ULONG *activates, ULONG *reactivates, - ULONG *deactivates, ULONG *expirations, ULONG *expiration_adjusts); -UINT tx_timer_performance_system_info_get(ULONG *activates, ULONG *reactivates, - ULONG *deactivates, ULONG *expirations, ULONG *expiration_adjusts); + VOID (*expiration_function)(ULONG input), ULONG expiration_input, + ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate); +UINT _tx_timer_deactivate(TX_TIMER *timer_ptr); +UINT _tx_timer_delete(TX_TIMER *timer_ptr); +UINT _tx_timer_info_get(TX_TIMER *timer_ptr, CHAR **name, UINT *active, ULONG *remaining_ticks, + ULONG *reschedule_ticks, TX_TIMER **next_timer); +UINT _tx_timer_performance_info_get(TX_TIMER *timer_ptr, ULONG *activates, ULONG *reactivates, + ULONG *deactivates, ULONG *expirations, ULONG *expiration_adjusts); +UINT _tx_timer_performance_system_info_get(ULONG *activates, ULONG *reactivates, + ULONG *deactivates, ULONG *expirations, ULONG *expiration_adjusts); -UINT tx_trace_enable(VOID *trace_buffer_start, ULONG trace_buffer_size, ULONG registry_entries); -UINT tx_trace_event_filter(ULONG event_filter_bits); -UINT tx_trace_event_unfilter(ULONG event_unfilter_bits); -UINT tx_trace_disable(VOID); -VOID tx_trace_isr_enter_insert(ULONG isr_id); -VOID tx_trace_isr_exit_insert(ULONG isr_id); -UINT tx_trace_buffer_full_notify(VOID (*full_buffer_callback)(VOID *)); -UINT tx_trace_user_event_insert(ULONG event_id, ULONG info_field_1, ULONG info_field_2, ULONG info_field_3, ULONG info_field_4); +ULONG _tx_time_get(VOID); +VOID _tx_time_set(ULONG new_time); + + +/* Define error checking shells for API services. These are only referenced by the + application. */ + +UINT _txe_timer_activate(TX_TIMER *timer_ptr); +UINT _txe_timer_change(TX_TIMER *timer_ptr, ULONG initial_ticks, ULONG reschedule_ticks); +UINT _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr, + VOID (*expiration_function)(ULONG input), ULONG expiration_input, + ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size); +UINT _txe_timer_deactivate(TX_TIMER *timer_ptr); +UINT _txe_timer_delete(TX_TIMER *timer_ptr); +UINT _txe_timer_info_get(TX_TIMER *timer_ptr, CHAR **name, UINT *active, ULONG *remaining_ticks, + ULONG *reschedule_ticks, TX_TIMER **next_timer); +#ifdef TX_ENABLE_MULTI_ERROR_CHECKING +UINT _txr_timer_activate(TX_TIMER *timer_ptr); +UINT _txr_timer_change(TX_TIMER *timer_ptr, ULONG initial_ticks, ULONG reschedule_ticks); +UINT _txr_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr, + VOID (*expiration_function)(ULONG input), ULONG expiration_input, + ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size); +UINT _txr_timer_deactivate(TX_TIMER *timer_ptr); +UINT _txr_timer_delete(TX_TIMER *timer_ptr); +UINT _txr_timer_info_get(TX_TIMER *timer_ptr, CHAR **name, UINT *active, ULONG *remaining_ticks, + ULONG *reschedule_ticks, TX_TIMER **next_timer); +#endif + + +/* Define trace API function prototypes. */ + +UINT _tx_trace_enable(VOID *trace_buffer_start, ULONG trace_buffer_size, ULONG registry_entries); +UINT _tx_trace_event_filter(ULONG event_filter_bits); +UINT _tx_trace_event_unfilter(ULONG event_unfilter_bits); +UINT _tx_trace_disable(VOID); +VOID _tx_trace_isr_enter_insert(ULONG isr_id); +VOID _tx_trace_isr_exit_insert(ULONG isr_id); +UINT _tx_trace_buffer_full_notify(VOID (*full_buffer_callback)(VOID *buffer)); +UINT _tx_trace_user_event_insert(ULONG event_id, ULONG info_field_1, ULONG info_field_2, ULONG info_field_3, ULONG info_field_4); +UINT _tx_trace_interrupt_control(UINT new_posture); + + +/* Add a default macro that can be re-defined in tx_port.h to add default processing when a thread starts. Common usage + would be for enabling floating point for a thread by default, however, the additional processing could be anything + defined in tx_port.h. */ + +#ifndef TX_THREAD_STARTED_EXTENSION +#define TX_THREAD_STARTED_EXTENSION(thread_ptr) +#endif + + +/* Add a default macro that can be re-defined in tx_port.h to add processing to the thread stack analyze function. + By default, this is simply defined as whitespace. */ + +#ifndef TX_THREAD_STACK_ANALYZE_EXTENSION +#define TX_THREAD_STACK_ANALYZE_EXTENSION +#endif + + +/* Add a default macro that can be re-defined in tx_port.h to add processing to the initialize kernel enter function. + By default, this is simply defined as whitespace. */ + +#ifndef TX_INITIALIZE_KERNEL_ENTER_EXTENSION +#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION +#endif + + +/* Check for MISRA compliance requirements. */ + +#ifdef TX_MISRA_ENABLE + + +/* Define MISRA-specific routines. */ + +VOID _tx_misra_memset(VOID *ptr, UINT value, UINT size); +UCHAR *_tx_misra_uchar_pointer_add(UCHAR *ptr, ULONG amount); +UCHAR *_tx_misra_uchar_pointer_sub(UCHAR *ptr, ULONG amount); +ULONG _tx_misra_uchar_pointer_dif(UCHAR *ptr1, UCHAR *ptr2); +ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); +ULONG *_tx_misra_ulong_pointer_add(ULONG *ptr, ULONG amount); +ULONG *_tx_misra_ulong_pointer_sub(ULONG *ptr, ULONG amount); +ULONG _tx_misra_ulong_pointer_dif(ULONG *ptr1, ULONG *ptr2); +VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); +VOID _tx_misra_message_copy(ULONG **source, ULONG **destination, UINT size); +ULONG _tx_misra_timer_pointer_dif(TX_TIMER_INTERNAL **ptr1, TX_TIMER_INTERNAL **ptr2); +TX_TIMER_INTERNAL **_tx_misra_timer_pointer_add(TX_TIMER_INTERNAL **ptr1, ULONG size); +VOID _tx_misra_user_timer_pointer_get(TX_TIMER_INTERNAL *internal_timer, TX_TIMER **user_timer); +VOID _tx_misra_thread_stack_check(TX_THREAD *thread_ptr, VOID **highest_stack); +VOID _tx_misra_trace_event_insert(ULONG event_id, VOID *info_field_1, ULONG info_field_2, ULONG info_field_3, ULONG info_field_4, ULONG filter, ULONG time_stamp); +UINT _tx_misra_always_true(void); + +UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **pointer); +UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); +UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); +TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); +UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); +TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); +UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); +TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); +UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); +ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); +TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); +TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); +ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); +TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); +UINT _tx_misra_status_get(UINT status); +TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); +TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); +VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); +TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); +VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); +CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); +TX_THREAD *_tx_misra_void_to_thread_pointer_convert(VOID *pointer); +UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); + + +#define TX_MEMSET(a,b,c) _tx_misra_memset((a), (UINT) (b), (UINT) (c)) +#define TX_UCHAR_POINTER_ADD(a,b) _tx_misra_uchar_pointer_add((UCHAR *) (a), (ULONG) (b)) +#define TX_UCHAR_POINTER_SUB(a,b) _tx_misra_uchar_pointer_sub((UCHAR *) (a), (ULONG) (b)) +#define TX_UCHAR_POINTER_DIF(a,b) _tx_misra_uchar_pointer_dif((UCHAR *) (a), (UCHAR *) (b)) +#define TX_ULONG_POINTER_ADD(a,b) _tx_misra_ulong_pointer_add((ULONG *) (a), (ULONG) (b)) +#define TX_ULONG_POINTER_SUB(a,b) _tx_misra_ulong_pointer_sub((ULONG *) (a), (ULONG) (b)) +#define TX_ULONG_POINTER_DIF(a,b) _tx_misra_ulong_pointer_dif((ULONG *) (a), (ULONG *) (b)) +#define TX_POINTER_TO_ULONG_CONVERT(a) _tx_misra_pointer_to_ulong_convert((VOID *) (a)) +#define TX_ULONG_TO_POINTER_CONVERT(a) _tx_misra_ulong_to_pointer_convert((ULONG) (a)) +#define TX_QUEUE_MESSAGE_COPY(s,d,z) _tx_misra_message_copy(&(s), &(d), (z)); +#define TX_TIMER_POINTER_DIF(a,b) _tx_misra_timer_pointer_dif((TX_TIMER_INTERNAL **) (a), (TX_TIMER_INTERNAL **) (b)) +#define TX_TIMER_POINTER_ADD(a,b) _tx_misra_timer_pointer_add((TX_TIMER_INTERNAL **) (a), (ULONG) (b)) +#define TX_USER_TIMER_POINTER_GET(a,b) _tx_misra_user_timer_pointer_get((TX_TIMER_INTERNAL *) (a), (TX_TIMER **) &(b)); +#define TX_THREAD_STACK_CHECK(a) _tx_misra_thread_stack_check((a), &((a)->tx_thread_stack_highest_ptr)); +#ifdef TX_ENABLE_EVENT_TRACE +#define TX_TRACE_IN_LINE_INSERT(i,a,b,c,d,e) _tx_misra_trace_event_insert((ULONG) (i), (VOID *) (a), (ULONG) (b), (ULONG) (c), (ULONG) (d), (ULONG) (e), ((ULONG) TX_TRACE_TIME_SOURCE)); +#endif +#define TX_LOOP_FOREVER (_tx_misra_always_true() == TX_TRUE) + + +#define TX_INDIRECT_VOID_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_indirect_void_to_uchar_pointer_convert((a)) +#define TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(a) _tx_misra_uchar_to_indirect_uchar_pointer_convert((a)) +#define TX_BLOCK_POOL_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_block_pool_to_uchar_pointer_convert((a)) +#define TX_VOID_TO_BLOCK_POOL_POINTER_CONVERT(a) _tx_misra_void_to_block_pool_pointer_convert((a)) +#define TX_VOID_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_void_to_uchar_pointer_convert((a)) +#define TX_UCHAR_TO_BLOCK_POOL_POINTER_CONVERT(a) _tx_misra_uchar_to_block_pool_pointer_convert((a)) +#define TX_VOID_TO_INDIRECT_UCHAR_POINTER_CONVERT(a) _tx_misra_void_to_indirect_uchar_pointer_convert((a)) +#define TX_VOID_TO_BYTE_POOL_POINTER_CONVERT(a) _tx_misra_void_to_byte_pool_pointer_convert((a)) +#define TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_byte_pool_to_uchar_pointer_convert((a)) +#define TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(a) _tx_misra_uchar_to_align_type_pointer_convert((a)) +#define TX_UCHAR_TO_INDIRECT_BYTE_POOL_POINTER(a) _tx_misra_uchar_to_indirect_byte_pool_pointer_convert((a)) +#define TX_VOID_TO_EVENT_FLAGS_POINTER_CONVERT(a) _tx_misra_void_to_event_flags_pointer_convert((a)) +#define TX_VOID_TO_ULONG_POINTER_CONVERT(a) _tx_misra_void_to_ulong_pointer_convert((a)) +#define TX_VOID_TO_MUTEX_POINTER_CONVERT(a) _tx_misra_void_to_mutex_pointer_convert((a)) +#define TX_MUTEX_PRIORITIZE_MISRA_EXTENSION(a) _tx_misra_status_get((a)) +#define TX_VOID_TO_QUEUE_POINTER_CONVERT(a) _tx_misra_void_to_queue_pointer_convert((a)) +#define TX_VOID_TO_SEMAPHORE_POINTER_CONVERT(a) _tx_misra_void_to_semaphore_pointer_convert((a)) +#define TX_UCHAR_TO_VOID_POINTER_CONVERT(a) _tx_misra_uchar_to_void_pointer_convert((a)) +#define TX_ULONG_TO_THREAD_POINTER_CONVERT(a) _tx_misra_ulong_to_thread_pointer_convert((a)) +#define TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(a) _tx_misra_timer_indirect_to_void_pointer_convert((a)) +#ifndef TX_TIMER_INITIALIZE_EXTENSION +#define TX_TIMER_INITIALIZE_EXTENSION(a) status = _tx_misra_status_get((a)); +#endif +#define TX_CONST_CHAR_TO_CHAR_POINTER_CONVERT(a) _tx_misra_const_char_to_char_pointer_convert((a)) +#define TX_VOID_TO_THREAD_POINTER_CONVERT(a) _tx_misra_void_to_thread_pointer_convert((a)) +#define TX_CHAR_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_char_to_uchar_pointer_convert((a)) + +#else + +/* Define the TX_MEMSET macro to the standard library function, if not already defined. */ + +#ifndef TX_MEMSET +#define TX_MEMSET(a,b,c) memset((a),(b),(c)) +#endif + +#define TX_UCHAR_POINTER_ADD(a,b) (((UCHAR *) (a)) + ((UINT) (b))) +#define TX_UCHAR_POINTER_SUB(a,b) (((UCHAR *) (a)) - ((UINT) (b))) +#define TX_UCHAR_POINTER_DIF(a,b) ((ULONG)(((UCHAR *) (a)) - ((UCHAR *) (b)))) +#define TX_ULONG_POINTER_ADD(a,b) (((ULONG *) (a)) + ((UINT) (b))) +#define TX_ULONG_POINTER_SUB(a,b) (((ULONG *) (a)) - ((UINT) (b))) +#define TX_ULONG_POINTER_DIF(a,b) ((ULONG)(((ULONG *) (a)) - ((ULONG *) (b)))) +#define TX_POINTER_TO_ULONG_CONVERT(a) ((ULONG) ((VOID *) (a))) +#define TX_ULONG_TO_POINTER_CONVERT(a) ((VOID *) ((ULONG) (a))) +#define TX_TIMER_POINTER_DIF(a,b) ((ULONG)(((TX_TIMER_INTERNAL **) (a)) - ((TX_TIMER_INTERNAL **) (b)))) +#define TX_TIMER_POINTER_ADD(a,b) (((TX_TIMER_INTERNAL **) (a)) + ((ULONG) (b))) +#define TX_USER_TIMER_POINTER_GET(a,b) { \ + UCHAR *working_ptr; \ + working_ptr = (UCHAR *) (a); \ + (b) = (TX_TIMER *) working_ptr; \ + working_ptr = working_ptr - (((UCHAR *) &(b) -> tx_timer_internal) - ((UCHAR *) &(b) -> tx_timer_id)); \ + (b) = (TX_TIMER *) working_ptr; \ + } +#define TX_LOOP_FOREVER ((UINT) 1) + + +#define TX_INDIRECT_VOID_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR **) ((VOID *) (a))) +#define TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(a) ((UCHAR **) ((VOID *) (a))) +#define TX_BLOCK_POOL_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR *) ((VOID *) (a))) +#define TX_VOID_TO_BLOCK_POOL_POINTER_CONVERT(a) ((TX_BLOCK_POOL *) ((VOID *) (a))) +#define TX_VOID_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR *) ((VOID *) (a))) +#define TX_UCHAR_TO_BLOCK_POOL_POINTER_CONVERT(a) ((TX_BLOCK_POOL *) ((VOID *) (a))) +#define TX_VOID_TO_INDIRECT_UCHAR_POINTER_CONVERT(a) ((UCHAR **) ((VOID *) (a))) +#define TX_VOID_TO_BYTE_POOL_POINTER_CONVERT(a) ((TX_BYTE_POOL *) ((VOID *) (a))) +#define TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR *) ((VOID *) (a))) +#ifndef TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT +#define TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(a) ((ALIGN_TYPE *) ((VOID *) (a))) +#endif +#define TX_UCHAR_TO_INDIRECT_BYTE_POOL_POINTER(a) ((TX_BYTE_POOL **) ((VOID *) (a))) +#define TX_VOID_TO_EVENT_FLAGS_POINTER_CONVERT(a) ((TX_EVENT_FLAGS_GROUP *) ((VOID *) (a))) +#define TX_VOID_TO_ULONG_POINTER_CONVERT(a) ((ULONG *) ((VOID *) (a))) +#define TX_VOID_TO_MUTEX_POINTER_CONVERT(a) ((TX_MUTEX *) ((VOID *) (a))) +#define TX_VOID_TO_QUEUE_POINTER_CONVERT(a) ((TX_QUEUE *) ((VOID *) (a))) +#define TX_VOID_TO_SEMAPHORE_POINTER_CONVERT(a) ((TX_SEMAPHORE *) ((VOID *) (a))) +#define TX_UCHAR_TO_VOID_POINTER_CONVERT(a) ((VOID *) (a)) +#define TX_ULONG_TO_THREAD_POINTER_CONVERT(a) ((TX_THREAD *) ((VOID *) (a))) +#ifndef TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT +#define TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(a) ((VOID *) (a)) +#endif +#ifndef TX_TIMER_INITIALIZE_EXTENSION +#define TX_TIMER_INITIALIZE_EXTENSION(a) +#endif +#define TX_CONST_CHAR_TO_CHAR_POINTER_CONVERT(a) ((CHAR *) ((VOID *) (a))) +#define TX_VOID_TO_THREAD_POINTER_CONVERT(a) ((TX_THREAD *) ((VOID *) (a))) +#define TX_CHAR_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR *) ((VOID *) (a))) + +#endif + + +/* Determine if there is an tx_api.h extension file to include. */ + +#ifdef TX_THREAD_API_EXTENSION + +/* Yes, bring in the tx_api.h extension file. */ +#include "tx_api_extension.h" #endif @@ -1567,7 +2047,7 @@ UINT tx_trace_user_event_insert(ULONG event_id, ULONG info_field_1, ULONG #error "TX_DISABLE_NOTIFY_CALLBACKS must not be defined." #endif -/* Ensure inline thread suspend/resume is not defined. */ +/* Ensure in-line thread suspend/resume is not defined. */ #ifdef TX_INLINE_THREAD_RESUME_SUSPEND #error "TX_INLINE_THREAD_RESUME_SUSPEND must not be defined." #endif @@ -1658,8 +2138,10 @@ void __ghs_rnerr(char *errMsg, int stackLevels, int stackTraceDisplay, void *hex #include "tx_el.h" #else #ifndef TX_SOURCE_CODE +#ifndef TX_MISRA_ENABLE #define _tx_el_user_event_insert(a,b,c,d,e) #endif +#endif #define TX_EL_INITIALIZE #define TX_EL_THREAD_REGISTER(a) #define TX_EL_THREAD_UNREGISTER(a) @@ -1728,7 +2210,7 @@ void __ghs_rnerr(char *errMsg, int stackLevels, int stackTraceDisplay, void *hex #define TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET_INSERT #define TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT #define TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET_INSERT -#define TX_EL_EVENT_FLAGS_PERFORMANCE_SYSTEM_INFO_GET_INSERT +#define TX_EL_EVENT_FLAGS__PERFORMANCE_SYSTEM_INFO_GET_INSERT #define TX_EL_EVENT_FLAGS_SET_NOTIFY_INSERT #define TX_EL_MUTEX_PERFORMANCE_INFO_GET_INSERT #define TX_EL_MUTEX_PERFORMANCE_SYSTEM_INFO_GET_INSERT diff --git a/3rd_party/threadx/tx_initialize_low_level.s b/3rd_party/threadx/tx_initialize_low_level.s deleted file mode 100644 index 87d53674..00000000 --- a/3rd_party/threadx/tx_initialize_low_level.s +++ /dev/null @@ -1,227 +0,0 @@ -;/**************************************************************************/ -;/* */ -;/* Copyright (c) 1996-2011 by Express Logic Inc. */ -;/* */ -;/* This software is copyrighted by and is the sole property of Express */ -;/* Logic, Inc. All rights, title, ownership, or other interests */ -;/* in the software remain the property of Express Logic, Inc. This */ -;/* software may only be used in accordance with the corresponding */ -;/* license agreement. Any unauthorized use, duplication, transmission, */ -;/* distribution, or disclosure of this software is expressly forbidden. */ -;/* */ -;/* This Copyright notice may not be removed or modified without prior */ -;/* written consent of Express Logic, Inc. */ -;/* */ -;/* Express Logic, Inc. reserves the right to modify this software */ -;/* without notice. */ -;/* */ -;/* Express Logic, Inc. info@expresslogic.com */ -;/* 11423 West Bernardo Court http://www.expresslogic.com */ -;/* San Diego, CA 92127 */ -;/* */ -;/**************************************************************************/ -; -; -;/**************************************************************************/ -;/**************************************************************************/ -;/** */ -;/** ThreadX Component */ -;/** */ -;/** Initialize */ -;/** */ -;/**************************************************************************/ -;/**************************************************************************/ -; -;#define TX_SOURCE_CODE -; -; -;/* Include necessary system files. */ -; -;#include "tx_api.h" -;#include "tx_initialize.h" -;#include "tx_thread.h" -;#include "tx_timer.h" -; -; - EXTERN _tx_thread_system_stack_ptr - EXTERN _tx_initialize_unused_memory - EXTERN _tx_thread_context_save - EXTERN _tx_thread_context_restore - EXTERN _tx_timer_interrupt - EXTERN __iar_program_start - EXTERN __tx_SVCallHandler - EXTERN __tx_PendSVHandler - EXTERN __tx_vectors - EXTERN __iar_program_start -; -; -SYSTEM_CLOCK EQU 150000000 -SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 100) -1) - - RSEG FREE_MEM:DATA - PUBLIC __tx_free_memory_start -__tx_free_memory_start - DS32 4 -; -; - SECTION `.text`:CODE:NOROOT(2) - THUMB -;/**************************************************************************/ -;/* */ -;/* FUNCTION RELEASE */ -;/* */ -;/* _tx_initialize_low_level Cortex-M4/IAR */ -;/* 5.1 */ -;/* AUTHOR */ -;/* */ -;/* William E. Lamie, Express Logic, Inc. */ -;/* */ -;/* DESCRIPTION */ -;/* */ -;/* This function is responsible for any low-level processor */ -;/* initialization, including setting up interrupt vectors, setting */ -;/* up a periodic timer interrupt source, saving the system stack */ -;/* pointer for use in ISR processing later, and finding the first */ -;/* available RAM memory address for tx_application_define. */ -;/* */ -;/* INPUT */ -;/* */ -;/* None */ -;/* */ -;/* OUTPUT */ -;/* */ -;/* None */ -;/* */ -;/* CALLS */ -;/* */ -;/* None */ -;/* */ -;/* CALLED BY */ -;/* */ -;/* _tx_initialize_kernel_enter ThreadX entry function */ -;/* */ -;/* RELEASE HISTORY */ -;/* */ -;/* DATE NAME DESCRIPTION */ -;/* */ -;/* 10-10-2010 William E. Lamie Initial Version 5.0 */ -;/* 07-15-2011 William E. Lamie Modified comment(s), */ -;/* resulting in version 5.1 */ -;/* */ -;/**************************************************************************/ -;VOID _tx_initialize_low_level(VOID) -;{ - PUBLIC _tx_initialize_low_level -_tx_initialize_low_level: -; -; /* Ensure that interrupts are disabled. */ -; - - CPSID i ; Disable interrupts -; -; -; /* Set base of available memory to end of non-initialised RAM area. */ -; - LDR r0, =__tx_free_memory_start ; Get end of non-initialized RAM area - LDR r2, =_tx_initialize_unused_memory ; Build address of unused memory pointer - STR r0, [r2, #0] ; Save first free memory address -; -; /* Enable the cycle count register. */ -; - LDR r0, =0xE0001000 ; Build address of DWT register - LDR r1, [r0] ; Pickup the current value - ORR r1, r1, #1 ; Set the CYCCNTENA bit - STR r1, [r0] ; Enable the cycle count register -; -; /* Setup Vector Table Offset Register. */ -; - MOV r0, #0xE000E000 ; Build address of NVIC registers - LDR r1, =__tx_vectors ; Pickup address of vector table - STR r1, [r0, #0xD08] ; Set vector table address -; -; /* Set system stack pointer from vector value. */ -; - LDR r0, =_tx_thread_system_stack_ptr ; Build address of system stack pointer - LDR r1, =__tx_vectors ; Pickup address of vector table - LDR r1, [r1] ; Pickup reset stack pointer - STR r1, [r0] ; Save system stack pointer -; -; /* Configure SysTick for 100Hz clock, or 16384 cycles if no reference. */ -; - MOV r0, #0xE000E000 ; Build address of NVIC registers - LDR r1, =SYSTICK_CYCLES - STR r1, [r0, #0x14] ; Setup SysTick Reload Value - MOV r1, #0x7 ; Build SysTick Control Enable Value - STR r1, [r0, #0x10] ; Setup SysTick Control -; -; /* Configure handler priorities. */ -; - LDR r1, =0x00000000 ; Rsrv, UsgF, BusF, MemM - STR r1, [r0, #0xD18] ; Setup System Handlers 4-7 Priority Registers - - LDR r1, =0xFF000000 ; SVCl, Rsrv, Rsrv, Rsrv - STR r1, [r0, #0xD1C] ; Setup System Handlers 8-11 Priority Registers - ; Note: SVC must be lowest priority, which is 0xFF - - LDR r1, =0x40FF0000 ; SysT, PnSV, Rsrv, DbgM - STR r1, [r0, #0xD20] ; Setup System Handlers 12-15 Priority Registers - ; Note: PnSV must be lowest priority, which is 0xFF - - LDR r0, =0xE000EF34 ; Pickup FPCCR - LDR r1, [r0] ; - LDR r2, =0x3FFFFFFF ; Build mask to clear ASPEN and LSPEN - AND r1, r1, r2 ; Clear the ASPEN and LSPEN bits - STR r1, [r0] ; Update FPCCR -; -; /* Return to caller. */ -; - BX lr -;} -; -; - - PUBLIC __stack_test -__stack_test: - push {r0} - push {r1} - push {r2} - push {r3} - pop {r3} - pop {r2} - pop {r1} - pop {r0} - bx lr - - -;/* Define shells for each of the unused vectors. */ -; - - PUBLIC __tx_IntHandler -__tx_IntHandler: -; VOID InterruptHandler (VOID) -; { - PUSH {lr} - BL _tx_thread_context_save - -; /* Do interrupt handler work here */ -; /* .... */ - - B _tx_thread_context_restore -; } - - PUBLIC __tx_SysTickHandler -__tx_SysTickHandler: -; VOID TimerInterruptHandler (VOID) -; { -; - PUSH {lr} - BL _tx_thread_context_save - MOV r0, #0xE000E000 ; Build address of NVIC registers - LDR r1, [r0, #0x10] ; Clear SysTick interrupt - BL _tx_timer_interrupt - B _tx_thread_context_restore -; } - - END - - diff --git a/3rd_party/threadx/tx_trace.h b/3rd_party/threadx/tx_trace.h new file mode 100644 index 00000000..7aa9de3c --- /dev/null +++ b/3rd_party/threadx/tx_trace.h @@ -0,0 +1,612 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 1996-2017 by Express Logic Inc. */ +/* */ +/* This software is copyrighted by and is the sole property of Express */ +/* Logic, Inc. All rights, title, ownership, or other interests */ +/* in the software remain the property of Express Logic, Inc. This */ +/* software may only be used in accordance with the corresponding */ +/* license agreement. Any unauthorized use, duplication, transmission, */ +/* distribution, or disclosure of this software is expressly forbidden. */ +/* */ +/* This Copyright notice may not be removed or modified without prior */ +/* written consent of Express Logic, Inc. */ +/* */ +/* Express Logic, Inc. reserves the right to modify this software */ +/* without notice. */ +/* */ +/* Express Logic, Inc. info@expresslogic.com */ +/* 11423 West Bernardo Court www.expresslogic.com */ +/* San Diego, CA 92127 */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Trace */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* COMPONENT DEFINITION RELEASE */ +/* */ +/* tx_trace.h PORTABLE C */ +/* 5.8 */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Express Logic, Inc. */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file defines the ThreadX trace component, including constants */ +/* and structure definitions as well as external references. It is */ +/* assumed that tx_api.h and tx_port.h have already been included. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 12-12-2005 William E. Lamie Initial Version 5.0 */ +/* 04-02-2007 William E. Lamie Modified comment(s), */ +/* resulting in version 5.1 */ +/* 12-12-2008 William E. Lamie Modified comment(s), added */ +/* new event definitions, */ +/* changed types to ensure the */ +/* trace has universal format, */ +/* optimized event macro, and */ +/* added filter logic and new */ +/* function prototypes, */ +/* resulting in version 5.2 */ +/* 07-04-2009 William E. Lamie Modified comment(s), removed */ +/* FileX & NetX event IDs since*/ +/* they are defined elsewhere, */ +/* and corrected priority */ +/* assignment in event trace, */ +/* resulting in version 5.3 */ +/* 12-12-2009 William E. Lamie Modified comment(s), added */ +/* defines for default source, */ +/* and added logic to insert */ +/* the thread's preemption- */ +/* threshold along with its */ +/* priority, resulting in */ +/* version 5.4 */ +/* 07-15-2011 William E. Lamie Modified comment(s), and */ +/* added variables for object */ +/* registry optimizations, */ +/* resulting in version 5.5 */ +/* 11-01-2012 William E. Lamie Modified comment(s), and */ +/* added conditional around */ +/* Trace function prototypes, */ +/* resulting in version 5.6 */ +/* 05-01-2015 William E. Lamie Modified comment(s), and */ +/* modified code for MISRA */ +/* compliance, resulting in */ +/* version 5.7 */ +/* 06-01-2017 William E. Lamie Modified comment(s), made */ +/* MISRA compatibility changes,*/ +/* and utilized macros for */ +/* system state and current */ +/* thread pointer retrieval, */ +/* resulting in version 5.8 */ +/* */ +/**************************************************************************/ + + +/* Include necessary system files. */ + +#ifndef TX_TRACE_H +#define TX_TRACE_H + + +/* Determine if tracing is enabled. If not, simply define the in-line trace + macros to whitespace. */ + +#ifndef TX_ENABLE_EVENT_TRACE +#define TX_TRACE_INITIALIZE +#define TX_TRACE_OBJECT_REGISTER(t,p,n,a,b) +#define TX_TRACE_OBJECT_UNREGISTER(o) +#define TX_TRACE_IN_LINE_INSERT(i,a,b,c,d,f) +#else + +/* Event tracing is enabled. */ + +/* Ensure that the thread component information is included. */ + +#include "tx_thread.h" + + +/* Define trace port-specfic extension to white space if it isn't defined + already. */ + +#ifndef TX_TRACE_PORT_EXTENSION +#define TX_TRACE_PORT_EXTENSION +#endif + + +/* Define the default clock source for trace event entry time stamp. The following two item are port specific. + For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock + source constants would be: + +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) +#define TX_TRACE_TIME_MASK 0x0000FFFFUL + +*/ + +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the ID showing the event trace buffer is valid. */ + +#define TX_TRACE_VALID 0x54585442UL + + +/* ThreadX Trace Description. The ThreadX Trace feature is designed to capture + events in real-time in a circular event buffer. This buffer may be analyzed by other + tools. The high-level format of the Trace structure is: + + [Trace Control Header ] + [Trace Object Registry - Entry 0 ] + ... + [Trace Object Registry - Entry "n" ] + [Trace Buffer - Entry 0 ] + ... + [Trace Buffer - Entry "n" ] + +*/ + + +/* Trace Control Header. The Trace Control Header contains information that + defines the format of the Trace Object Registry as well as the location and + current entry of the Trace Buffer itself. The high-level format of the + Trace Control Header is: + + Entry Size Description + + [Trace ID] 4 This 4-byte field contains the ThreadX Trace + Identification. If the trace buffer is valid, the + contents are 0x54585442 (TXTB). Since it is written as + a 32-bit unsigned word, this value is also used to + determine if the event trace information is in + little or big endian format. + [Timer Valid Mask] 4 Mask of valid bits in the 32-bit time stamp. This + enables use of 32, 24, 16, or event 8-bit timers. + If the time source is 32-bits, the mask is + 0xFFFFFFFF. If the time source is 16-bits, the + mask is 0x0000FFFF. + [Trace Base Address] 4 The base address for all trace pointer. Subtracting + the pointer and this address will yield the proper + offset into the trace buffer. + [Trace Object Registry Start Pointer] 4 Pointer to the start of Trace Object Registry + [Reserved] 2 Reserved two bytes - should be 0x0000 + [Trace Object Object Name Size] 2 Number of bytes in object name + [Trace Object Registry End Pointer] 4 Pointer to the end of Trace Object Registry + [Trace Buffer Start Pointer] 4 Pointer to the start of the Trace Buffer Area + [Trace Buffer End Pointer] 4 Pointer to the end of the Trace Buffer Area + [Trace Buffer Current Pointer] 4 Pointer to the oldest entry in the Trace Buffer. + This entry will be overwritten on the next event and + incremented to the next event (wrapping to the top + if the buffer end pointer is exceeded). + [Reserved] 4 Reserved 4 bytes, should be 0xAAAAAAAA + [Reserved] 4 Reserved 4 bytes, should be 0xBBBBBBBB + [Reserved] 4 Reserved 4 bytes, should be 0xCCCCCCCC +*/ + + +/* Define the Trace Control Header. */ + +typedef struct TX_TRACE_HEADER_STRUCT +{ + + ULONG tx_trace_header_id; + ULONG tx_trace_header_timer_valid_mask; + ULONG tx_trace_header_trace_base_address; + ULONG tx_trace_header_registry_start_pointer; + USHORT tx_trace_header_reserved1; + USHORT tx_trace_header_object_name_size; + ULONG tx_trace_header_registry_end_pointer; + ULONG tx_trace_header_buffer_start_pointer; + ULONG tx_trace_header_buffer_end_pointer; + ULONG tx_trace_header_buffer_current_pointer; + ULONG tx_trace_header_reserved2; + ULONG tx_trace_header_reserved3; + ULONG tx_trace_header_reserved4; +} TX_TRACE_HEADER; + + +/* Trace Object Registry. The Trace Object Registry is used to map the object pointer in the trace buffer to + the application's name for the object (defined during object creation in ThreadX). */ + +#ifndef TX_TRACE_OBJECT_REGISTRY_NAME +#define TX_TRACE_OBJECT_REGISTRY_NAME 32 +#endif + + +/* Define the object name types as well as the contents of any additional parameters that might be useful in + trace analysis. */ + +#define TX_TRACE_OBJECT_TYPE_NOT_VALID ((UCHAR) 0) /* Object is not valid */ +#define TX_TRACE_OBJECT_TYPE_THREAD ((UCHAR) 1) /* P1 = stack start address, P2 = stack size */ +#define TX_TRACE_OBJECT_TYPE_TIMER ((UCHAR) 2) /* P1 = initial ticks, P2 = reschedule ticks */ +#define TX_TRACE_OBJECT_TYPE_QUEUE ((UCHAR) 3) /* P1 = queue size, P2 = message size */ +#define TX_TRACE_OBJECT_TYPE_SEMAPHORE ((UCHAR) 4) /* P1 = initial instances */ +#define TX_TRACE_OBJECT_TYPE_MUTEX ((UCHAR) 5) /* P1 = priority inheritance flag */ +#define TX_TRACE_OBJECT_TYPE_EVENT_FLAGS ((UCHAR) 6) /* none */ +#define TX_TRACE_OBJECT_TYPE_BLOCK_POOL ((UCHAR) 7) /* P1 = total blocks, P2 = block size */ +#define TX_TRACE_OBJECT_TYPE_BYTE_POOL ((UCHAR) 8) /* P1 = total bytes */ + + +typedef struct TX_TRACE_OBJECT_ENTRY_STRUCT +{ + + UCHAR tx_trace_object_entry_available; /* TX_TRUE -> available */ + UCHAR tx_trace_object_entry_type; /* Types defined above */ + UCHAR tx_trace_object_entry_reserved1; /* Should be zero - except for thread */ + UCHAR tx_trace_object_entry_reserved2; /* Should be zero - except for thread */ + ULONG tx_trace_object_entry_thread_pointer; /* ThreadX object pointer */ + ULONG tx_trace_object_entry_param_1; /* Parameter value defined */ + ULONG tx_trace_object_entry_param_2; /* according to type above */ + UCHAR tx_trace_object_entry_name[TX_TRACE_OBJECT_REGISTRY_NAME]; /* Object name */ +} TX_TRACE_OBJECT_ENTRY; + + +/* Trace Buffer Entry. The Trace Buffer Entry contains information about a particular + event in the system. The high-level format of the Trace Buffer Entry is: + + Entry Size Description + + [Thread Pointer] 4 This 4-byte field contains the pointer to the + ThreadX thread running that caused the event. + If this field is NULL, the entry hasn't been used + yet. If this field is 0xFFFFFFFF, the event occurred + from within an ISR. If this entry is 0xF0F0F0F0, the + event occurred during initialization. + [Thread Priority or 4 This 4-byte field contains the current thread pointer for interrupt + Current Thread events or the thread preemption-threshold/priority for thread events. + Preemption-Threshold/ + Priority] + [Event ID] 4 This 4-byte field contains the Event ID of the event. A value of + 0xFFFFFFFF indicates the event is invalid. All events are marked + as invalid during initialization. + [Time Stamp] 4 This 4-byte field contains the time stamp of the event. + [Information Field 1] 4 This 4-byte field contains the first 4-bytes of information + specific to the event. + [Information Field 2] 4 This 4-byte field contains the second 4-bytes of information + specific to the event. + [Information Field 3] 4 This 4-byte field contains the third 4-bytes of information + specific to the event. + [Information Field 4] 4 This 4-byte field contains the fourth 4-bytes of information + specific to the event. +*/ + +#define TX_TRACE_INVALID_EVENT 0xFFFFFFFFUL + + +/* Define ThreadX Trace Events, along with a brief description of the additional information fields, + where I1 -> Information Field 1, I2 -> Information Field 2, etc. */ + +/* Event numbers 0 through 4095 are reserved by Express Logic. Specific event assignments are: + + ThreadX events: 1-199 + FileX events: 200-299 + NetX events: 300-599 + USBX events: 600-999 + + User-defined event numbers start at 4096 and continue through 65535, as defined by the constants + TX_TRACE_USER_EVENT_START and TX_TRACE_USER_EVENT_END, respectively. User events should be based + on these constants in case the user event number assignment is changed in future releases. */ + +/* Define the basic ThreadX thread scheduling events first. */ + +#define TX_TRACE_THREAD_RESUME 1 /* I1 = thread ptr, I2 = previous_state, I3 = stack ptr, I4 = next thread */ +#define TX_TRACE_THREAD_SUSPEND 2 /* I1 = thread ptr, I2 = new_state, I3 = stack ptr I4 = next thread */ +#define TX_TRACE_ISR_ENTER 3 /* I1 = stack_ptr, I2 = ISR number, I3 = system state, I4 = preempt disable */ +#define TX_TRACE_ISR_EXIT 4 /* I1 = stack_ptr, I2 = ISR number, I3 = system state, I4 = preempt disable */ +#define TX_TRACE_TIME_SLICE 5 /* I1 = next thread ptr, I2 = system state, I3 = preempt disable, I4 = stack*/ +#define TX_TRACE_RUNNING 6 /* None */ + + +/* Define the rest of the ThreadX system events. */ + +#define TX_TRACE_BLOCK_ALLOCATE 10 /* I1 = pool ptr, I2 = memory ptr, I3 = wait option, I4 = remaining blocks */ +#define TX_TRACE_BLOCK_POOL_CREATE 11 /* I1 = pool ptr, I2 = pool_start, I3 = total blocks, I4 = block size */ +#define TX_TRACE_BLOCK_POOL_DELETE 12 /* I1 = pool ptr, I2 = stack ptr */ +#define TX_TRACE_BLOCK_POOL_INFO_GET 13 /* I1 = pool ptr */ +#define TX_TRACE_BLOCK_POOL_PERFORMANCE_INFO_GET 14 /* I1 = pool ptr */ +#define TX_TRACE_BLOCK_POOL__PERFORMANCE_SYSTEM_INFO_GET 15 /* None */ +#define TX_TRACE_BLOCK_POOL_PRIORITIZE 16 /* I1 = pool ptr, I2 = suspended count, I3 = stack ptr */ +#define TX_TRACE_BLOCK_RELEASE 17 /* I1 = pool ptr, I2 = memory ptr, I3 = suspended, I4 = stack ptr */ +#define TX_TRACE_BYTE_ALLOCATE 20 /* I1 = pool ptr, I2 = memory ptr, I3 = size requested, I4 = wait option */ +#define TX_TRACE_BYTE_POOL_CREATE 21 /* I1 = pool ptr, I2 = start ptr, I3 = pool size, I4 = stack ptr */ +#define TX_TRACE_BYTE_POOL_DELETE 22 /* I1 = pool ptr, I2 = stack ptr */ +#define TX_TRACE_BYTE_POOL_INFO_GET 23 /* I1 = pool ptr */ +#define TX_TRACE_BYTE_POOL_PERFORMANCE_INFO_GET 24 /* I1 = pool ptr */ +#define TX_TRACE_BYTE_POOL__PERFORMANCE_SYSTEM_INFO_GET 25 /* None */ +#define TX_TRACE_BYTE_POOL_PRIORITIZE 26 /* I1 = pool ptr, I2 = suspended count, I3 = stack ptr */ +#define TX_TRACE_BYTE_RELEASE 27 /* I1 = pool ptr, I2 = memory ptr, I3 = suspended, I4 = available bytes */ +#define TX_TRACE_EVENT_FLAGS_CREATE 30 /* I1 = group ptr, I2 = stack ptr */ +#define TX_TRACE_EVENT_FLAGS_DELETE 31 /* I1 = group ptr, I2 = stack ptr */ +#define TX_TRACE_EVENT_FLAGS_GET 32 /* I1 = group ptr, I2 = requested flags, I3 = current flags, I4 = get option*/ +#define TX_TRACE_EVENT_FLAGS_INFO_GET 33 /* I1 = group ptr */ +#define TX_TRACE_EVENT_FLAGS_PERFORMANCE_INFO_GET 34 /* I1 = group ptr */ +#define TX_TRACE_EVENT_FLAGS__PERFORMANCE_SYSTEM_INFO_GET 35 /* None */ +#define TX_TRACE_EVENT_FLAGS_SET 36 /* I1 = group ptr, I2 = flags to set, I3 = set option, I4= suspended count */ +#define TX_TRACE_EVENT_FLAGS_SET_NOTIFY 37 /* I1 = group ptr */ +#define TX_TRACE_INTERRUPT_CONTROL 40 /* I1 = new interrupt posture, I2 = stack ptr */ +#define TX_TRACE_MUTEX_CREATE 50 /* I1 = mutex ptr, I2 = inheritance, I3 = stack ptr */ +#define TX_TRACE_MUTEX_DELETE 51 /* I1 = mutex ptr, I2 = stack ptr */ +#define TX_TRACE_MUTEX_GET 52 /* I1 = mutex ptr, I2 = wait option, I3 = owning thread, I4 = own count */ +#define TX_TRACE_MUTEX_INFO_GET 53 /* I1 = mutex ptr */ +#define TX_TRACE_MUTEX_PERFORMANCE_INFO_GET 54 /* I1 = mutex ptr */ +#define TX_TRACE_MUTEX_PERFORMANCE_SYSTEM_INFO_GET 55 /* None */ +#define TX_TRACE_MUTEX_PRIORITIZE 56 /* I1 = mutex ptr, I2 = suspended count, I3 = stack ptr */ +#define TX_TRACE_MUTEX_PUT 57 /* I1 = mutex ptr, I2 = owning thread, I3 = own count, I4 = stack ptr */ +#define TX_TRACE_QUEUE_CREATE 60 /* I1 = queue ptr, I2 = message size, I3 = queue start, I4 = queue size */ +#define TX_TRACE_QUEUE_DELETE 61 /* I1 = queue ptr, I2 = stack ptr */ +#define TX_TRACE_QUEUE_FLUSH 62 /* I1 = queue ptr, I2 = stack ptr */ +#define TX_TRACE_QUEUE_FRONT_SEND 63 /* I1 = queue ptr, I2 = source ptr, I3 = wait option, I4 = enqueued */ +#define TX_TRACE_QUEUE_INFO_GET 64 /* I1 = queue ptr */ +#define TX_TRACE_QUEUE_PERFORMANCE_INFO_GET 65 /* I1 = queue ptr */ +#define TX_TRACE_QUEUE_PERFORMANCE_SYSTEM_INFO_GET 66 /* None */ +#define TX_TRACE_QUEUE_PRIORITIZE 67 /* I1 = queue ptr, I2 = suspended count, I3 = stack ptr */ +#define TX_TRACE_QUEUE_RECEIVE 68 /* I1 = queue ptr, I2 = destination ptr, I3 = wait option, I4 = enqueued */ +#define TX_TRACE_QUEUE_SEND 69 /* I1 = queue ptr, I2 = source ptr, I3 = wait option, I4 = enqueued */ +#define TX_TRACE_QUEUE_SEND_NOTIFY 70 /* I1 = queue ptr */ +#define TX_TRACE_SEMAPHORE_CEILING_PUT 80 /* I1 = semaphore ptr, I2 = current count, I3 = suspended count,I4 =ceiling */ +#define TX_TRACE_SEMAPHORE_CREATE 81 /* I1 = semaphore ptr, I2 = initial count, I3 = stack ptr */ +#define TX_TRACE_SEMAPHORE_DELETE 82 /* I1 = semaphore ptr, I2 = stack ptr */ +#define TX_TRACE_SEMAPHORE_GET 83 /* I1 = semaphore ptr, I2 = wait option, I3 = current count, I4 = stack ptr */ +#define TX_TRACE_SEMAPHORE_INFO_GET 84 /* I1 = semaphore ptr */ +#define TX_TRACE_SEMAPHORE_PERFORMANCE_INFO_GET 85 /* I1 = semaphore ptr */ +#define TX_TRACE_SEMAPHORE__PERFORMANCE_SYSTEM_INFO_GET 86 /* None */ +#define TX_TRACE_SEMAPHORE_PRIORITIZE 87 /* I1 = semaphore ptr, I2 = suspended count, I2 = stack ptr */ +#define TX_TRACE_SEMAPHORE_PUT 88 /* I1 = semaphore ptr, I2 = current count, I3 = suspended count,I4=stack ptr*/ +#define TX_TRACE_SEMAPHORE_PUT_NOTIFY 89 /* I1 = semaphore ptr */ +#define TX_TRACE_THREAD_CREATE 100 /* I1 = thread ptr, I2 = priority, I3 = stack ptr, I4 = stack_size */ +#define TX_TRACE_THREAD_DELETE 101 /* I1 = thread ptr, I2 = stack ptr */ +#define TX_TRACE_THREAD_ENTRY_EXIT_NOTIFY 102 /* I1 = thread ptr, I2 = thread state, I3 = stack ptr */ +#define TX_TRACE_THREAD_IDENTIFY 103 /* None */ +#define TX_TRACE_THREAD_INFO_GET 104 /* I1 = thread ptr, I2 = thread state */ +#define TX_TRACE_THREAD_PERFORMANCE_INFO_GET 105 /* I1 = thread ptr, I2 = thread state */ +#define TX_TRACE_THREAD_PERFORMANCE_SYSTEM_INFO_GET 106 /* None */ +#define TX_TRACE_THREAD_PREEMPTION_CHANGE 107 /* I1 = thread ptr, I2 = new threshold, I3 = old threshold, I4 =thread state*/ +#define TX_TRACE_THREAD_PRIORITY_CHANGE 108 /* I1 = thread ptr, I2 = new priority, I3 = old priority, I4 = thread state */ +#define TX_TRACE_THREAD_RELINQUISH 109 /* I1 = stack ptr, I2 = next thread ptr */ +#define TX_TRACE_THREAD_RESET 110 /* I1 = thread ptr, I2 = thread state */ +#define TX_TRACE_THREAD_RESUME_API 111 /* I1 = thread ptr, I2 = thread state, I3 = stack ptr */ +#define TX_TRACE_THREAD_SLEEP 112 /* I1 = sleep value, I2 = thread state, I3 = stack ptr */ +#define TX_TRACE_THREAD_STACK_ERROR_NOTIFY 113 /* None */ +#define TX_TRACE_THREAD_SUSPEND_API 114 /* I1 = thread ptr, I2 = thread state, I3 = stack ptr */ +#define TX_TRACE_THREAD_TERMINATE 115 /* I1 = thread ptr, I2 = thread state, I3 = stack ptr */ +#define TX_TRACE_THREAD_TIME_SLICE_CHANGE 116 /* I1 = thread ptr, I2 = new timeslice, I3 = old timeslice */ +#define TX_TRACE_THREAD_WAIT_ABORT 117 /* I1 = thread ptr, I2 = thread state, I3 = stack ptr */ +#define TX_TRACE_TIME_GET 120 /* I1 = current time, I2 = stack ptr */ +#define TX_TRACE_TIME_SET 121 /* I1 = new time */ +#define TX_TRACE_TIMER_ACTIVATE 122 /* I1 = timer ptr */ +#define TX_TRACE_TIMER_CHANGE 123 /* I1 = timer ptr, I2 = initial ticks, I3= reschedule ticks */ +#define TX_TRACE_TIMER_CREATE 124 /* I1 = timer ptr, I2 = initial ticks, I3= reschedule ticks, I4 = enable */ +#define TX_TRACE_TIMER_DEACTIVATE 125 /* I1 = timer ptr, I2 = stack ptr */ +#define TX_TRACE_TIMER_DELETE 126 /* I1 = timer ptr */ +#define TX_TRACE_TIMER_INFO_GET 127 /* I1 = timer ptr, I2 = stack ptr */ +#define TX_TRACE_TIMER_PERFORMANCE_INFO_GET 128 /* I1 = timer ptr */ +#define TX_TRACE_TIMER_PERFORMANCE_SYSTEM_INFO_GET 129 /* None */ + + +/* Define the an Trace Buffer Entry. */ + +typedef struct TX_TRACE_BUFFER_ENTRY_STRUCT +{ + + ULONG tx_trace_buffer_entry_thread_pointer; + ULONG tx_trace_buffer_entry_thread_priority; + ULONG tx_trace_buffer_entry_event_id; + ULONG tx_trace_buffer_entry_time_stamp; +#ifdef TX_MISRA_ENABLE + ULONG tx_trace_buffer_entry_info_1; + ULONG tx_trace_buffer_entry_info_2; + ULONG tx_trace_buffer_entry_info_3; + ULONG tx_trace_buffer_entry_info_4; +#else + ULONG tx_trace_buffer_entry_information_field_1; + ULONG tx_trace_buffer_entry_information_field_2; + ULONG tx_trace_buffer_entry_information_field_3; + ULONG tx_trace_buffer_entry_information_field_4; +#endif +} TX_TRACE_BUFFER_ENTRY; + + +/* Trace management component data declarations follow. */ + +/* Determine if the initialization function of this component is including + this file. If so, make the data definitions really happen. Otherwise, + make them extern so other functions in the component can access them. */ + +#ifdef TX_TRACE_INIT +#define TRACE_DECLARE +#else +#define TRACE_DECLARE extern +#endif + + +/* Define the pointer to the start of the trace buffer control structure. */ + +TRACE_DECLARE TX_TRACE_HEADER *_tx_trace_header_ptr; + + +/* Define the pointer to the start of the trace object registry area in the trace buffer. */ + +TRACE_DECLARE TX_TRACE_OBJECT_ENTRY *_tx_trace_registry_start_ptr; + + +/* Define the pointer to the end of the trace object registry area in the trace buffer. */ + +TRACE_DECLARE TX_TRACE_OBJECT_ENTRY *_tx_trace_registry_end_ptr; + + +/* Define the pointer to the starting entry of the actual trace event area of the trace buffer. */ + +TRACE_DECLARE TX_TRACE_BUFFER_ENTRY *_tx_trace_buffer_start_ptr; + + +/* Define the pointer to the ending entry of the actual trace event area of the trace buffer. */ + +TRACE_DECLARE TX_TRACE_BUFFER_ENTRY *_tx_trace_buffer_end_ptr; + + +/* Define the pointer to the current entry of the actual trace event area of the trace buffer. */ + +TRACE_DECLARE TX_TRACE_BUFFER_ENTRY *_tx_trace_buffer_current_ptr; + + +/* Define the trace event enable bits, where each bit represents a type of event that can be enabled + or disabled dynamically by the application. */ + +TRACE_DECLARE ULONG _tx_trace_event_enable_bits; + + +/* Define a counter that is used in environments that don't have a timer source. This counter + is incremented on each use giving each event a unique timestamp. */ + +TRACE_DECLARE ULONG _tx_trace_simulated_time; + + +/* Define the function pointer used to call the application when the trace buffer wraps. If NULL, + the application has not registered a callback function. */ + +TRACE_DECLARE VOID (*_tx_trace_full_notify_function)(VOID *buffer); + + +/* Define the total number of registry entries. */ + +TRACE_DECLARE ULONG _tx_trace_total_registry_entries; + + +/* Define a counter that is used to track the number of available registry entries. */ + +TRACE_DECLARE ULONG _tx_trace_available_registry_entries; + + +/* Define an index that represents the start of the registry search. */ + +TRACE_DECLARE ULONG _tx_trace_registry_search_start; + + +/* Define the event trace macros that are expanded in-line when event tracing is enabled. */ + +#ifdef TX_MISRA_ENABLE +#define TX_TRACE_INFO_FIELD_ASSIGNMENT(a,b,c,d) trace_event_ptr -> tx_trace_buffer_entry_info_1 = (ULONG) (a); trace_event_ptr -> tx_trace_buffer_entry_info_2 = (ULONG) (b); trace_event_ptr -> tx_trace_buffer_entry_info_3 = (ULONG) (c); trace_event_ptr -> tx_trace_buffer_entry_info_4 = (ULONG) (d); +#else +#define TX_TRACE_INFO_FIELD_ASSIGNMENT(a,b,c,d) trace_event_ptr -> tx_trace_buffer_entry_information_field_1 = (ULONG) (a); trace_event_ptr -> tx_trace_buffer_entry_information_field_2 = (ULONG) (b); trace_event_ptr -> tx_trace_buffer_entry_information_field_3 = (ULONG) (c); trace_event_ptr -> tx_trace_buffer_entry_information_field_4 = (ULONG) (d); +#endif + + +#define TX_TRACE_INITIALIZE _tx_trace_initialize(); +#define TX_TRACE_OBJECT_REGISTER(t,p,n,a,b) _tx_trace_object_register((UCHAR) (t), (VOID *) (p), (CHAR *) (n), (ULONG) (a), (ULONG) (b)); +#define TX_TRACE_OBJECT_UNREGISTER(o) _tx_trace_object_unregister((VOID *) (o)); +#ifndef TX_TRACE_IN_LINE_INSERT +#define TX_TRACE_IN_LINE_INSERT(i,a,b,c,d,e) \ + { \ + TX_TRACE_BUFFER_ENTRY *trace_event_ptr; \ + ULONG trace_system_state; \ + ULONG trace_priority; \ + TX_THREAD *trace_thread_ptr; \ + trace_event_ptr = _tx_trace_buffer_current_ptr; \ + if ((trace_event_ptr) && (_tx_trace_event_enable_bits & ((ULONG) (e)))) \ + { \ + TX_TRACE_PORT_EXTENSION \ + trace_system_state = (ULONG) TX_THREAD_GET_SYSTEM_STATE(); \ + TX_THREAD_GET_CURRENT(trace_thread_ptr) \ + \ + if (trace_system_state == 0) \ + { \ + trace_priority = trace_thread_ptr -> tx_thread_priority; \ + trace_priority = trace_priority | 0x80000000UL | (trace_thread_ptr -> tx_thread_preempt_threshold << 16); \ + } \ + else if (trace_system_state < 0xF0F0F0F0UL) \ + { \ + trace_priority = (ULONG) trace_thread_ptr; \ + trace_thread_ptr = (TX_THREAD *) 0xFFFFFFFFUL; \ + } \ + else \ + { \ + trace_thread_ptr = (TX_THREAD *) 0xF0F0F0F0UL; \ + trace_priority = 0; \ + } \ + trace_event_ptr -> tx_trace_buffer_entry_thread_pointer = (ULONG) trace_thread_ptr; \ + trace_event_ptr -> tx_trace_buffer_entry_thread_priority = (ULONG) trace_priority; \ + trace_event_ptr -> tx_trace_buffer_entry_event_id = (ULONG) (i); \ + trace_event_ptr -> tx_trace_buffer_entry_time_stamp = (ULONG) TX_TRACE_TIME_SOURCE; \ + TX_TRACE_INFO_FIELD_ASSIGNMENT((a),(b),(c),(d)) \ + trace_event_ptr++; \ + if (trace_event_ptr >= _tx_trace_buffer_end_ptr) \ + { \ + trace_event_ptr = _tx_trace_buffer_start_ptr; \ + _tx_trace_buffer_current_ptr = trace_event_ptr; \ + _tx_trace_header_ptr -> tx_trace_header_buffer_current_pointer = (ULONG) trace_event_ptr; \ + if (_tx_trace_full_notify_function) \ + (_tx_trace_full_notify_function)((VOID *) _tx_trace_header_ptr); \ + } \ + else \ + { \ + _tx_trace_buffer_current_ptr = trace_event_ptr; \ + _tx_trace_header_ptr -> tx_trace_header_buffer_current_pointer = (ULONG) trace_event_ptr; \ + } \ + } \ + } +#endif +#endif + + +#ifdef TX_SOURCE_CODE + +/* Define internal function prototypes of the trace component, only if compiling ThreadX source code. */ + +VOID _tx_trace_initialize(VOID); +VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2); +VOID _tx_trace_object_unregister(VOID *object_ptr); + + +#ifdef TX_ENABLE_EVENT_TRACE + +/* Check for MISRA compliance requirements. */ + +#ifdef TX_MISRA_ENABLE + +/* Define MISRA-specific routines. */ + +UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); +TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); +TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); +TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); +UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); + + +#define TX_OBJECT_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_object_to_uchar_pointer_convert((a)) +#define TX_UCHAR_TO_OBJECT_POINTER_CONVERT(a) _tx_misra_uchar_to_object_pointer_convert((a)) +#define TX_UCHAR_TO_HEADER_POINTER_CONVERT(a) _tx_misra_uchar_to_header_pointer_convert((a)) +#define TX_UCHAR_TO_ENTRY_POINTER_CONVERT(a) _tx_misra_uchar_to_entry_pointer_convert((a)) +#define TX_ENTRY_TO_UCHAR_POINTER_CONVERT(a) _tx_misra_entry_to_uchar_pointer_convert((a)) + +#else + +#define TX_OBJECT_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR *) ((VOID *) (a))) +#define TX_UCHAR_TO_OBJECT_POINTER_CONVERT(a) ((TX_TRACE_OBJECT_ENTRY *) ((VOID *) (a))) +#define TX_UCHAR_TO_HEADER_POINTER_CONVERT(a) ((TX_TRACE_HEADER *) ((VOID *) (a))) +#define TX_UCHAR_TO_ENTRY_POINTER_CONVERT(a) ((TX_TRACE_BUFFER_ENTRY *) ((VOID *) (a))) +#define TX_ENTRY_TO_UCHAR_POINTER_CONVERT(a) ((UCHAR *) ((VOID *) (a))) + +#endif +#endif +#endif +#endif + diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.cpp b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.cpp new file mode 100644 index 00000000..24b2b4cc --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.cpp @@ -0,0 +1,407 @@ +//**************************************************************************** +// Product: DPP example, EK-TM4C123GXL board, ThreadX kernel +// Last Updated for Version: 6.3.7 +// Date of the Last Update: 2018-12-17 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005-2018 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 . +// +// Contact information: +// https://www.state-machine.com +// mailto:info@state-machine.com +//**************************************************************************** +#include "qpcpp.h" +#include "dpp.h" +#include "bsp.h" + +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// namespace DPP ************************************************************* +namespace DPP { + +// Local-scope objects ------------------------------------------------------- +#define LED_RED (1U << 1) +#define LED_BLUE (1U << 2) +#define LED_GREEN (1U << 3) + +#define BTN_SW1 (1U << 4) +#define BTN_SW2 (1U << 0) + +static unsigned l_rnd; // random seed + +#ifdef Q_SPY + QP::QSTimeCtr QS_tickTime_; + QP::QSTimeCtr QS_tickPeriod_; + + #define UART_BAUD_RATE 115200U + #define UART_FR_TXFE (1U << 7) + #define UART_FR_RXFE (1U << 4) + #define UART_TXFIFO_DEPTH 16U + + enum AppRecords { // application-specific trace records + PHILO_STAT = QP::QS_USER, + COMMAND_STAT + }; +#endif + +extern "C" { + +// ISRs used in this project ================================================= +#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 UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0) { // while RX FIFO NOT empty + uint32_t b = UART0->DR; + QP::QS::rxPut(b); + } +} +#else +void UART0_IRQHandler(void) {} +#endif + + +} // extern "C" + +// BSP functions ============================================================= +void BSP::init(void) { + // NOTE: SystemInit() has been 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)); + + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5); // enable Run mode for GPIOF + + // configure the LEDs and push buttons + GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE); // set as output + GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); // digital enable + GPIOF->DATA_Bits[LED_RED] = 0U; // turn the LED off + GPIOF->DATA_Bits[LED_GREEN] = 0U; // turn the LED off + GPIOF->DATA_Bits[LED_BLUE] = 0U; // turn the LED off + + // configure the Buttons + GPIOF->DIR &= ~(BTN_SW1 | BTN_SW2); // set direction: input + ROM_GPIOPadConfigSet(GPIOF_BASE, (BTN_SW1 | BTN_SW2), + GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); + + // seed the random number generator + BSP::randomSeed(1234U); + + if (!QS_INIT((void *)0)) { // initialize the QS software tracing + Q_ERROR(); + } + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(COMMAND_STAT); +} +//............................................................................ +void BSP::displayPhilStat(uint8_t n, char const *stat) { + GPIOF->DATA_Bits[LED_RED] = ((stat[0] == 'h') ? 0xFFU : 0U); + GPIOF->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? 0xFFU : 0U); + + QS_BEGIN(PHILO_STAT, AO_Philo[n]) // application-specific record begin + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP::displayPaused(uint8_t paused) { + GPIOF->DATA_Bits[LED_RED] = ((paused != 0U) ? LED_RED : 0U); +} +//............................................................................ +uint32_t BSP::random(void) { // a very cheap pseudo-random-number generator + // Some flating point code is to exercise the VFP... + 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) + */ + uint32_t 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; +} + +} // namespace DPP + + +// namespace QP ************************************************************** +namespace QP { + +static TX_TIMER l_tick_timer; // ThreadX timer to call QF::tickX_() + +#ifdef Q_SPY + // ThreadX thread and thread function for QS output, see NOTE1 + static TX_THREAD l_qs_output_thread; + static void qs_thread_function(ULONG thread_input); + static ULONG qs_thread_stkSto[64]; +#endif + +// QF callbacks ============================================================== +void QF::onStartup(void) { + // + // NOTE: + // This application uses the ThreadX timer to periodically call + // the QF_tickX_(0) function. Here, only the clock tick rate of 0 + // is used, but other timers can be used to call QF_tickX_() for + // other clock tick rates, if needed. + // + // The choice of a ThreadX timer is not the only option. Applications + // might choose to call QF_tickX_() directly from timer interrupts + // or from active object(s). + // + Q_ALLEGE(tx_timer_create(&l_tick_timer, // ThreadX timer object + const_cast("QF_TICK"), // name of the timer + (VOID (*)(ULONG))&QP::QF::tickX_, // expiration fun + 0U, // expiration function input (tick rate) + 1U, // initial ticks + 1U, // reschedule ticks + TX_AUTO_ACTIVATE) // automatically activate timer + == TX_SUCCESS); + +#ifdef Q_SPY + NVIC_EnableIRQ(UART0_IRQn); // UART0 interrupt used for QS-RX + + // start a ThreadX timer to perform QS output. See NOTE1... + Q_ALLEGE(tx_thread_create(&l_qs_output_thread, // thread control block + const_cast("QS_TX"), // thread name + &qs_thread_function, // thread function + 0LU, // thread input (unsued) + qs_thread_stkSto, // stack start + sizeof(qs_thread_stkSto), // stack size in bytes + TX_MAX_PRIORITIES - 1U, // ThreadX priority (lowest possible) + TX_MAX_PRIORITIES - 1U, // preemption threshold disabled + TX_NO_TIME_SLICE, + TX_AUTO_START) + == TX_SUCCESS); +#endif // Q_SPY +} +//............................................................................ +void QF::onCleanup(void) { +} + +//............................................................................ +extern "C" void Q_onAssert(char const *module, int loc) { + // + // NOTE: add here your application-specific error handling + // + (void)module; + (void)loc; + QS_ASSERTION(module, loc, static_cast(10000U)); + +#ifndef NDEBUG + /* for debugging, hang on in an endless loop toggling the RED LED... */ + while (GPIOF->DATA_Bits[BTN_SW1] != 0) { + GPIOF->DATA = LED_RED; + GPIOF->DATA = 0U; + } +#endif + + NVIC_SystemReset(); +} + +// QS callbacks ============================================================== +#ifdef Q_SPY + +//............................................................................ +static void qs_thread_function(ULONG /*thread_input*/) { // see NOTE1 + for (;;) { + QS::rxParse(); // parse all the received bytes + + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept + uint8_t const *block; + QF_CRIT_STAT_TYPE intStat; + + QF_CRIT_ENTRY(intStat); + block = QS::getBlock(&fifo); // try to get next block to transmit + QF_CRIT_EXIT(intStat); + + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO + } + } + + // no blocking in this thread; see NOTE1 + } +} + +//............................................................................ +bool QS::onStartup(void const *arg) { + static uint8_t qsTxBuf[2*1024]; // buffer for QS transmit channel + static uint8_t qsRxBuf[100]; // buffer for QS receive channel + uint32_t tmp; + + initBuf(qsTxBuf, sizeof(qsTxBuf)); + rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0); // enable Run mode for GPIOA + + // configure UART0 pins for UART operation + tmp = (1U << 0) | (1U << 1); + GPIOA->DIR &= ~tmp; + GPIOA->SLR &= ~tmp; + GPIOA->ODR &= ~tmp; + GPIOA->PUR &= ~tmp; + GPIOA->PDR &= ~tmp; + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins + GPIOA->PCTL &= ~0x00U; + GPIOA->PCTL |= 0x11U; + + // configure the UART for the desired baud rate, 8-N-1 operation + tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; + UART0->IBRD = tmp / 64U; + UART0->FBRD = tmp % 64U; + UART0->LCRH = (0x3U << 5); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4); // enable FIFOs + UART0->CTL = (1U << 0) // UART enable + | (1U << 8) // UART TX enable + | (1U << 9); // UART RX enable + + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4) | (1U << 6); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() + + DPP::QS_tickPeriod_ = SystemCoreClock / DPP::BSP::TICKS_PER_SEC; + DPP::QS_tickTime_ = DPP::QS_tickPeriod_; // to start the timestamp at zero + + // setup the QS filters... + QS_FILTER_ON(QS_ALL_RECORDS); + QS_FILTER_OFF(QS_QF_TICK); + + return true; // return success +} +//............................................................................ +void QS::onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS::onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? + return DPP::QS_tickTime_ - static_cast(SysTick->VAL); + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return DPP::QS_tickTime_ + DPP::QS_tickPeriod_ + - static_cast(SysTick->VAL); + } +} +//............................................................................ +void QS::onFlush(void) { + uint16_t fifo = UART_TXFIFO_DEPTH; // Tx FIFO depth + uint8_t const *block; + while ((block = getBlock(&fifo)) != static_cast(0)) { + // busy-wait until TX FIFO empty + while ((UART0->FR & UART_FR_TXFE) == 0U) { + } + + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the TX FIFO + } + fifo = UART_TXFIFO_DEPTH; // re-load the Tx FIFO depth + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS::onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +extern "C" void assert_failed(char const *module, int loc); // prototype +extern void QS_target_info_(uint8_t isReset); // prototype + +void QS::onCommand(uint8_t cmdId, uint32_t param1, + uint32_t param2, uint32_t param3) +{ + (void)cmdId; + (void)param1; + (void)param2; + (void)param3; + + // application-specific record + QS_BEGIN(DPP::COMMAND_STAT, static_cast(0)) + QS_U8(2, cmdId); + QS_U32(8, param1); + QS_U32(8, param2); + QS_U32(8, param3); + QS_END() + + switch (cmdId) { + case 1: { + QS_target_info_(static_cast(0xFF)); // test a reset + break; + } + case 10: { + assert_failed("QS_onCommand", 10); // for testing assertions + break; + } + } +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +} // namespace QP + +//**************************************************************************** +// NOTE1: +// This application uses the ThreadX thread of the lowest priority to perform +// the QS data output to the host. This is not the only choice available, and +// other applications might choose to peform the QS output some other way. +// +// The lowest-priority thread does not block, so in effect, it becomes the +// idle loop. This presents no problems to ThreadX - its idle task in the +// scheduler does not need to run. +// + diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h new file mode 100644 index 00000000..17165127 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h @@ -0,0 +1,61 @@ +//**************************************************************************** +// 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 . +// +// Contact information: +// https://state-machine.com +// mailto:info@state-machine.com +//**************************************************************************** +#ifndef bsp_h +#define bsp_h + +namespace DPP { + +class BSP { +public: + enum { TICKS_PER_SEC = 100 }; + + static void init(void); + static void displayPaused(uint8_t const paused); + static void displayPhilStat(uint8_t const n, char_t const *stat); + static void terminate(int16_t const result); + + static void randomSeed(uint32_t const seed); // random seed + static uint32_t random(void); // pseudo-random generator + + // for testing... + static void wait4SW1(void); + static void ledOn(void); + static void ledOff(void); +}; + +extern QP::QActive *the_Ticker0; + +} // namespace DPP + +#endif // bsp_h diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h new file mode 100644 index 00000000..fef51edd --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h @@ -0,0 +1,86 @@ +//$file${.::dpp.h} ########################################################### +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 4.3.0 (https://www.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. +// +//$endhead${.::dpp.h} ######################################################## +#ifndef dpp_h +#define dpp_h + +namespace DPP { + +enum DPPSignals { + EAT_SIG = QP::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 the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + HUNGRY_SIG, // posted direclty to Table from hungry Philo + MAX_SIG // the last signal +}; + +} // namespace DPP + +//$declare${Events::TableEvt} ################################################ +namespace DPP { + +//${Events::TableEvt} ........................................................ +class TableEvt : public QP::QEvt { +public: + uint8_t philoNum; +}; + +} // namespace DPP +//$enddecl${Events::TableEvt} ################################################ + +// number of philosophers +#define N_PHILO ((uint8_t)5) + +//$declare${AOs::AO_Philo[N_PHILO]} ########################################## +namespace DPP { + +extern QP::QActive * const AO_Philo[N_PHILO]; + +} // namespace DPP +//$enddecl${AOs::AO_Philo[N_PHILO]} ########################################## + +//$declare${AOs::AO_Table} ################################################### +namespace DPP { + +extern QP::QActive * const AO_Table; + +} // namespace DPP +//$enddecl${AOs::AO_Table} ################################################### + +#ifdef qxk_h +//$declare${AOs::XT_Test1} ################################################### +namespace DPP { + +extern QP::QXThread * const XT_Test1; + +} // namespace DPP +//$enddecl${AOs::XT_Test1} ################################################### +//$declare${AOs::XT_Test2} ################################################### +namespace DPP { + +extern QP::QXThread * const XT_Test2; + +} // namespace DPP +//$enddecl${AOs::XT_Test2} ################################################### +#endif // qxk_h + +#endif // dpp_h \ No newline at end of file diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm new file mode 100644 index 00000000..154063a6 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm @@ -0,0 +1,498 @@ + + + Dining Philosopher Problem example with MSM state machines + + + + + + + + + + + + + + + + + + + : QActive(Q_STATE_CAST(&Philo::initial)), + m_timeEvt(this, TIMEOUT_SIG, 0U) + + + + + + static bool registered = false; // starts off with 0, per C-standard +(void)e; // suppress the compiler warning about unused parameter + +me->subscribe(EAT_SIG); +me->subscribe(TEST_SIG); + +if (!registered) { + registered = true; + + QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); + + QS_FUN_DICTIONARY(&initial); + QS_FUN_DICTIONARY(&thinking); + QS_FUN_DICTIONARY(&hungry); + QS_FUN_DICTIONARY(&eating); +} + +QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos +QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos + + + + + + + me->m_timeEvt.armX(think_time(), 0U); + (void)me->m_timeEvt.disarm(); + + + + + + + + + /* EAT or DONE must be for other Philos than this one */ +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + + + + + + + + + + + + + + + + + + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoNum = PHILO_ID(me); +AO_Table->POST(pe, me); + + + + + Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) + + + + + + + + + + + /* DONE must be for other Philos than this one */ +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + + + + + + + + + + + me->m_timeEvt.armX(eat_time(), 0U); + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoNum = PHILO_ID(me); +QP::QF::PUBLISH(pe, me); +(void)me->m_timeEvt.disarm(); + + + + + + + + + /* EAT or DONE must be for other Philos than this one */ +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + + + + + + + + + + + + + + + + + + + + + : QActive(Q_STATE_CAST(&Table::initial)) + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + m_fork[n] = FREE; + m_isHungry[n] = false; +} + + + + + + (void)e; // suppress the compiler warning about unused parameter + +me->subscribe(DONE_SIG); +me->subscribe(PAUSE_SIG); +me->subscribe(SERVE_SIG); +me->subscribe(TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->m_fork[n] = FREE; + me->m_isHungry[n] = false; + BSP::displayPhilStat(n, THINKING); +} + +// global signals... +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +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); + +// signals just for this AO... +QS_SIG_DICTIONARY(HUNGRY_SIG, me); + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... + if (me->m_isHungry[n] + && (me->m_fork[LEFT(n)] == FREE) + && (me->m_fork[n] == FREE)) + { + me->m_fork[LEFT(n)] = USED; + me->m_fork[n] = USED; + TableEvt *te = Q_NEW(TableEvt, EAT_SIG); + te->philoNum = n; + QP::QF::PUBLISH(te, me); + me->m_isHungry[n] = false; + BSP::displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); + +BSP::displayPhilStat(n, HUNGRY); +uint8_t m = LEFT(n); + + + (me->m_fork[m] == FREE) && (me->m_fork[n] == FREE) + me->m_fork[m] = USED; +me->m_fork[n] = USED; +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoNum = n; +QP::QF::PUBLISH(pe, me); +BSP::displayPhilStat(n, EATING); + + + + + + + else + me->m_isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); + +BSP::displayPhilStat(n, THINKING); +uint8_t m = LEFT(n); +// both forks of Phil[n] must be used +Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); + +me->m_fork[m] = FREE; +me->m_fork[n] = FREE; +m = RIGHT(n); // check the right neighbor + +if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) { + me->m_fork[n] = USED; + me->m_fork[m] = USED; + me->m_isHungry[m] = false; + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoNum = m; + QP::QF::PUBLISH(pe, me); + BSP::displayPhilStat(m, EATING); +} +m = LEFT(n); // check the left neighbor +n = LEFT(m); // left fork of the left neighbor +if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { + me->m_fork[m] = USED; + me->m_fork[n] = USED; + me->m_isHungry[m] = false; + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoNum = m; + QP::QF::PUBLISH(pe, me); + BSP::displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP::displayPaused(1U); + BSP::displayPaused(0U); + + + + + + + + + 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->m_isHungry[n])); +me->m_isHungry[n] = true; +BSP::displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); + +BSP::displayPhilStat(n, THINKING); +uint8_t m = LEFT(n); +/* both forks of Phil[n] must be used */ +Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); + +me->m_fork[m] = FREE; +me->m_fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + + + + + + + + + #ifndef dpp_h +#define dpp_h + +namespace DPP { + +enum DPPSignals { + EAT_SIG = QP::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 the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + HUNGRY_SIG, // posted direclty to Table from hungry Philo + MAX_SIG // the last signal +}; + +} // namespace DPP + +$declare(Events::TableEvt) + +// number of philosophers +#define N_PHILO ((uint8_t)5) + +$declare(AOs::AO_Philo[N_PHILO]) + +$declare(AOs::AO_Table) + +#ifdef qxk_h +$declare(AOs::XT_Test1) +$declare(AOs::XT_Test2) +#endif // qxk_h + +#endif // dpp_h + + + + #include "qpcpp.h" +#include "dpp.h" +#include "bsp.h" + +Q_DEFINE_THIS_FILE + +// Active object class ------------------------------------------------------- +$declare(AOs::Philo) + +namespace DPP { + +// Local objects ------------------------------------------------------------- +static Philo l_philo[N_PHILO]; // storage for all Philos + +// helper function to provide a randomized think time for Philos +inline QP::QTimeEvtCtr think_time() { + return static_cast<QP::QTimeEvtCtr>((BSP::random() % BSP::TICKS_PER_SEC) + + (BSP::TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +inline QP::QTimeEvtCtr eat_time() { + return static_cast<QP::QTimeEvtCtr>((BSP::random() % BSP::TICKS_PER_SEC) + + BSP::TICKS_PER_SEC); +} + +// helper function to provide the ID of Philo "me" +inline uint8_t PHILO_ID(Philo const * const me) { + return static_cast<uint8_t>(me - l_philo); +} + +enum InternalSignals { // internal signals + TIMEOUT_SIG = MAX_SIG +}; + +// Global objects ------------------------------------------------------------ +QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO + &l_philo[0], + &l_philo[1], + &l_philo[2], + &l_philo[3], + &l_philo[4] +}; + +} // namespace DPP + +// Philo definition ---------------------------------------------------------- +$define(AOs::Philo) + + + + #include "qpcpp.h" +#include "dpp.h" +#include "bsp.h" + +Q_DEFINE_THIS_FILE + +// Active object class ------------------------------------------------------- +$declare(AOs::Table) + +namespace DPP { + +// helper function to provide the RIGHT neighbour of a Philo[n] +inline uint8_t RIGHT(uint8_t const n) { + return static_cast<uint8_t>((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbour of a Philo[n] +inline uint8_t LEFT(uint8_t const n) { + return static_cast<uint8_t>((n + 1U) % N_PHILO); +} + +static uint8_t const FREE = static_cast<uint8_t>(0); +static uint8_t const USED = static_cast<uint8_t>(1); + +static char_t const * const THINKING = &"thinking"[0]; +static char_t const * const HUNGRY = &"hungry "[0]; +static char_t const * const EATING = &"eating "[0]; + +// Local objects ------------------------------------------------------------- +static Table l_table; // the single instance of the Table active object + +// Global-scope objects ------------------------------------------------------ +QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer + +} // namespace DPP + +//............................................................................ +$define(AOs::Table) + + + diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd new file mode 100644 index 00000000..2738edc9 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd @@ -0,0 +1,4213 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 28 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 28 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 28 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp new file mode 100644 index 00000000..db97c552 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp @@ -0,0 +1,3218 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 20 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 30 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 20 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 20 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.cpp + + + $PROJ_DIR$\..\bsp.h + + + $PROJ_DIR$\..\dpp.h + + + $PROJ_DIR$\..\main.cpp + + + $PROJ_DIR$\..\philo.cpp + + + $PROJ_DIR$\..\..\..\..\..\include\qstamp.cpp + + + $PROJ_DIR$\..\table.cpp + + + + ek-tm4c123gxl + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.cpp + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\threadx\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\threadx\qf_port.cpp + + + $PROJ_DIR$\..\..\..\..\..\ports\threadx\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\threadx\qs_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.cpp + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.cpp + + + + ThreadX + + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tm4c123xx_iar\readme_threadx.txt + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tm4c123xx_iar\tx.a + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx_api.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tm4c123xx_iar\tx_port.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx_trace.h + + + diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.eww b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.eww new file mode 100644 index 00000000..7a61d220 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp.ewp + + + + + diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf new file mode 100644 index 00000000..1ef57ccc --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf @@ -0,0 +1,29 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 1024; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place at start of RAM_region {block CSTACK }; +place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.cpp b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.cpp new file mode 100644 index 00000000..4d384f29 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.cpp @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////////// +// Product: DPP example for ThreadX +// Last updated for version 6.3.7 +// Last updated on 2018-12-17 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005-2018 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 . +// +// Contact information: +// https://www.state-machine.com +// mailto:info@state-machine.com +////////////////////////////////////////////////////////////////////////////// +#include "qpcpp.h" +#include "dpp.h" +#include "bsp.h" + +// Local-scope objects ------------------------------------------------------- +static QP::QEvt const *l_tableQueueSto[N_PHILO]; +static QP::QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; +static QP::QSubscrList l_subscrSto[DPP::MAX_PUB_SIG]; + +static union SmallEvents { + void *e0; // minimum event size + uint8_t e1[sizeof(DPP::TableEvt)]; + // ... other event types to go into this pool +} l_smlPoolSto[2*N_PHILO + 10]; // storage for the small event pool + +static ULONG l_philoStk[N_PHILO][256]; // stacks for the Philosophers +static ULONG l_tableStk[256]; // stack for the Table + +//............................................................................ +int main() { + DPP::BSP::init(); // initialize the Board Support Package + tx_kernel_enter(); // transfet control to the ThreadX RTOS + return 0; // tx_kernel_enter() does not return +} +//............................................................................ +void tx_application_define(void * /*first_unused_memory*/) { + // initialize the framework and the underlying RT kernel... + QP::QF::init(); + + // init publish-subscribe + QP::QF::psInit(l_subscrSto, Q_DIM(l_subscrSto)); + + // initialize event pools... + QP::QF::poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), + sizeof(l_smlPoolSto[0])); + + QS_OBJ_DICTIONARY(l_smlPoolSto); + QS_OBJ_DICTIONARY(l_tableQueueSto); + QS_OBJ_DICTIONARY(l_philoQueueSto[0]); + QS_OBJ_DICTIONARY(l_philoQueueSto[1]); + QS_OBJ_DICTIONARY(l_philoQueueSto[2]); + QS_OBJ_DICTIONARY(l_philoQueueSto[3]); + QS_OBJ_DICTIONARY(l_philoQueueSto[4]); + + // start the active objects... + for (uint8_t n = 0; n < N_PHILO; ++n) { + DPP::AO_Philo[n]->start( + static_cast(n + 1), + l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), + l_philoStk[n], sizeof(l_philoStk[n])); + } + DPP::AO_Table->start( + static_cast(N_PHILO + 1), + l_tableQueueSto, Q_DIM(l_tableQueueSto), + l_tableStk, sizeof(l_tableStk)); + + (void)QP::QF::run(); // run the QF application +} diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.cpp b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.cpp new file mode 100644 index 00000000..ec939d39 --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.cpp @@ -0,0 +1,246 @@ +//$file${.::philo.cpp} ####################################################### +// +// Model: dpp.qm +// File: ${.::philo.cpp} +// +// This code has been generated by QM 4.3.0 (https://www.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. +// +//$endhead${.::philo.cpp} #################################################### +#include "qpcpp.h" +#include "dpp.h" +#include "bsp.h" + +Q_DEFINE_THIS_FILE + +// Active object class ------------------------------------------------------- +//$declare${AOs::Philo} ###################################################### +namespace DPP { + +//${AOs::Philo} .............................................................. +class Philo : public QP::QActive { +private: + QP::QTimeEvt m_timeEvt; + +public: + Philo(); + +protected: + static QP::QState initial(Philo * const me, QP::QEvt const * const e); + static QP::QState thinking(Philo * const me, QP::QEvt const * const e); + static QP::QState hungry(Philo * const me, QP::QEvt const * const e); + static QP::QState eating(Philo * const me, QP::QEvt const * const e); +}; + +} // namespace DPP +//$enddecl${AOs::Philo} ###################################################### + +namespace DPP { + +// Local objects ------------------------------------------------------------- +static Philo l_philo[N_PHILO]; // storage for all Philos + +// helper function to provide a randomized think time for Philos +inline QP::QTimeEvtCtr think_time() { + return static_cast((BSP::random() % BSP::TICKS_PER_SEC) + + (BSP::TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +inline QP::QTimeEvtCtr eat_time() { + return static_cast((BSP::random() % BSP::TICKS_PER_SEC) + + BSP::TICKS_PER_SEC); +} + +// helper function to provide the ID of Philo "me" +inline uint8_t PHILO_ID(Philo const * const me) { + return static_cast(me - l_philo); +} + +enum InternalSignals { // internal signals + TIMEOUT_SIG = MAX_SIG +}; + +// Global objects ------------------------------------------------------------ +QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO + &l_philo[0], + &l_philo[1], + &l_philo[2], + &l_philo[3], + &l_philo[4] +}; + +} // namespace DPP + +// Philo definition ---------------------------------------------------------- +// Check for the minimum required QP version +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpcpp version 6.3.0 or higher required +#endif + +//$define${AOs::Philo} ####################################################### +namespace DPP { + +//${AOs::Philo} .............................................................. +//${AOs::Philo::Philo} ....................................................... +Philo::Philo() + : QActive(Q_STATE_CAST(&Philo::initial)), + m_timeEvt(this, TIMEOUT_SIG, 0U) +{} +//${AOs::Philo::SM} .......................................................... +QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) { + //${AOs::Philo::SM::initial} + static bool registered = false; // starts off with 0, per C-standard + (void)e; // suppress the compiler warning about unused parameter + + me->subscribe(EAT_SIG); + me->subscribe(TEST_SIG); + + if (!registered) { + registered = true; + + QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); + + QS_FUN_DICTIONARY(&initial); + QS_FUN_DICTIONARY(&thinking); + QS_FUN_DICTIONARY(&hungry); + QS_FUN_DICTIONARY(&eating); + } + + QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos + QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos + return Q_TRAN(&thinking); +} +//${AOs::Philo::SM::thinking} ................................................ +QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) { + QP::QState status_; + switch (e->sig) { + //${AOs::Philo::SM::thinking} + case Q_ENTRY_SIG: { + me->m_timeEvt.armX(think_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)me->m_timeEvt.disarm(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&hungry); + break; + } + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + /* EAT or DONE must be for other Philos than this one */ + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&top); + break; + } + } + return status_; +} +//${AOs::Philo::SM::hungry} .................................................. +QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) { + QP::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); + AO_Table->POST(pe, 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(&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(&top); + break; + } + } + return status_; +} +//${AOs::Philo::SM::eating} .................................................. +QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) { + QP::QState status_; + switch (e->sig) { + //${AOs::Philo::SM::eating} + case Q_ENTRY_SIG: { + me->m_timeEvt.armX(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); + QP::QF::PUBLISH(pe, me); + (void)me->m_timeEvt.disarm(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&thinking); + break; + } + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + /* EAT or DONE must be for other Philos than this one */ + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&top); + break; + } + } + return status_; +} + +} // namespace DPP +//$enddef${AOs::Philo} ####################################################### diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.cpp b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.cpp new file mode 100644 index 00000000..5e37b43c --- /dev/null +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.cpp @@ -0,0 +1,308 @@ +//$file${.::table.cpp} ####################################################### +// +// Model: dpp.qm +// File: ${.::table.cpp} +// +// This code has been generated by QM 4.3.0 (https://www.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. +// +//$endhead${.::table.cpp} #################################################### +#include "qpcpp.h" +#include "dpp.h" +#include "bsp.h" + +Q_DEFINE_THIS_FILE + +// Active object class ------------------------------------------------------- +//$declare${AOs::Table} ###################################################### +namespace DPP { + +//${AOs::Table} .............................................................. +class Table : public QP::QActive { +private: + uint8_t m_fork[N_PHILO]; + bool m_isHungry[N_PHILO]; + +public: + Table(); + +protected: + static QP::QState initial(Table * const me, QP::QEvt const * const e); + static QP::QState active(Table * const me, QP::QEvt const * const e); + static QP::QState serving(Table * const me, QP::QEvt const * const e); + static QP::QState paused(Table * const me, QP::QEvt const * const e); +}; + +} // namespace DPP +//$enddecl${AOs::Table} ###################################################### + +namespace DPP { + +// helper function to provide the RIGHT neighbour of a Philo[n] +inline uint8_t RIGHT(uint8_t const n) { + return static_cast((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbour of a Philo[n] +inline uint8_t LEFT(uint8_t const n) { + return static_cast((n + 1U) % N_PHILO); +} + +static uint8_t const FREE = static_cast(0); +static uint8_t const USED = static_cast(1); + +static char_t const * const THINKING = &"thinking"[0]; +static char_t const * const HUNGRY = &"hungry "[0]; +static char_t const * const EATING = &"eating "[0]; + +// Local objects ------------------------------------------------------------- +static Table l_table; // the single instance of the Table active object + +// Global-scope objects ------------------------------------------------------ +QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer + +} // namespace DPP + +//............................................................................ +// Check for the minimum required QP version +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpcpp version 6.3.0 or higher required +#endif + +//$define${AOs::Table} ####################################################### +namespace DPP { + +//${AOs::Table} .............................................................. +//${AOs::Table::Table} ....................................................... +Table::Table() + : QActive(Q_STATE_CAST(&Table::initial)) +{ + for (uint8_t n = 0U; n < N_PHILO; ++n) { + m_fork[n] = FREE; + m_isHungry[n] = false; + } +} +//${AOs::Table::SM} .......................................................... +QP::QState Table::initial(Table * const me, QP::QEvt const * const e) { + //${AOs::Table::SM::initial} + (void)e; // suppress the compiler warning about unused parameter + + me->subscribe(DONE_SIG); + me->subscribe(PAUSE_SIG); + me->subscribe(SERVE_SIG); + me->subscribe(TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->m_fork[n] = FREE; + me->m_isHungry[n] = false; + BSP::displayPhilStat(n, THINKING); + } + + // global signals... + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + 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); + + // signals just for this AO... + QS_SIG_DICTIONARY(HUNGRY_SIG, me); + + QS_FUN_DICTIONARY(&active); + QS_FUN_DICTIONARY(&serving); + QS_FUN_DICTIONARY(&paused); + + return Q_TRAN(&serving); +} +//${AOs::Table::SM::active} .................................................. +QP::QState Table::active(Table * const me, QP::QEvt const * const e) { + QP::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(&top); + break; + } + } + return status_; +} +//${AOs::Table::SM::active::serving} ......................................... +QP::QState Table::serving(Table * const me, QP::QEvt const * const e) { + QP::QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::serving} + case Q_ENTRY_SIG: { + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... + if (me->m_isHungry[n] + && (me->m_fork[LEFT(n)] == FREE) + && (me->m_fork[n] == FREE)) + { + me->m_fork[LEFT(n)] = USED; + me->m_fork[n] = USED; + TableEvt *te = Q_NEW(TableEvt, EAT_SIG); + te->philoNum = n; + QP::QF::PUBLISH(te, me); + me->m_isHungry[n] = false; + BSP::displayPhilStat(n, EATING); + } + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); + + BSP::displayPhilStat(n, HUNGRY); + uint8_t m = LEFT(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) { + me->m_fork[m] = USED; + me->m_fork[n] = USED; + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoNum = n; + QP::QF::PUBLISH(pe, me); + BSP::displayPhilStat(n, EATING); + status_ = Q_HANDLED(); + } + //${AOs::Table::SM::active::serving::HUNGRY::[else]} + else { + me->m_isHungry[n] = true; + status_ = Q_HANDLED(); + } + break; + } + //${AOs::Table::SM::active::serving::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); + + BSP::displayPhilStat(n, THINKING); + uint8_t m = LEFT(n); + // both forks of Phil[n] must be used + Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); + + me->m_fork[m] = FREE; + me->m_fork[n] = FREE; + m = RIGHT(n); // check the right neighbor + + if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) { + me->m_fork[n] = USED; + me->m_fork[m] = USED; + me->m_isHungry[m] = false; + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoNum = m; + QP::QF::PUBLISH(pe, me); + BSP::displayPhilStat(m, EATING); + } + m = LEFT(n); // check the left neighbor + n = LEFT(m); // left fork of the left neighbor + if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { + me->m_fork[m] = USED; + me->m_fork[n] = USED; + me->m_isHungry[m] = false; + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoNum = m; + QP::QF::PUBLISH(pe, 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(&paused); + break; + } + default: { + status_ = Q_SUPER(&active); + break; + } + } + return status_; +} +//${AOs::Table::SM::active::paused} .......................................... +QP::QState Table::paused(Table * const me, QP::QEvt const * const e) { + QP::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(&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->m_isHungry[n])); + me->m_isHungry[n] = true; + BSP::displayPhilStat(n, HUNGRY); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); + + BSP::displayPhilStat(n, THINKING); + uint8_t m = LEFT(n); + /* both forks of Phil[n] must be used */ + Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); + + me->m_fork[m] = FREE; + me->m_fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&active); + break; + } + } + return status_; +} + +} // namespace DPP +//$enddef${AOs::Table} ####################################################### diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.cpp b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.cpp index ae83ab9a..f2007886 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.cpp +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.cpp @@ -1,13 +1,13 @@ //**************************************************************************** // Product: DPP example, STM32F4-Discovery board, ThreadX kernel -// Last updated for version 5.9.0 -// Last updated on 2017-05-09 +// Last Updated for Version: 6.3.7 +// Date of the Last Update: 2018-12-17 // -// Q u a n t u m L e a P s -// --------------------------- -// innovating embedded systems +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// Copyright (C) Quantum Leaps, LLC. All rights reserved. +// Copyright (C) 2005-2018 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 @@ -28,7 +28,7 @@ // along with this program. If not, see . // // Contact information: -// https://state-machine.com +// https://www.state-machine.com // mailto:info@state-machine.com //**************************************************************************** #include "qpcpp.h" @@ -325,17 +325,8 @@ bool QS::onStartup(void const *arg) { DPP::QS_tickTime_ = DPP::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(DPP::PHILO_STAT); + QS_FILTER_ON(QS_ALL_RECORDS); + QS_FILTER_OFF(QS_QF_TICK); return true; // return success } diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h index 2825d2c2..17165127 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h @@ -1,7 +1,7 @@ //**************************************************************************** // Product: DPP example -// Last Updated for Version: 5.6.0 -// Date of the Last Update: 2015-12-28 +// 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 // --------------------------- @@ -46,7 +46,7 @@ public: static void terminate(int16_t const result); static void randomSeed(uint32_t const seed); // random seed - static uint32_t random(void); // pseudo-random generator + static uint32_t random(void); // pseudo-random generator // for testing... static void wait4SW1(void); @@ -54,6 +54,8 @@ public: static void ledOff(void); }; +extern QP::QActive *the_Ticker0; + } // namespace DPP #endif // bsp_h diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h index 46bcf10b..fef51edd 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h @@ -3,7 +3,7 @@ // Model: dpp.qm // File: ${.::dpp.h} // -// This code has been generated by QM tool (https://state-machine.com/qm). +// This code has been generated by QM 4.3.0 (https://www.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 @@ -48,8 +48,7 @@ public: //$enddecl${Events::TableEvt} ################################################ // number of philosophers -// NOTE: Only one Philo, because of the ThreadX demo library limits -#define N_PHILO (static_cast(1)) +#define N_PHILO ((uint8_t)5) //$declare${AOs::AO_Philo[N_PHILO]} ########################################## namespace DPP { @@ -84,4 +83,4 @@ extern QP::QXThread * const XT_Test2; //$enddecl${AOs::XT_Test2} ################################################### #endif // qxk_h -#endif // dpp_h +#endif // dpp_h \ No newline at end of file diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm index 3588eef6..154063a6 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm @@ -1,59 +1,69 @@ - + Dining Philosopher Problem example with MSM state machines + + + + + + + + : QActive(Q_STATE_CAST(&Philo::initial)), m_timeEvt(this, TIMEOUT_SIG, 0U) + + static bool registered = false; // starts off with 0, per C-standard (void)e; // suppress the compiler warning about unused parameter + +me->subscribe(EAT_SIG); +me->subscribe(TEST_SIG); + if (!registered) { registered = true; - QS_OBJ_DICTIONARY(&l_philo[0]); QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[1]); - //QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[2]); - //QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[3]); - //QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[4]); - //QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); - QS_FUN_DICTIONARY(&Philo::initial); - QS_FUN_DICTIONARY(&Philo::thinking); - QS_FUN_DICTIONARY(&Philo::hungry); - QS_FUN_DICTIONARY(&Philo::eating); + QS_FUN_DICTIONARY(&initial); + QS_FUN_DICTIONARY(&thinking); + QS_FUN_DICTIONARY(&hungry); + QS_FUN_DICTIONARY(&eating); } -QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos -me->subscribe(EAT_SIG); -me->subscribe(TEST_SIG); +QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos +QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos + me->m_timeEvt.armX(think_time(), 0U); (void)me->m_timeEvt.disarm(); + - + + /* EAT or DONE must be for other Philos than this one */ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); @@ -61,6 +71,7 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + @@ -71,11 +82,14 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); pe->philoNum = PHILO_ID(me); AO_Table->POST(pe, me); + + Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) @@ -86,6 +100,7 @@ AO_Table->POST(pe, me); + /* DONE must be for other Philos than this one */ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); @@ -97,17 +112,20 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + me->m_timeEvt.armX(eat_time(), 0U); TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); pe->philoNum = PHILO_ID(me); QP::QF::PUBLISH(pe, me); (void)me->m_timeEvt.disarm(); + + /* EAT or DONE must be for other Philos than this one */ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); @@ -123,9 +141,13 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + + + + : QActive(Q_STATE_CAST(&Table::initial)) @@ -134,25 +156,12 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { m_isHungry[n] = false; } - + + + (void)e; // suppress the compiler warning about unused parameter -QS_OBJ_DICTIONARY(&l_table); -QS_FUN_DICTIONARY(&QP::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 - me->subscribe(DONE_SIG); me->subscribe(PAUSE_SIG); me->subscribe(SERVE_SIG); @@ -162,23 +171,37 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { me->m_fork[n] = FREE; me->m_isHungry[n] = false; BSP::displayPhilStat(n, THINKING); -} +} + +// global signals... +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +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); + +// signals just for this AO... +QS_SIG_DICTIONARY(HUNGRY_SIG, me); + + + Q_ERROR(); + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if (me->m_isHungry[n] @@ -194,6 +217,7 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { BSP::displayPhilStat(n, EATING); } } + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry @@ -201,6 +225,7 @@ Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP::displayPhilStat(n, HUNGRY); uint8_t m = LEFT(n); + (me->m_fork[m] == FREE) && (me->m_fork[n] == FREE) me->m_fork[m] = USED; @@ -213,6 +238,7 @@ BSP::displayPhilStat(n, EATING); + else me->m_isHungry[n] = true; @@ -224,6 +250,7 @@ BSP::displayPhilStat(n, EATING); + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry @@ -262,12 +289,14 @@ if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { + Q_ERROR(); + @@ -277,14 +306,17 @@ if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { + BSP::displayPaused(1U); BSP::displayPaused(0U); + + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // philo ID must be in range and he must be not hungry @@ -295,6 +327,7 @@ BSP::displayPhilStat(n, HUNGRY); + uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry @@ -321,12 +354,18 @@ me->m_fork[n] = FREE; + + + + + + #ifndef dpp_h #define dpp_h @@ -350,8 +389,7 @@ enum DPPSignals { $declare(Events::TableEvt) // number of philosophers -// NOTE: Only one Philo, because of the ThreadX demo library limits -#define N_PHILO (static_cast<uint8_t>(1)) +#define N_PHILO ((uint8_t)5) $declare(AOs::AO_Philo[N_PHILO]) @@ -362,9 +400,9 @@ $declare(AOs::XT_Test1) $declare(AOs::XT_Test2) #endif // qxk_h -#endif // dpp_h - +#endif // dpp_h + #include "qpcpp.h" #include "dpp.h" @@ -404,10 +442,10 @@ enum InternalSignals { // internal signals // Global objects ------------------------------------------------------------ QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO &l_philo[0], - //&l_philo[1], - //&l_philo[2], - //&l_philo[3], - //&l_philo[4] + &l_philo[1], + &l_philo[2], + &l_philo[3], + &l_philo[4] }; } // namespace DPP @@ -415,6 +453,7 @@ QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Phil // Philo definition ---------------------------------------------------------- $define(AOs::Philo) + #include "qpcpp.h" #include "dpp.h" diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd index b3d65a2a..c370daf2 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd @@ -2894,7 +2894,7 @@ - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.cpp @@ -3185,7 +3188,7 @@ stm32f4-discovery - $PROJ_DIR$\..\..\..\..\..\3rd_party\stm32f4-discovery\iar\startup_stm32f4xx_threadx.s + $PROJ_DIR$\..\..\..\..\..\3rd_party\stm32f4-discovery\iar\startup_stm32f4xx.s $PROJ_DIR$\..\..\..\..\..\3rd_party\stm32f4-discovery\stm32f4xx.h @@ -3212,19 +3215,19 @@ ThreadX - $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx.a + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\stm32f4xx_iar\readme_threadx.txt + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\stm32f4xx_iar\tx.a $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx_api.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx_initialize_low_level.s + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\stm32f4xx_iar\tx_port.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx_port.h + $PROJ_DIR$\..\..\..\..\..\3rd_party\threadx\tx_trace.h - - $PROJ_DIR$\ReadMe.txt - diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.cpp b/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.cpp index eb87088b..4d384f29 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.cpp +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.cpp @@ -1,13 +1,13 @@ ////////////////////////////////////////////////////////////////////////////// // Product: DPP example for ThreadX -// Last updated for version 6.2.0 -// Last updated on 2018-04-06 +// Last updated for version 6.3.7 +// Last updated on 2018-12-17 // -// Q u a n t u m L e a P s -// --------------------------- -// innovating embedded systems +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// Copyright (C) Quantum Leaps, LLC. All rights reserved. +// Copyright (C) 2005-2018 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 @@ -70,11 +70,10 @@ void tx_application_define(void * /*first_unused_memory*/) { QS_OBJ_DICTIONARY(l_smlPoolSto); QS_OBJ_DICTIONARY(l_tableQueueSto); QS_OBJ_DICTIONARY(l_philoQueueSto[0]); - //NOTE: can't use more active objects in the ThreadX demo! - //QS_OBJ_DICTIONARY(l_philoQueueSto[1]); - //QS_OBJ_DICTIONARY(l_philoQueueSto[2]); - //QS_OBJ_DICTIONARY(l_philoQueueSto[3]); - //QS_OBJ_DICTIONARY(l_philoQueueSto[4]); + QS_OBJ_DICTIONARY(l_philoQueueSto[1]); + QS_OBJ_DICTIONARY(l_philoQueueSto[2]); + QS_OBJ_DICTIONARY(l_philoQueueSto[3]); + QS_OBJ_DICTIONARY(l_philoQueueSto[4]); // start the active objects... for (uint8_t n = 0; n < N_PHILO; ++n) { diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.cpp b/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.cpp index f924c6bc..ec939d39 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.cpp +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.cpp @@ -3,7 +3,7 @@ // Model: dpp.qm // File: ${.::philo.cpp} // -// This code has been generated by QM tool (https://state-machine.com/qm). +// This code has been generated by QM 4.3.0 (https://www.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 @@ -73,20 +73,21 @@ enum InternalSignals { // internal signals // Global objects ------------------------------------------------------------ QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO &l_philo[0], - //&l_philo[1], - //&l_philo[2], - //&l_philo[3], - //&l_philo[4] + &l_philo[1], + &l_philo[2], + &l_philo[3], + &l_philo[4] }; } // namespace DPP // Philo definition ---------------------------------------------------------- -//$define${AOs::Philo} ####################################################### // Check for the minimum required QP version -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpcpp version 6.0.1 or higher required +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpcpp version 6.3.0 or higher required #endif + +//$define${AOs::Philo} ####################################################### namespace DPP { //${AOs::Philo} .............................................................. @@ -95,36 +96,32 @@ Philo::Philo() : QActive(Q_STATE_CAST(&Philo::initial)), m_timeEvt(this, TIMEOUT_SIG, 0U) {} - //${AOs::Philo::SM} .......................................................... QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) { //${AOs::Philo::SM::initial} static bool registered = false; // starts off with 0, per C-standard (void)e; // suppress the compiler warning about unused parameter - if (!registered) { - registered = true; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[1]); - //QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[2]); - //QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[3]); - //QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[4]); - //QS_OBJ_DICTIONARY(&l_philo[4].m_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 me->subscribe(EAT_SIG); me->subscribe(TEST_SIG); + + if (!registered) { + registered = true; + + QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt); + QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt); + + QS_FUN_DICTIONARY(&initial); + QS_FUN_DICTIONARY(&thinking); + QS_FUN_DICTIONARY(&hungry); + QS_FUN_DICTIONARY(&eating); + } + + QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos + QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos return Q_TRAN(&thinking); } //${AOs::Philo::SM::thinking} ................................................ diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.cpp b/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.cpp index 99eaaf5b..5e37b43c 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.cpp +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.cpp @@ -3,7 +3,7 @@ // Model: dpp.qm // File: ${.::table.cpp} // -// This code has been generated by QM tool (https://state-machine.com/qm). +// This code has been generated by QM 4.3.0 (https://www.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 @@ -73,11 +73,12 @@ QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer } // namespace DPP //............................................................................ -//$define${AOs::Table} ####################################################### // Check for the minimum required QP version -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpcpp version 6.0.1 or higher required +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpcpp version 6.3.0 or higher required #endif + +//$define${AOs::Table} ####################################################### namespace DPP { //${AOs::Table} .............................................................. @@ -90,27 +91,11 @@ Table::Table() m_isHungry[n] = false; } } - //${AOs::Table::SM} .......................................................... QP::QState Table::initial(Table * const me, QP::QEvt const * const e) { //${AOs::Table::SM::initial} (void)e; // suppress the compiler warning about unused parameter - QS_OBJ_DICTIONARY(&l_table); - QS_FUN_DICTIONARY(&QP::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 - me->subscribe(DONE_SIG); me->subscribe(PAUSE_SIG); me->subscribe(SERVE_SIG); @@ -121,6 +106,21 @@ QP::QState Table::initial(Table * const me, QP::QEvt const * const e) { me->m_isHungry[n] = false; BSP::displayPhilStat(n, THINKING); } + + // global signals... + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + 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); + + // signals just for this AO... + QS_SIG_DICTIONARY(HUNGRY_SIG, me); + + QS_FUN_DICTIONARY(&active); + QS_FUN_DICTIONARY(&serving); + QS_FUN_DICTIONARY(&paused); + return Q_TRAN(&serving); } //${AOs::Table::SM::active} ..................................................