From 5550cca87dedf72d45250ad01e9cdeee8c4140ba Mon Sep 17 00:00:00 2001 From: QL Date: Thu, 25 Oct 2018 11:11:36 -0400 Subject: [PATCH] 6.3.6 --- 3rd_party/FreeRTOS/Source/croutine.c | 2 +- 3rd_party/FreeRTOS/Source/event_groups.c | 2 +- 3rd_party/FreeRTOS/Source/include/FreeRTOS.h | 2 +- .../FreeRTOS/Source/include/StackMacros.h | 2 +- 3rd_party/FreeRTOS/Source/include/croutine.h | 2 +- .../Source/include/deprecated_definitions.h | 2 +- .../FreeRTOS/Source/include/event_groups.h | 2 +- 3rd_party/FreeRTOS/Source/include/list.h | 2 +- .../FreeRTOS/Source/include/message_buffer.h | 2 +- .../FreeRTOS/Source/include/mpu_prototypes.h | 2 +- .../FreeRTOS/Source/include/mpu_wrappers.h | 2 +- 3rd_party/FreeRTOS/Source/include/portable.h | 2 +- 3rd_party/FreeRTOS/Source/include/projdefs.h | 2 +- 3rd_party/FreeRTOS/Source/include/queue.h | 10 +- 3rd_party/FreeRTOS/Source/include/semphr.h | 2 +- .../FreeRTOS/Source/include/stack_macros.h | 2 +- .../FreeRTOS/Source/include/stream_buffer.h | 6 +- 3rd_party/FreeRTOS/Source/include/task.h | 10 +- 3rd_party/FreeRTOS/Source/include/timers.h | 6 +- 3rd_party/FreeRTOS/Source/list.c | 2 +- .../Source/portable/CCS/ARM_CM3/port.c | 2 +- .../Source/portable/CCS/ARM_CM3/portasm.asm | 2 +- .../Source/portable/CCS/ARM_CM3/portmacro.h | 2 +- .../Source/portable/CCS/ARM_CM4F/port.c | 2 +- .../Source/portable/CCS/ARM_CM4F/portasm.asm | 2 +- .../Source/portable/CCS/ARM_CM4F/portmacro.h | 2 +- .../Source/portable/CCS/ARM_Cortex-R4/port.c | 2 +- .../portable/CCS/ARM_Cortex-R4/portASM.asm | 2 +- .../portable/CCS/ARM_Cortex-R4/portmacro.h | 2 +- .../Source/portable/CCS/MSP430X/data_model.h | 2 +- .../Source/portable/CCS/MSP430X/port.c | 2 +- .../Source/portable/CCS/MSP430X/portext.asm | 2 +- .../Source/portable/CCS/MSP430X/portmacro.h | 2 +- .../Source/portable/Common/mpu_wrappers.c | 2 +- .../portable/GCC/ARM_CA53_64_BIT/port.c | 2 +- .../portable/GCC/ARM_CA53_64_BIT/portASM.S | 2 +- .../portable/GCC/ARM_CA53_64_BIT/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CA9/port.c | 2 +- .../Source/portable/GCC/ARM_CA9/portASM.S | 2 +- .../Source/portable/GCC/ARM_CA9/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CM0/port.c | 2 +- .../Source/portable/GCC/ARM_CM0/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CM3/port.c | 2 +- .../Source/portable/GCC/ARM_CM3/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CM3_MPU/port.c | 2 +- .../portable/GCC/ARM_CM3_MPU/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CM4F/port.c | 2 +- .../Source/portable/GCC/ARM_CM4F/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CM4_MPU/port.c | 2 +- .../portable/GCC/ARM_CM4_MPU/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CM7/r0p1/port.c | 2 +- .../portable/GCC/ARM_CM7/r0p1/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CR5/port.c | 2 +- .../Source/portable/GCC/ARM_CR5/portASM.S | 2 +- .../Source/portable/GCC/ARM_CR5/portmacro.h | 2 +- .../Source/portable/GCC/ARM_CRx_No_GIC/port.c | 2 +- .../portable/GCC/ARM_CRx_No_GIC/portASM.S | 2 +- .../portable/GCC/ARM_CRx_No_GIC/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CA5_No_GIC/port.c | 2 +- .../portable/IAR/ARM_CA5_No_GIC/portASM.h | 2 +- .../portable/IAR/ARM_CA5_No_GIC/portASM.s | 2 +- .../portable/IAR/ARM_CA5_No_GIC/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CA9/port.c | 2 +- .../Source/portable/IAR/ARM_CA9/portASM.h | 2 +- .../Source/portable/IAR/ARM_CA9/portASM.s | 2 +- .../Source/portable/IAR/ARM_CA9/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CM0/port.c | 2 +- .../Source/portable/IAR/ARM_CM0/portasm.s | 2 +- .../Source/portable/IAR/ARM_CM0/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CM3/port.c | 2 +- .../Source/portable/IAR/ARM_CM3/portasm.s | 2 +- .../Source/portable/IAR/ARM_CM3/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CM4F/port.c | 2 +- .../Source/portable/IAR/ARM_CM4F/portasm.s | 2 +- .../Source/portable/IAR/ARM_CM4F/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CM4F_MPU/port.c | 2 +- .../portable/IAR/ARM_CM4F_MPU/portasm.s | 2 +- .../portable/IAR/ARM_CM4F_MPU/portmacro.h | 2 +- .../Source/portable/IAR/ARM_CM7/r0p1/port.c | 2 +- .../portable/IAR/ARM_CM7/r0p1/portasm.s | 2 +- .../portable/IAR/ARM_CM7/r0p1/portmacro.h | 2 +- .../Source/portable/MSVC-MingW/port.c | 2 +- .../Source/portable/MSVC-MingW/portmacro.h | 2 +- .../FreeRTOS/Source/portable/MemMang/heap_1.c | 3 +- .../FreeRTOS/Source/portable/MemMang/heap_2.c | 2 +- .../FreeRTOS/Source/portable/MemMang/heap_3.c | 2 +- .../FreeRTOS/Source/portable/MemMang/heap_4.c | 2 +- .../FreeRTOS/Source/portable/MemMang/heap_5.c | 2 +- .../Source/portable/RVDS/ARM_CA9/port.c | 2 +- .../Source/portable/RVDS/ARM_CA9/portASM.s | 2 +- .../Source/portable/RVDS/ARM_CA9/portmacro.h | 2 +- .../portable/RVDS/ARM_CA9/portmacro.inc | 2 +- .../Source/portable/RVDS/ARM_CM0/port.c | 2 +- .../Source/portable/RVDS/ARM_CM0/portmacro.h | 2 +- .../Source/portable/RVDS/ARM_CM3/port.c | 2 +- .../Source/portable/RVDS/ARM_CM3/portmacro.h | 2 +- .../Source/portable/RVDS/ARM_CM4F/port.c | 2 +- .../Source/portable/RVDS/ARM_CM4F/portmacro.h | 2 +- .../Source/portable/RVDS/ARM_CM4_MPU/port.c | 2 +- .../portable/RVDS/ARM_CM4_MPU/portmacro.h | 2 +- .../Source/portable/RVDS/ARM_CM7/r0p1/port.c | 2 +- .../portable/RVDS/ARM_CM7/r0p1/portmacro.h | 2 +- .../Source/portable/Tasking/ARM_CM4F/port.c | 2 +- .../portable/Tasking/ARM_CM4F/port_asm.asm | 2 +- .../portable/Tasking/ARM_CM4F/portmacro.h | 2 +- 3rd_party/FreeRTOS/Source/queue.c | 6 +- 3rd_party/FreeRTOS/Source/stream_buffer.c | 14 +- 3rd_party/FreeRTOS/Source/tasks.c | 25 +- 3rd_party/FreeRTOS/Source/timers.c | 14 +- doxygen/Doxyfile | 4 +- doxygen/Doxyfile-CHM | 4 +- doxygen/Doxyfile-DOC | 4 +- doxygen/exa.dox | 213 ++- doxygen/exa_native.dox | 4 +- doxygen/exa_os.dox | 180 ++- doxygen/exa_qutest.dox | 158 ++ doxygen/history.dox | 40 +- doxygen/images/blinky_posix.png | Bin 0 -> 183278 bytes doxygen/images/blinky_win.png | Bin 0 -> 15865 bytes doxygen/images/dpp_posix.png | Bin 0 -> 258803 bytes doxygen/images/dpp_win.png | Bin 0 -> 79277 bytes doxygen/images/qp_banner.jpg | Bin 73758 -> 74355 bytes doxygen/images/qutest_philo.png | Bin 0 -> 80468 bytes doxygen/images/qutest_py.png | Bin 0 -> 65702 bytes doxygen/images/qutest_tcl.png | Bin 0 -> 109239 bytes doxygen/images/qutest_tm4c123_py.png | Bin 0 -> 43081 bytes doxygen/images/qutest_tm4c123_tcl.png | Bin 0 -> 60661 bytes doxygen/img/file_mak.png | Bin 0 -> 719 bytes doxygen/img/file_pdf.png | Bin 0 -> 641 bytes doxygen/img/file_py.png | Bin 0 -> 594 bytes doxygen/img/file_qm.png | Bin 0 -> 1030 bytes doxygen/img/file_qmp.png | Bin 0 -> 975 bytes doxygen/img/img.htm | 10 +- doxygen/main.dox | 38 +- doxygen/make.bat | 12 +- doxygen/metrics.dox | 106 +- doxygen/modules.dox | 2 +- doxygen/ports_native.dox | 4 +- doxygen/ports_os.dox | 80 +- doxygen/ports_rtos.dox | 12 +- doxygen/struct.dox | 2 +- .../arm-cm/blinky_efm32-slstk3401a/README.txt | 14 - .../blinky_efm32-slstk3401a/win32-qv/Makefile | 262 --- .../blinky_efm32-slstk3401a/win32-qv/bsp.c | 89 -- .../blinky_efm32-slstk3401a/win32/Makefile | 253 --- .../blinky_efm32-slstk3401a/win32/bsp.c | 89 -- .../arm-cm/blinky_ek-tm4c123gxl/README.txt | 13 - .../blinky_ek-tm4c123gxl/win32-qv/Makefile | 262 --- .../blinky_ek-tm4c123gxl/win32-qv/bsp.c | 89 -- .../blinky_ek-tm4c123gxl/win32/Makefile | 253 --- .../arm-cm/blinky_ek-tm4c123gxl/win32/bsp.c | 89 -- .../arm-cm/dpp_efm32-slstk3401a/README.txt | 52 +- .../arm-cm/dpp_efm32-slstk3401a/qk/main.c | 10 - .../arm-cm/dpp_efm32-slstk3401a/qv/main.c | 10 - .../arm-cm/dpp_efm32-slstk3401a/qxk/main.c | 10 - .../{win32-qv => win32-gui}/Makefile | 196 ++- .../{win32-qv => win32-gui}/Res/BTN_DWN.bmp | Bin .../{win32-qv => win32-gui}/Res/BTN_UP.bmp | Bin .../{win32-qv => win32-gui}/Res/eating.bmp | Bin .../{win32-qv => win32-gui}/Res/hungry.bmp | Bin .../{win32-qv => win32-gui}/Res/qp.ico | Bin .../{win32-qv => win32-gui}/Res/thinking.bmp | Bin .../{win32-qv => win32-gui}/bsp.c | 251 +-- .../{win32-qv => win32-gui}/dpp-gui.rc | 0 .../{win32-qv => win32-gui}/dpp-gui.sln | 0 .../{win32-qv => win32-gui}/dpp-gui.vcxproj | 28 +- .../dpp-gui.vcxproj.filters | 8 - .../{win32-qv => win32-gui}/main.c | 10 - .../{win32-qv => win32-gui}/resource.h | 0 .../dpp_efm32-slstk3401a/win32/Makefile | 257 --- .../win32/Res/BTN_DWN.bmp | Bin 5994 -> 0 bytes .../dpp_efm32-slstk3401a/win32/Res/BTN_UP.bmp | Bin 5994 -> 0 bytes .../dpp_efm32-slstk3401a/win32/Res/eating.bmp | Bin 17814 -> 0 bytes .../dpp_efm32-slstk3401a/win32/Res/hungry.bmp | Bin 17814 -> 0 bytes .../win32/Res/thinking.bmp | Bin 17814 -> 0 bytes .../arm-cm/dpp_efm32-slstk3401a/win32/bsp.c | 516 ------ .../dpp_efm32-slstk3401a/win32/dpp-gui.rc | 77 - .../dpp_efm32-slstk3401a/win32/dpp-gui.sln | 23 - .../win32/dpp-gui.vcxproj | 289 ---- .../win32/dpp-gui.vcxproj.filters | 62 - .../arm-cm/dpp_efm32-slstk3401a/win32/main.c | 120 -- .../dpp_efm32-slstk3401a/win32/resource.h | 21 - examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c | 10 - examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c | 9 +- examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c | 9 - examples/arm-cm/dpp_mbed-lpc1768/main.c | 10 - examples/arm-cm/dpp_nucleo-h743zi/qk/main.c | 10 - examples/arm-cm/dpp_nucleo-h743zi/qv/main.c | 10 - examples/arm-cm/dpp_nucleo-h743zi/qxk/main.c | 10 - examples/arm-cm/dpp_nucleo-l053r8/main.c | 10 - examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c | 7 - examples/arm-cm/dpp_nucleo-l152re/main.c | 10 - .../arm-cm/dpp_stm32f4-discovery/qk/main.c | 9 - .../arm-cm/dpp_stm32f4-discovery/qv/main.c | 9 - .../arm-cm/dpp_stm32f4-discovery/qxk/main.c | 9 - .../arm-cm/dpp_stm32f746g-discovery/qk/main.c | 9 - .../arm-cm/dpp_stm32f746g-discovery/qv/main.c | 9 - .../qxk/arm/dpp-qxk.uvoptx | 81 +- .../qxk/arm/dpp-qxk.uvprojx | 13 +- .../dpp_stm32f746g-discovery/qxk/main.c | 9 - examples/arm-cm/game_efm32-slstk3401a/.game | 65 - .../arm-cm/game_efm32-slstk3401a/README.txt | 40 +- examples/arm-cm/game_efm32-slstk3401a/game.h | 2 +- examples/arm-cm/game_efm32-slstk3401a/game.qm | 2 +- examples/arm-cm/game_efm32-slstk3401a/main.c | 13 - examples/arm-cm/game_efm32-slstk3401a/mine1.c | 2 +- examples/arm-cm/game_efm32-slstk3401a/mine2.c | 2 +- .../arm-cm/game_efm32-slstk3401a/missile.c | 2 +- examples/arm-cm/game_efm32-slstk3401a/ship.c | 2 +- .../arm-cm/game_efm32-slstk3401a/tunnel.c | 2 +- .../{win32-qv => win32-gui}/Makefile | 196 ++- .../{win32-qv => win32-gui}/Res/BOARD.bmp | Bin .../{win32-qv => win32-gui}/Res/BTN_DWN.bmp | Bin .../{win32-qv => win32-gui}/Res/BTN_UP.bmp | Bin .../{win32-qv => win32-gui}/Res/LCD.bmp | Bin .../{win32-qv => win32-gui}/Res/LED_OFF.bmp | Bin .../{win32-qv => win32-gui}/Res/LED_ON.bmp | Bin .../win32-gui}/Res/qp.ico | Bin .../{win32-qv => win32-gui}/Res/seg.bmp | Bin .../{win32-qv => win32-gui}/Res/seg0.bmp | Bin .../{win32-qv => win32-gui}/Res/seg1.bmp | Bin .../{win32-qv => win32-gui}/Res/seg2.bmp | Bin .../{win32-qv => win32-gui}/Res/seg3.bmp | Bin .../{win32-qv => win32-gui}/Res/seg4.bmp | Bin .../{win32-qv => win32-gui}/Res/seg5.bmp | Bin .../{win32-qv => win32-gui}/Res/seg6.bmp | Bin .../{win32-qv => win32-gui}/Res/seg7.bmp | Bin .../{win32-qv => win32-gui}/Res/seg8.bmp | Bin .../{win32-qv => win32-gui}/Res/seg9.bmp | Bin .../{win32 => win32-gui}/bsp.c | 243 +-- .../{win32-qv => win32-gui}/game-gui.rc | 0 .../{win32-qv => win32-gui}/game-gui.sln | 0 .../{win32-qv => win32-gui}/game-gui.vcxproj | 35 +- .../game-gui.vcxproj.filters | 14 - .../{win32-qv => win32-gui}/main.c | 9 - .../{win32-qv => win32-gui}/resource.h | 0 .../game_efm32-slstk3401a/win32-qv/Res/qp.ico | Bin 10134 -> 0 bytes .../game_efm32-slstk3401a/win32-qv/bsp.c | 1042 ------------ .../game_efm32-slstk3401a/win32/Makefile | 260 --- .../game_efm32-slstk3401a/win32/Res/BOARD.bmp | Bin 1659366 -> 0 bytes .../win32/Res/BTN_DWN.bmp | Bin 14132 -> 0 bytes .../win32/Res/BTN_UP.bmp | Bin 14132 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/LCD.bmp | Bin 196662 -> 0 bytes .../win32/Res/LED_OFF.bmp | Bin 784 -> 0 bytes .../win32/Res/LED_ON.bmp | Bin 784 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/qp.ico | Bin 10134 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg.bmp | Bin 38334 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg0.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg1.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg2.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg3.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg4.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg5.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg6.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg7.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg8.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/Res/seg9.bmp | Bin 4926 -> 0 bytes .../game_efm32-slstk3401a/win32/game-gui.rc | 127 -- .../game_efm32-slstk3401a/win32/game-gui.sln | 23 - .../win32/game-gui.vcxproj | 291 ---- .../win32/game-gui.vcxproj.filters | 65 - .../arm-cm/game_efm32-slstk3401a/win32/main.c | 126 -- .../game_efm32-slstk3401a/win32/resource.h | 33 - .../blinky_launchxl2-tms57012/qk/ti/.project | 2 +- .../arm-cr/dpp_launchxl2-tms57012/qk/main.c | 9 - .../arm-cr/dpp_launchxl2-tms57012/qv/main.c | 9 - examples/arm7-9/dpp_at91sam7s-ek/main.c | 9 - .../arm-cm/dpp_stm32f429-discovery/main.c | 9 - examples/emwin/demo_no_wm/bsp.c | 12 +- examples/emwin/demo_with_wm/bsp.c | 14 +- .../freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c | 18 +- .../arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp | 60 +- .../freertos/arm-cm/dpp_ek-tm4c123gxl/main.c | 9 - .../freertos/arm-cm/dpp_nucleo-h743zi/main.c | 9 - .../arm-cm/dpp_stm32f746g-discovery/main.c | 9 - examples/msp430/dpp_msp-exp430g2/main.c | 9 - examples/posix-qv/dpp/Makefile | 242 --- examples/posix-qv/dpp/bsp.c | 549 ------- examples/posix-qv/dpp/bsp.h | 47 - examples/posix-qv/dpp/dpp.h | 72 - examples/posix-qv/dpp/dpp.qm | 445 ------ examples/posix-qv/dpp/main.c | 87 - examples/posix-qv/dpp/philo.c | 229 --- examples/posix-qv/dpp/table.c | 300 ---- examples/posix/README.url | 3 - examples/posix/blinky/Makefile | 239 --- examples/posix/blinky/blinky.c | 152 -- examples/posix/blinky/blinky.qm | 105 -- examples/posix/dpp/Makefile | 242 --- examples/posix/dpp/bsp.c | 549 ------- examples/posix/dpp/bsp.h | 47 - examples/posix/dpp/dpp.h | 71 - examples/posix/dpp/dpp.qm | 445 ------ examples/posix/dpp/main.c | 87 - examples/posix/dpp/philo.c | 225 --- examples/posix/dpp/table.c | 296 ---- examples/posix/qhsmtst/Makefile | 240 --- examples/posix/qhsmtst/main.c | 182 --- examples/posix/qhsmtst/qhsmtst.c | 374 ----- examples/posix/qhsmtst/qhsmtst.h | 46 - examples/posix/qhsmtst/qhsmtst.qm | 291 ---- examples/posix/qmsmtst/Makefile | 240 --- examples/posix/qmsmtst/main.c | 182 --- examples/posix/qmsmtst/qmsmtst.c | 688 -------- examples/posix/qmsmtst/qmsmtst.h | 50 - examples/posix/qmsmtst/qmsmtst.qm | 291 ---- examples/qutest/TDDbook_Flash/FakeMicroTime.c | 57 - examples/qutest/TDDbook_Flash/FakeMicroTime.h | 35 - examples/qutest/TDDbook_Flash/Flash.c | 180 --- examples/qutest/TDDbook_Flash/Flash.h | 47 - examples/qutest/TDDbook_Flash/IO.h | 40 - examples/qutest/TDDbook_Flash/Makefile | 247 --- examples/qutest/TDDbook_Flash/MicroTime.h | 35 - examples/qutest/TDDbook_Flash/MockIO.c | 70 - .../qutest/TDDbook_Flash/efm32-slstk3401a.mak | 335 ---- .../qutest/TDDbook_Flash/ek-tm4c123gxl.mak | 335 ---- examples/qutest/TDDbook_Flash/m28w160ect.h | 55 - examples/qutest/TDDbook_Flash/test_Flash.c | 112 -- examples/qutest/TDDbook_Flash/test_Flash.py | 200 --- examples/qutest/TDDbook_Flash/test_Flash.tcl | 200 --- examples/qutest/TDDbook_LedDriver/LedDriver.c | 551 ------- examples/qutest/TDDbook_LedDriver/LedDriver.h | 76 - .../qutest/TDDbook_LedDriver/LedDriverTest.c | 297 ---- examples/qutest/TDDbook_LedDriver/Makefile | 245 --- .../qutest/TDDbook_LedDriver/test_LedDriver.c | 163 -- .../TDDbook_LedDriver/test_LedDriver.py | 80 - .../TDDbook_LedDriver/test_LedDriver.tcl | 75 - examples/qutest/TDDbook_Sprintf/SprintfTest.c | 146 -- .../qutest/TDDbook_Sprintf/test_Sprintf.c | 95 -- .../qutest/TDDbook_Sprintf/test_Sprintf.py | 53 - .../qutest/TDDbook_Sprintf/test_sprintf.tcl | 49 - examples/qutest/blinky/{ => src}/blinky.c | 4 +- examples/qutest/blinky/{ => src}/blinky.h | 2 +- examples/qutest/blinky/{ => src}/blinky.qm | 4 +- examples/qutest/blinky/{ => src}/bsp.c | 2 +- examples/qutest/blinky/{ => src}/bsp.h | 0 examples/qutest/blinky/test_blinky.c | 105 -- examples/qutest/blinky/test_blinky.py | 64 - examples/qutest/blinky/test_blinky.tcl | 57 - examples/qutest/defer/conftest.py | 7 - examples/qutest/defer/defer.c | 255 --- examples/qutest/defer/defer.h | 57 - examples/qutest/defer/ek-tm4c123gxl.mak | 332 ---- examples/qutest/defer/test_defer.c | 103 -- examples/qutest/defer/test_defer_disp.py | 78 - examples/qutest/defer/test_defer_disp.tcl | 81 - examples/qutest/defer/test_defer_post.py | 86 - examples/qutest/defer/test_defer_post.tcl | 89 -- examples/qutest/dpp/conftest.py | 7 - examples/qutest/dpp/efm32-slstk3401a.ewd | 1407 ----------------- examples/qutest/dpp/efm32-slstk3401a.ewp | 1135 ------------- examples/qutest/dpp/efm32-slstk3401a.eww | 10 - examples/qutest/dpp/posix_host.mak | 260 --- examples/qutest/dpp/{ => src}/bsp.c | 0 examples/qutest/dpp/{ => src}/bsp.h | 0 examples/qutest/dpp/{ => src}/dpp.h | 2 +- examples/qutest/dpp/{ => src}/dpp.qm | 12 +- examples/qutest/dpp/{ => src}/philo.c | 4 +- examples/qutest/dpp/{ => src}/table.c | 10 +- examples/qutest/dpp/{ => test_dpp}/Makefile | 184 ++- .../{blinky => dpp/test_dpp}/conftest.py | 2 +- examples/qutest/dpp/{ => test_dpp}/main.c | 21 +- .../make_efm32} | 87 +- .../dpp/{posix.mak => test_dpp/make_posix} | 139 +- .../make_tm4c123} | 91 +- examples/qutest/dpp/{ => test_dpp}/test_dpp.c | 50 +- examples/qutest/dpp/test_dpp/test_init.py | 71 + examples/qutest/dpp/test_dpp/test_init.tcl | 62 + examples/qutest/dpp/test_dpp/test_tick.py | 84 + examples/qutest/dpp/test_dpp/test_tick.tcl | 78 + .../{blinky => dpp/test_philo}/Makefile | 191 ++- .../test_philo}/conftest.py | 2 +- examples/qutest/dpp/test_philo/test_init.py | 32 + examples/qutest/dpp/test_philo/test_init.tcl | 22 + examples/qutest/dpp/test_philo/test_philo.c | 160 ++ .../qutest/dpp/{ => test_philo}/test_philo.py | 51 +- .../dpp/{ => test_philo}/test_philo.tcl | 97 +- examples/qutest/dpp/test_table.tcl | 45 - .../qutest/{defer => dpp/test_table}/Makefile | 192 ++- .../test_table}/conftest.py | 2 +- examples/qutest/dpp/test_table/test_init.py | 47 + examples/qutest/dpp/test_table/test_init.tcl | 37 + examples/qutest/dpp/test_table/test_table.c | 176 +++ .../qutest/dpp/{ => test_table}/test_table.py | 32 +- examples/qutest/dpp/test_table/test_table.tcl | 83 + examples/qutest/evt_par/conftest.py | 7 - examples/qutest/evt_par/ek-tm4c123gxl.mak | 332 ---- examples/qutest/evt_par/{ => src}/my_ao.c | 2 +- examples/qutest/evt_par/{ => src}/my_app.h | 0 examples/qutest/evt_par/test_evt_par.c | 142 -- examples/qutest/evt_par/test_evt_par.py | 42 - examples/qutest/evt_par/test_evt_par.tcl | 39 - examples/qutest/qhsmtst/Makefile | 246 --- examples/qutest/qhsmtst/conftest.py | 7 - examples/qutest/qhsmtst/efm32-slstk3401a.mak | 333 ---- examples/qutest/qhsmtst/ek-tm4c123gxl.mak | 332 ---- examples/qutest/qhsmtst/{ => src}/qhsmtst.c | 0 examples/qutest/qhsmtst/{ => src}/qhsmtst.h | 0 examples/qutest/qhsmtst/{ => src}/qhsmtst.qm | 0 examples/qutest/qhsmtst/test_qhsm-funct.py | 201 --- examples/qutest/qhsmtst/test_qhsm-funct.tcl | 194 --- examples/qutest/qhsmtst/test_qhsm-struct.py | 225 --- examples/qutest/qhsmtst/test_qhsm-struct.tcl | 218 --- examples/qutest/qmsmtst/Makefile | 246 --- examples/qutest/qmsmtst/conftest.py | 7 - examples/qutest/qmsmtst/{ => src}/qmsmtst.c | 0 examples/qutest/qmsmtst/{ => src}/qmsmtst.h | 0 examples/qutest/qmsmtst/{ => src}/qmsmtst.qm | 0 examples/qutest/qmsmtst/test_qmsm-funct.py | 201 --- examples/qutest/qmsmtst/test_qmsm-funct.tcl | 194 --- examples/qutest/qmsmtst/test_qmsm-struct.py | 225 --- examples/qutest/qmsmtst/test_qmsm-struct.tcl | 218 --- examples/qutest/self_test/conftest.py | 7 - examples/qutest/self_test/posix.mak | 240 --- examples/qutest/self_test/posix_host.mak | 256 --- examples/qutest/self_test/test_command.py | 28 - examples/qutest/self_test/test_command.tcl | 21 - examples/qutest/self_test/test_peek-poke.py | 73 - examples/qutest/self_test/test_peek-poke.tcl | 69 - examples/qutest/self_test/test_probe.py | 50 - examples/qutest/self_test/test_probe.tcl | 46 - examples/qutest/self_test/test_qutest.c | 120 -- .../flash.bat | 0 .../qutest_port.c | 0 .../test.icf | 0 .../test.ld | 0 .../qutest_port.c | 0 .../{ek-tm4c123gxl => target_tm4c123}/test.ld | 0 examples/qutest/unity_basic/README.txt | 105 ++ .../qutest/unity_basic/src/ProductionCode.c | 23 + .../qutest/unity_basic/src/ProductionCode.h | 3 + .../qutest/unity_basic/test_qutest/Makefile | 267 ++++ .../test_qutest}/conftest.py | 2 +- .../qutest/unity_basic/test_qutest/log_py.txt | 84 + .../test_qutest/make_efm32} | 92 +- .../test_qutest/make_tm4c123} | 96 +- .../test_qutest/test_ProductionCode.c} | 113 +- .../test_qutest/test_ProductionCode.py | 78 + .../test_qutest/test_ProductionCode.tcl | 73 + .../test_unity}/Makefile | 150 +- .../test_unity/TestProductionCode.c | 83 + examples/qutest/unity_mock/README.txt | 126 ++ examples/qutest/unity_mock/src/Led.h | 12 + examples/qutest/unity_mock/src/LedBar.c | 16 + examples/qutest/unity_mock/src/LedBar.h | 9 + .../test_qutest}/Makefile | 192 ++- .../qutest/unity_mock/test_qutest/conftest.py | 7 + .../test_qutest/make_efm32} | 94 +- .../test_qutest/make_tm4c123} | 97 +- .../qutest/unity_mock/test_qutest/spy_Led.c | 82 + .../test_qutest/test_LedBar.c} | 102 +- .../unity_mock/test_qutest/test_LedBar.py | 89 ++ .../unity_mock/test_qutest/test_LedBar.tcl | 77 + .../test_unity}/Makefile | 155 +- .../qutest/unity_mock/test_unity/MockLed.c | 123 ++ .../qutest/unity_mock/test_unity/MockLed.h | 38 + .../qutest/unity_mock/test_unity/TestLedBar.c | 87 + .../unity_mock/test_unity/TestLedBar_Runner.c | 107 ++ .../unity_mock/test_unity/cmock/cmock.c | 210 +++ .../unity_mock/test_unity/cmock/cmock.h | 38 + .../test_unity/cmock/cmock_internals.h | 89 ++ .../ti-rtos/arm-cm/dpp_ek-tm4c123gxl/main.c | 9 - .../ucos-ii/arm-cm/dpp_ek-tm4c123gxl/main.c | 9 - .../ucos-ii/arm-cm/dpp_nucleo-l152re/main.c | 9 - examples/win32-qv/README.url | 3 - examples/win32-qv/blinky/README.txt | 7 - examples/win32-qv/dpp-gui/README.txt | 10 - examples/win32-qv/dpp/Makefile | 261 --- examples/win32-qv/dpp/bsp.c | 244 --- examples/win32-qv/dpp/dpp.h | 71 - examples/win32-qv/dpp/dpp.qm | 445 ------ examples/win32-qv/dpp/dpp.vcxproj.filters | 36 - examples/win32-qv/dpp/philo.c | 225 --- examples/win32-qv/dpp/table.c | 296 ---- examples/win32-qv/game-gui/README.txt | 13 - examples/win32-qv/reminder2/Makefile | 259 --- examples/win32-qv/reminder2/reminder2.c | 198 --- examples/win32/README.txt | 43 - examples/win32/README.url | 3 - examples/win32/blinky/Makefile | 239 --- examples/win32/blinky/README.txt | 11 - examples/win32/blinky/make.bat | 3 - examples/win32/calc/Makefile | 260 --- examples/win32/calc1/Makefile | 260 --- examples/win32/calc1_sub/Makefile | 260 --- examples/win32/comp/Makefile | 260 --- examples/win32/comp/alarm.c | 144 -- examples/win32/comp/alarm.h | 44 - examples/win32/comp/clock.h | 62 - examples/win32/comp/comp.c | 303 ---- examples/win32/comp_qm/Makefile | 261 --- examples/win32/defer/Makefile | 259 --- examples/win32/dpp-comp/Makefile | 263 --- examples/win32/dpp/Makefile | 261 --- examples/win32/dpp/bsp.c | 246 --- examples/win32/dpp/bsp.h | 48 - examples/win32/dpp/dpp.sln | 25 - examples/win32/dpp/dpp.vcxproj | 177 --- examples/win32/dpp/dpp.vcxproj.filters | 36 - examples/win32/dpp/main.c | 110 -- examples/win32/history_qhsm/Makefile | 259 --- examples/win32/history_qmsm/Makefile | 259 --- examples/win32/history_qmsm/history.sln | 25 - examples/win32/qhsmtst/Makefile | 250 --- .../win32/qhsmtst/qhsmtst.vcxproj.filters | 28 - examples/win32/qmsmtst/Makefile | 250 --- examples/win32/reminder/Makefile | 259 --- examples/win32/reminder/bsp.c | 69 - examples/win32/reminder/bsp.h | 42 - examples/win32/reminder2/Makefile | 259 --- examples/win32/reminder2/bsp.c | 69 - examples/win32/reminder2/bsp.h | 42 - examples/workstation/README.txt | 106 ++ examples/workstation/blinky/Makefile | 285 ++++ .../{posix => workstation}/blinky/README.txt | 2 +- .../{win32 => workstation}/blinky/blinky.c | 2 +- .../{win32 => workstation}/blinky/blinky.qm | 2 +- examples/workstation/calc/Makefile | 287 ++++ .../{win32/calc1 => workstation/calc}/bsp.c | 38 +- examples/{win32 => workstation}/calc/bsp.h | 0 examples/{win32 => workstation}/calc/calc.c | 0 examples/{win32 => workstation}/calc/calc.h | 0 examples/{win32 => workstation}/calc/calc.qm | 0 examples/{win32 => workstation}/calc/main.c | 33 +- examples/workstation/calc1/Makefile | 287 ++++ .../calc1_sub => workstation/calc1}/bsp.c | 37 +- examples/{win32 => workstation}/calc1/bsp.h | 0 examples/{win32 => workstation}/calc1/calc1.c | 0 examples/{win32 => workstation}/calc1/calc1.h | 0 .../{win32 => workstation}/calc1/calc1.qm | 0 examples/{win32 => workstation}/calc1/main.c | 33 +- examples/workstation/calc1_sub/Makefile | 287 ++++ .../calc1_sub/SM of Calc.png | Bin .../calc1_sub/SubM operand of Calc.png | Bin .../calc => workstation/calc1_sub}/bsp.c | 37 +- .../{win32 => workstation}/calc1_sub/bsp.h | 0 .../calc1_sub/calc1_sub.c | 0 .../calc1_sub/calc1_sub.h | 0 .../calc1_sub/calc1_sub.qm | 0 .../{win32 => workstation}/calc1_sub/main.c | 33 +- examples/workstation/comp/Makefile | 288 ++++ .../comp_qm => workstation/comp}/alarm.c | 47 +- .../comp_qm => workstation/comp}/alarm.h | 24 +- .../{win32/comp_qm => workstation/comp}/bsp.c | 35 +- .../{win32/comp_qm => workstation/comp}/bsp.h | 0 .../comp_qm => workstation/comp}/clock.c | 64 +- .../comp_qm => workstation/comp}/clock.h | 30 +- .../comp_qm => workstation/comp}/comp.qm | 18 +- .../comp_qm => workstation/comp}/main.c | 17 +- examples/workstation/defer/Makefile | 286 ++++ examples/{win32 => workstation}/defer/bsp.c | 38 +- .../reminder2 => workstation/defer}/bsp.h | 0 examples/{win32 => workstation}/defer/defer.c | 12 +- examples/workstation/dpp-comp/Makefile | 291 ++++ .../{win32 => workstation}/dpp-comp/bsp.c | 215 +-- .../dpp => workstation/dpp-comp}/bsp.h | 0 .../dpp-comp/comp/comp.qmp | 2 +- .../dpp-comp/comp/philo.c | 13 +- .../dpp-comp/cont/cont.qmp | 0 .../dpp-comp/cont/dpp.h | 4 +- .../dpp-comp/cont/table.c | 11 +- .../{win32 => workstation}/dpp-comp/dpp.qm | 2 +- .../{win32 => workstation}/dpp-comp/main.c | 4 - .../workstation/dpp-comp/qspyview/dpp.tcl | 384 +++++ .../dpp-comp/qspyview/img/BTN_DWN.gif | Bin 0 -> 2071 bytes .../dpp-comp/qspyview/img/BTN_UP.gif | Bin 0 -> 1987 bytes .../dpp-comp/qspyview/img/eating.gif | Bin 0 -> 3169 bytes .../dpp-comp/qspyview/img/hungry.gif | Bin 0 -> 2428 bytes .../dpp-comp/qspyview/img/thinking.gif | Bin 0 -> 2378 bytes .../dpp-comp/qspyview/qspyview.bat | 4 + .../dpp-comp/qspyview/qspyview.lnk | Bin 0 -> 1400 bytes .../{win32 => workstation}/dpp-gui/README.txt | 2 +- examples/workstation/dpp/Makefile | 288 ++++ examples/workstation/dpp/bsp.c | 175 ++ .../{win32/dpp-comp => workstation/dpp}/bsp.h | 0 examples/{win32 => workstation}/dpp/dpp.h | 0 examples/{win32 => workstation}/dpp/dpp.qm | 0 .../{win32-qv => workstation}/dpp/dpp.sln | 0 .../{win32-qv => workstation}/dpp/dpp.vcxproj | 32 +- examples/workstation/dpp/dpp.vcxproj.filters | 14 + examples/{win32-qv => workstation}/dpp/main.c | 9 - examples/{win32 => workstation}/dpp/philo.c | 0 examples/workstation/dpp/qspyview/dpp.tcl | 384 +++++ .../workstation/dpp/qspyview/img/BTN_DWN.gif | Bin 0 -> 2071 bytes .../workstation/dpp/qspyview/img/BTN_UP.gif | Bin 0 -> 1987 bytes .../workstation/dpp/qspyview/img/eating.gif | Bin 0 -> 3169 bytes .../workstation/dpp/qspyview/img/hungry.gif | Bin 0 -> 2428 bytes .../workstation/dpp/qspyview/img/thinking.gif | Bin 0 -> 2378 bytes .../workstation/dpp/qspyview/qspyview.bat | 4 + .../workstation/dpp/qspyview/qspyview.lnk | Bin 0 -> 1400 bytes examples/{win32 => workstation}/dpp/table.c | 0 .../game-gui/README.txt | 2 +- examples/workstation/history_qhsm/Makefile | 286 ++++ .../history_qhsm/history.c | 70 +- .../history_qhsm/history.h | 16 +- .../history_qhsm/history.qm | 3 +- .../history_qhsm/main.c | 44 +- examples/workstation/history_qmsm/Makefile | 286 ++++ .../history_qmsm/history.c | 8 +- .../history_qmsm/history.h | 2 +- .../history_qmsm/history.qm | 3 +- .../history_qmsm/main.c | 47 +- examples/workstation/qhsmtst/Makefile | 286 ++++ .../{win32 => workstation}/qhsmtst/log.txt | 2 +- .../{win32 => workstation}/qhsmtst/main.c | 94 +- .../{win32 => workstation}/qhsmtst/qhsmtst.c | 7 +- .../{win32 => workstation}/qhsmtst/qhsmtst.h | 2 +- .../{win32 => workstation}/qhsmtst/qhsmtst.qm | 2 +- .../qhsmtst/qhsmtst.sln | 0 .../qhsmtst/qhsmtst.vcxproj | 34 +- .../qhsmtst/qhsmtst.vcxproj.filters | 11 + examples/workstation/qmsmtst/Makefile | 286 ++++ .../{win32 => workstation}/qmsmtst/log.txt | 2 +- .../{win32 => workstation}/qmsmtst/main.c | 92 +- .../{win32 => workstation}/qmsmtst/qmsmtst.c | 7 +- .../{win32 => workstation}/qmsmtst/qmsmtst.h | 2 +- .../{win32 => workstation}/qmsmtst/qmsmtst.qm | 2 +- examples/workstation/reminder/Makefile | 286 ++++ .../reminder2 => workstation/reminder}/bsp.c | 25 +- .../comp => workstation/reminder}/bsp.h | 0 .../reminder/reminder.c | 2 +- examples/workstation/reminder2/Makefile | 286 ++++ .../comp => workstation/reminder2}/bsp.c | 25 +- .../defer => workstation/reminder2}/bsp.h | 0 .../reminder2/reminder2.c | 7 +- include/qep.h | 18 +- include/qs.h | 79 +- include/qs_dummy.h | 67 +- ports/arm-cm/qutest/qf_port.h | 25 +- ports/posix-qutest/qf_port.h | 24 +- ports/posix-qutest/qutest_port.c | 59 +- ports/posix-qv/qf_port.c | 73 +- ports/posix-qv/qf_port.h | 27 +- ports/posix-qv/qs_port.c | 240 +++ ports/posix-qv/qs_port.h | 19 +- ports/posix/README.url | 3 - ports/posix/qf_port.c | 81 +- ports/posix/qf_port.h | 23 +- ports/posix/qs_port.c | 240 +++ ports/posix/qs_port.h | 32 +- ports/win32-qutest/Makefile | 11 +- ports/win32-qutest/qf_port.h | 18 +- ports/win32-qutest/qp.vcxproj | 1 + ports/win32-qutest/qp.vcxproj.filters | 3 + ports/win32-qutest/qutest_port.c | 48 +- ports/win32-qv/Makefile | 19 +- ports/win32-qv/qf_port.c | 82 +- ports/win32-qv/qf_port.h | 30 +- ports/win32-qv/qp.vcxproj | 6 +- ports/win32-qv/qp.vcxproj.filters | 3 + ports/win32-qv/qs_port.c | 243 +++ ports/win32-qv/qs_port.h | 18 +- ports/win32/Makefile | 19 +- ports/win32/qf_port.c | 60 +- ports/win32/qf_port.h | 27 +- ports/win32/qp.vcxproj | 6 +- ports/win32/qp.vcxproj.filters | 3 + ports/win32/qs_port.c | 243 +++ ports/win32/qs_port.h | 18 +- src/qf/qf_actq.c | 93 +- src/qf/qf_dyn.c | 19 +- src/qf/qf_mem.c | 22 +- src/qf/qf_qeq.c | 35 +- src/qs/qs.c | 18 +- src/qs/qs_rx.c | 99 +- src/qs/qutest.c | 478 +++--- version-6.3.4 | 2 - version-6.3.6 | 2 + 668 files changed, 12899 insertions(+), 35396 deletions(-) create mode 100644 doxygen/exa_qutest.dox create mode 100644 doxygen/images/blinky_posix.png create mode 100644 doxygen/images/blinky_win.png create mode 100644 doxygen/images/dpp_posix.png create mode 100644 doxygen/images/dpp_win.png create mode 100644 doxygen/images/qutest_philo.png create mode 100644 doxygen/images/qutest_py.png create mode 100644 doxygen/images/qutest_tcl.png create mode 100644 doxygen/images/qutest_tm4c123_py.png create mode 100644 doxygen/images/qutest_tm4c123_tcl.png create mode 100644 doxygen/img/file_mak.png create mode 100644 doxygen/img/file_pdf.png create mode 100644 doxygen/img/file_py.png create mode 100644 doxygen/img/file_qm.png create mode 100644 doxygen/img/file_qmp.png delete mode 100644 examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/Makefile delete mode 100644 examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/bsp.c delete mode 100644 examples/arm-cm/blinky_efm32-slstk3401a/win32/Makefile delete mode 100644 examples/arm-cm/blinky_efm32-slstk3401a/win32/bsp.c delete mode 100644 examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/Makefile delete mode 100644 examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/bsp.c delete mode 100644 examples/arm-cm/blinky_ek-tm4c123gxl/win32/Makefile delete mode 100644 examples/arm-cm/blinky_ek-tm4c123gxl/win32/bsp.c rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Makefile (59%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Res/BTN_DWN.bmp (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Res/BTN_UP.bmp (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Res/eating.bmp (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Res/hungry.bmp (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Res/qp.ico (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/Res/thinking.bmp (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/bsp.c (59%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/dpp-gui.rc (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/dpp-gui.sln (100%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/dpp-gui.vcxproj (87%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/dpp-gui.vcxproj.filters (76%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/main.c (93%) rename examples/arm-cm/dpp_efm32-slstk3401a/{win32-qv => win32-gui}/resource.h (100%) delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/Makefile delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/BTN_DWN.bmp delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/BTN_UP.bmp delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/eating.bmp delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/hungry.bmp delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/thinking.bmp delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/bsp.c delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.rc delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.sln delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj.filters delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/main.c delete mode 100644 examples/arm-cm/dpp_efm32-slstk3401a/win32/resource.h delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/.game rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Makefile (59%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/BOARD.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/BTN_DWN.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/BTN_UP.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/LCD.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/LED_OFF.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/LED_ON.bmp (100%) rename examples/arm-cm/{dpp_efm32-slstk3401a/win32 => game_efm32-slstk3401a/win32-gui}/Res/qp.ico (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg0.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg1.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg2.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg3.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg4.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg5.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg6.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg7.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg8.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/Res/seg9.bmp (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32 => win32-gui}/bsp.c (81%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/game-gui.rc (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/game-gui.sln (100%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/game-gui.vcxproj (86%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/game-gui.vcxproj.filters (73%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/main.c (94%) rename examples/arm-cm/game_efm32-slstk3401a/{win32-qv => win32-gui}/resource.h (100%) delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/qp.ico delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32-qv/bsp.c delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Makefile delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/BOARD.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/BTN_DWN.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/BTN_UP.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/LCD.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/LED_OFF.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/LED_ON.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/qp.ico delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg0.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg1.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg2.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg3.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg4.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg5.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg6.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg7.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg8.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg9.bmp delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.rc delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.sln delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj.filters delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/main.c delete mode 100644 examples/arm-cm/game_efm32-slstk3401a/win32/resource.h delete mode 100644 examples/posix-qv/dpp/Makefile delete mode 100644 examples/posix-qv/dpp/bsp.c delete mode 100644 examples/posix-qv/dpp/bsp.h delete mode 100644 examples/posix-qv/dpp/dpp.h delete mode 100644 examples/posix-qv/dpp/dpp.qm delete mode 100644 examples/posix-qv/dpp/main.c delete mode 100644 examples/posix-qv/dpp/philo.c delete mode 100644 examples/posix-qv/dpp/table.c delete mode 100644 examples/posix/README.url delete mode 100644 examples/posix/blinky/Makefile delete mode 100644 examples/posix/blinky/blinky.c delete mode 100644 examples/posix/blinky/blinky.qm delete mode 100644 examples/posix/dpp/Makefile delete mode 100644 examples/posix/dpp/bsp.c delete mode 100644 examples/posix/dpp/bsp.h delete mode 100644 examples/posix/dpp/dpp.h delete mode 100644 examples/posix/dpp/dpp.qm delete mode 100644 examples/posix/dpp/main.c delete mode 100644 examples/posix/dpp/philo.c delete mode 100644 examples/posix/dpp/table.c delete mode 100644 examples/posix/qhsmtst/Makefile delete mode 100644 examples/posix/qhsmtst/main.c delete mode 100644 examples/posix/qhsmtst/qhsmtst.c delete mode 100644 examples/posix/qhsmtst/qhsmtst.h delete mode 100644 examples/posix/qhsmtst/qhsmtst.qm delete mode 100644 examples/posix/qmsmtst/Makefile delete mode 100644 examples/posix/qmsmtst/main.c delete mode 100644 examples/posix/qmsmtst/qmsmtst.c delete mode 100644 examples/posix/qmsmtst/qmsmtst.h delete mode 100644 examples/posix/qmsmtst/qmsmtst.qm delete mode 100644 examples/qutest/TDDbook_Flash/FakeMicroTime.c delete mode 100644 examples/qutest/TDDbook_Flash/FakeMicroTime.h delete mode 100644 examples/qutest/TDDbook_Flash/Flash.c delete mode 100644 examples/qutest/TDDbook_Flash/Flash.h delete mode 100644 examples/qutest/TDDbook_Flash/IO.h delete mode 100644 examples/qutest/TDDbook_Flash/Makefile delete mode 100644 examples/qutest/TDDbook_Flash/MicroTime.h delete mode 100644 examples/qutest/TDDbook_Flash/MockIO.c delete mode 100644 examples/qutest/TDDbook_Flash/efm32-slstk3401a.mak delete mode 100644 examples/qutest/TDDbook_Flash/ek-tm4c123gxl.mak delete mode 100644 examples/qutest/TDDbook_Flash/m28w160ect.h delete mode 100644 examples/qutest/TDDbook_Flash/test_Flash.c delete mode 100644 examples/qutest/TDDbook_Flash/test_Flash.py delete mode 100644 examples/qutest/TDDbook_Flash/test_Flash.tcl delete mode 100644 examples/qutest/TDDbook_LedDriver/LedDriver.c delete mode 100644 examples/qutest/TDDbook_LedDriver/LedDriver.h delete mode 100644 examples/qutest/TDDbook_LedDriver/LedDriverTest.c delete mode 100644 examples/qutest/TDDbook_LedDriver/Makefile delete mode 100644 examples/qutest/TDDbook_LedDriver/test_LedDriver.c delete mode 100644 examples/qutest/TDDbook_LedDriver/test_LedDriver.py delete mode 100644 examples/qutest/TDDbook_LedDriver/test_LedDriver.tcl delete mode 100644 examples/qutest/TDDbook_Sprintf/SprintfTest.c delete mode 100644 examples/qutest/TDDbook_Sprintf/test_Sprintf.c delete mode 100644 examples/qutest/TDDbook_Sprintf/test_Sprintf.py delete mode 100644 examples/qutest/TDDbook_Sprintf/test_sprintf.tcl rename examples/qutest/blinky/{ => src}/blinky.c (97%) rename examples/qutest/blinky/{ => src}/blinky.h (95%) rename examples/qutest/blinky/{ => src}/blinky.qm (97%) rename examples/qutest/blinky/{ => src}/bsp.c (98%) rename examples/qutest/blinky/{ => src}/bsp.h (100%) delete mode 100644 examples/qutest/blinky/test_blinky.c delete mode 100644 examples/qutest/blinky/test_blinky.py delete mode 100644 examples/qutest/blinky/test_blinky.tcl delete mode 100644 examples/qutest/defer/conftest.py delete mode 100644 examples/qutest/defer/defer.c delete mode 100644 examples/qutest/defer/defer.h delete mode 100644 examples/qutest/defer/ek-tm4c123gxl.mak delete mode 100644 examples/qutest/defer/test_defer.c delete mode 100644 examples/qutest/defer/test_defer_disp.py delete mode 100644 examples/qutest/defer/test_defer_disp.tcl delete mode 100644 examples/qutest/defer/test_defer_post.py delete mode 100644 examples/qutest/defer/test_defer_post.tcl delete mode 100644 examples/qutest/dpp/conftest.py delete mode 100644 examples/qutest/dpp/efm32-slstk3401a.ewd delete mode 100644 examples/qutest/dpp/efm32-slstk3401a.ewp delete mode 100644 examples/qutest/dpp/efm32-slstk3401a.eww delete mode 100644 examples/qutest/dpp/posix_host.mak rename examples/qutest/dpp/{ => src}/bsp.c (100%) rename examples/qutest/dpp/{ => src}/bsp.h (100%) rename examples/qutest/dpp/{ => src}/dpp.h (97%) rename examples/qutest/dpp/{ => src}/dpp.qm (96%) rename examples/qutest/dpp/{ => src}/philo.c (97%) rename examples/qutest/dpp/{ => src}/table.c (96%) rename examples/qutest/dpp/{ => test_dpp}/Makefile (66%) rename examples/qutest/{blinky => dpp/test_dpp}/conftest.py (69%) rename examples/qutest/dpp/{ => test_dpp}/main.c (86%) rename examples/qutest/dpp/{efm32-slstk3401a.mak => test_dpp/make_efm32} (82%) rename examples/qutest/dpp/{posix.mak => test_dpp/make_posix} (74%) rename examples/qutest/dpp/{ek-tm4c123gxl.mak => test_dpp/make_tm4c123} (81%) rename examples/qutest/dpp/{ => test_dpp}/test_dpp.c (70%) create mode 100644 examples/qutest/dpp/test_dpp/test_init.py create mode 100644 examples/qutest/dpp/test_dpp/test_init.tcl create mode 100644 examples/qutest/dpp/test_dpp/test_tick.py create mode 100644 examples/qutest/dpp/test_dpp/test_tick.tcl rename examples/qutest/{blinky => dpp/test_philo}/Makefile (65%) rename examples/qutest/{TDDbook_Flash => dpp/test_philo}/conftest.py (69%) create mode 100644 examples/qutest/dpp/test_philo/test_init.py create mode 100644 examples/qutest/dpp/test_philo/test_init.tcl create mode 100644 examples/qutest/dpp/test_philo/test_philo.c rename examples/qutest/dpp/{ => test_philo}/test_philo.py (75%) rename examples/qutest/dpp/{ => test_philo}/test_philo.tcl (51%) delete mode 100644 examples/qutest/dpp/test_table.tcl rename examples/qutest/{defer => dpp/test_table}/Makefile (65%) rename examples/qutest/{TDDbook_LedDriver => dpp/test_table}/conftest.py (69%) create mode 100644 examples/qutest/dpp/test_table/test_init.py create mode 100644 examples/qutest/dpp/test_table/test_init.tcl create mode 100644 examples/qutest/dpp/test_table/test_table.c rename examples/qutest/dpp/{ => test_table}/test_table.py (67%) create mode 100644 examples/qutest/dpp/test_table/test_table.tcl delete mode 100644 examples/qutest/evt_par/conftest.py delete mode 100644 examples/qutest/evt_par/ek-tm4c123gxl.mak rename examples/qutest/evt_par/{ => src}/my_ao.c (98%) rename examples/qutest/evt_par/{ => src}/my_app.h (100%) delete mode 100644 examples/qutest/evt_par/test_evt_par.c delete mode 100644 examples/qutest/evt_par/test_evt_par.py delete mode 100644 examples/qutest/evt_par/test_evt_par.tcl delete mode 100644 examples/qutest/qhsmtst/Makefile delete mode 100644 examples/qutest/qhsmtst/conftest.py delete mode 100644 examples/qutest/qhsmtst/efm32-slstk3401a.mak delete mode 100644 examples/qutest/qhsmtst/ek-tm4c123gxl.mak rename examples/qutest/qhsmtst/{ => src}/qhsmtst.c (100%) rename examples/qutest/qhsmtst/{ => src}/qhsmtst.h (100%) rename examples/qutest/qhsmtst/{ => src}/qhsmtst.qm (100%) delete mode 100644 examples/qutest/qhsmtst/test_qhsm-funct.py delete mode 100644 examples/qutest/qhsmtst/test_qhsm-funct.tcl delete mode 100644 examples/qutest/qhsmtst/test_qhsm-struct.py delete mode 100644 examples/qutest/qhsmtst/test_qhsm-struct.tcl delete mode 100644 examples/qutest/qmsmtst/Makefile delete mode 100644 examples/qutest/qmsmtst/conftest.py rename examples/qutest/qmsmtst/{ => src}/qmsmtst.c (100%) rename examples/qutest/qmsmtst/{ => src}/qmsmtst.h (100%) rename examples/qutest/qmsmtst/{ => src}/qmsmtst.qm (100%) delete mode 100644 examples/qutest/qmsmtst/test_qmsm-funct.py delete mode 100644 examples/qutest/qmsmtst/test_qmsm-funct.tcl delete mode 100644 examples/qutest/qmsmtst/test_qmsm-struct.py delete mode 100644 examples/qutest/qmsmtst/test_qmsm-struct.tcl delete mode 100644 examples/qutest/self_test/conftest.py delete mode 100644 examples/qutest/self_test/posix.mak delete mode 100644 examples/qutest/self_test/posix_host.mak delete mode 100644 examples/qutest/self_test/test_command.py delete mode 100644 examples/qutest/self_test/test_command.tcl delete mode 100644 examples/qutest/self_test/test_peek-poke.py delete mode 100644 examples/qutest/self_test/test_peek-poke.tcl delete mode 100644 examples/qutest/self_test/test_probe.py delete mode 100644 examples/qutest/self_test/test_probe.tcl delete mode 100644 examples/qutest/self_test/test_qutest.c rename examples/qutest/{efm32-slstk3401a => target_efm32}/flash.bat (100%) rename examples/qutest/{efm32-slstk3401a => target_efm32}/qutest_port.c (100%) rename examples/qutest/{efm32-slstk3401a => target_efm32}/test.icf (100%) rename examples/qutest/{efm32-slstk3401a => target_efm32}/test.ld (100%) rename examples/qutest/{ek-tm4c123gxl => target_tm4c123}/qutest_port.c (100%) rename examples/qutest/{ek-tm4c123gxl => target_tm4c123}/test.ld (100%) create mode 100644 examples/qutest/unity_basic/README.txt create mode 100644 examples/qutest/unity_basic/src/ProductionCode.c create mode 100644 examples/qutest/unity_basic/src/ProductionCode.h create mode 100644 examples/qutest/unity_basic/test_qutest/Makefile rename examples/qutest/{TDDbook_Sprintf => unity_basic/test_qutest}/conftest.py (69%) create mode 100644 examples/qutest/unity_basic/test_qutest/log_py.txt rename examples/qutest/{self_test/efm32-slstk3401a.mak => unity_basic/test_qutest/make_efm32} (81%) rename examples/qutest/{self_test/ek-tm4c123gxl.mak => unity_basic/test_qutest/make_tm4c123} (81%) rename examples/qutest/{qmsmtst/test_qmsm.c => unity_basic/test_qutest/test_ProductionCode.c} (53%) create mode 100644 examples/qutest/unity_basic/test_qutest/test_ProductionCode.py create mode 100644 examples/qutest/unity_basic/test_qutest/test_ProductionCode.tcl rename examples/qutest/{self_test => unity_basic/test_unity}/Makefile (68%) create mode 100644 examples/qutest/unity_basic/test_unity/TestProductionCode.c create mode 100644 examples/qutest/unity_mock/README.txt create mode 100644 examples/qutest/unity_mock/src/Led.h create mode 100644 examples/qutest/unity_mock/src/LedBar.c create mode 100644 examples/qutest/unity_mock/src/LedBar.h rename examples/qutest/{evt_par => unity_mock/test_qutest}/Makefile (65%) create mode 100644 examples/qutest/unity_mock/test_qutest/conftest.py rename examples/qutest/{qmsmtst/efm32-slstk3401a.mak => unity_mock/test_qutest/make_efm32} (81%) rename examples/qutest/{qmsmtst/ek-tm4c123gxl.mak => unity_mock/test_qutest/make_tm4c123} (80%) create mode 100644 examples/qutest/unity_mock/test_qutest/spy_Led.c rename examples/qutest/{qhsmtst/test_qhsm.c => unity_mock/test_qutest/test_LedBar.c} (62%) create mode 100644 examples/qutest/unity_mock/test_qutest/test_LedBar.py create mode 100644 examples/qutest/unity_mock/test_qutest/test_LedBar.tcl rename examples/qutest/{TDDbook_Sprintf => unity_mock/test_unity}/Makefile (68%) create mode 100644 examples/qutest/unity_mock/test_unity/MockLed.c create mode 100644 examples/qutest/unity_mock/test_unity/MockLed.h create mode 100644 examples/qutest/unity_mock/test_unity/TestLedBar.c create mode 100644 examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c create mode 100644 examples/qutest/unity_mock/test_unity/cmock/cmock.c create mode 100644 examples/qutest/unity_mock/test_unity/cmock/cmock.h create mode 100644 examples/qutest/unity_mock/test_unity/cmock/cmock_internals.h delete mode 100644 examples/win32-qv/README.url delete mode 100644 examples/win32-qv/blinky/README.txt delete mode 100644 examples/win32-qv/dpp-gui/README.txt delete mode 100644 examples/win32-qv/dpp/Makefile delete mode 100644 examples/win32-qv/dpp/bsp.c delete mode 100644 examples/win32-qv/dpp/dpp.h delete mode 100644 examples/win32-qv/dpp/dpp.qm delete mode 100644 examples/win32-qv/dpp/dpp.vcxproj.filters delete mode 100644 examples/win32-qv/dpp/philo.c delete mode 100644 examples/win32-qv/dpp/table.c delete mode 100644 examples/win32-qv/game-gui/README.txt delete mode 100644 examples/win32-qv/reminder2/Makefile delete mode 100644 examples/win32-qv/reminder2/reminder2.c delete mode 100644 examples/win32/README.txt delete mode 100644 examples/win32/README.url delete mode 100644 examples/win32/blinky/Makefile delete mode 100644 examples/win32/blinky/README.txt delete mode 100644 examples/win32/blinky/make.bat delete mode 100644 examples/win32/calc/Makefile delete mode 100644 examples/win32/calc1/Makefile delete mode 100644 examples/win32/calc1_sub/Makefile delete mode 100644 examples/win32/comp/Makefile delete mode 100644 examples/win32/comp/alarm.c delete mode 100644 examples/win32/comp/alarm.h delete mode 100644 examples/win32/comp/clock.h delete mode 100644 examples/win32/comp/comp.c delete mode 100644 examples/win32/comp_qm/Makefile delete mode 100644 examples/win32/defer/Makefile delete mode 100644 examples/win32/dpp-comp/Makefile delete mode 100644 examples/win32/dpp/Makefile delete mode 100644 examples/win32/dpp/bsp.c delete mode 100644 examples/win32/dpp/bsp.h delete mode 100644 examples/win32/dpp/dpp.sln delete mode 100644 examples/win32/dpp/dpp.vcxproj delete mode 100644 examples/win32/dpp/dpp.vcxproj.filters delete mode 100644 examples/win32/dpp/main.c delete mode 100644 examples/win32/history_qhsm/Makefile delete mode 100644 examples/win32/history_qmsm/Makefile delete mode 100644 examples/win32/history_qmsm/history.sln delete mode 100644 examples/win32/qhsmtst/Makefile delete mode 100644 examples/win32/qhsmtst/qhsmtst.vcxproj.filters delete mode 100644 examples/win32/qmsmtst/Makefile delete mode 100644 examples/win32/reminder/Makefile delete mode 100644 examples/win32/reminder/bsp.c delete mode 100644 examples/win32/reminder/bsp.h delete mode 100644 examples/win32/reminder2/Makefile delete mode 100644 examples/win32/reminder2/bsp.c delete mode 100644 examples/win32/reminder2/bsp.h create mode 100644 examples/workstation/README.txt create mode 100644 examples/workstation/blinky/Makefile rename examples/{posix => workstation}/blinky/README.txt (77%) rename examples/{win32 => workstation}/blinky/blinky.c (98%) rename examples/{win32 => workstation}/blinky/blinky.qm (98%) create mode 100644 examples/workstation/calc/Makefile rename examples/{win32/calc1 => workstation/calc}/bsp.c (83%) rename examples/{win32 => workstation}/calc/bsp.h (100%) rename examples/{win32 => workstation}/calc/calc.c (100%) rename examples/{win32 => workstation}/calc/calc.h (100%) rename examples/{win32 => workstation}/calc/calc.qm (100%) rename examples/{win32 => workstation}/calc/main.c (88%) create mode 100644 examples/workstation/calc1/Makefile rename examples/{win32/calc1_sub => workstation/calc1}/bsp.c (83%) rename examples/{win32 => workstation}/calc1/bsp.h (100%) rename examples/{win32 => workstation}/calc1/calc1.c (100%) rename examples/{win32 => workstation}/calc1/calc1.h (100%) rename examples/{win32 => workstation}/calc1/calc1.qm (100%) rename examples/{win32 => workstation}/calc1/main.c (88%) create mode 100644 examples/workstation/calc1_sub/Makefile rename examples/{win32 => workstation}/calc1_sub/SM of Calc.png (100%) rename examples/{win32 => workstation}/calc1_sub/SubM operand of Calc.png (100%) rename examples/{win32/calc => workstation/calc1_sub}/bsp.c (83%) rename examples/{win32 => workstation}/calc1_sub/bsp.h (100%) rename examples/{win32 => workstation}/calc1_sub/calc1_sub.c (100%) rename examples/{win32 => workstation}/calc1_sub/calc1_sub.h (100%) rename examples/{win32 => workstation}/calc1_sub/calc1_sub.qm (100%) rename examples/{win32 => workstation}/calc1_sub/main.c (88%) create mode 100644 examples/workstation/comp/Makefile rename examples/{win32/comp_qm => workstation/comp}/alarm.c (75%) rename examples/{win32/comp_qm => workstation/comp}/alarm.h (62%) rename examples/{win32/comp_qm => workstation/comp}/bsp.c (86%) rename examples/{win32/comp_qm => workstation/comp}/bsp.h (100%) rename examples/{win32/comp_qm => workstation/comp}/clock.c (76%) rename examples/{win32/comp_qm => workstation/comp}/clock.h (63%) rename examples/{win32/comp_qm => workstation/comp}/comp.qm (97%) rename examples/{win32/comp_qm => workstation/comp}/main.c (87%) create mode 100644 examples/workstation/defer/Makefile rename examples/{win32 => workstation}/defer/bsp.c (73%) rename examples/{win32-qv/reminder2 => workstation/defer}/bsp.h (100%) rename examples/{win32 => workstation}/defer/defer.c (97%) create mode 100644 examples/workstation/dpp-comp/Makefile rename examples/{win32 => workstation}/dpp-comp/bsp.c (50%) rename examples/{win32-qv/dpp => workstation/dpp-comp}/bsp.h (100%) rename examples/{win32 => workstation}/dpp-comp/comp/comp.qmp (99%) rename examples/{win32 => workstation}/dpp-comp/comp/philo.c (94%) rename examples/{win32 => workstation}/dpp-comp/cont/cont.qmp (100%) rename examples/{win32 => workstation}/dpp-comp/cont/dpp.h (96%) rename examples/{win32 => workstation}/dpp-comp/cont/table.c (97%) rename examples/{win32 => workstation}/dpp-comp/dpp.qm (95%) rename examples/{win32 => workstation}/dpp-comp/main.c (97%) create mode 100644 examples/workstation/dpp-comp/qspyview/dpp.tcl create mode 100644 examples/workstation/dpp-comp/qspyview/img/BTN_DWN.gif create mode 100644 examples/workstation/dpp-comp/qspyview/img/BTN_UP.gif create mode 100644 examples/workstation/dpp-comp/qspyview/img/eating.gif create mode 100644 examples/workstation/dpp-comp/qspyview/img/hungry.gif create mode 100644 examples/workstation/dpp-comp/qspyview/img/thinking.gif create mode 100644 examples/workstation/dpp-comp/qspyview/qspyview.bat create mode 100644 examples/workstation/dpp-comp/qspyview/qspyview.lnk rename examples/{win32 => workstation}/dpp-gui/README.txt (84%) create mode 100644 examples/workstation/dpp/Makefile create mode 100644 examples/workstation/dpp/bsp.c rename examples/{win32/dpp-comp => workstation/dpp}/bsp.h (100%) rename examples/{win32 => workstation}/dpp/dpp.h (100%) rename examples/{win32 => workstation}/dpp/dpp.qm (100%) rename examples/{win32-qv => workstation}/dpp/dpp.sln (100%) rename examples/{win32-qv => workstation}/dpp/dpp.vcxproj (80%) create mode 100644 examples/workstation/dpp/dpp.vcxproj.filters rename examples/{win32-qv => workstation}/dpp/main.c (93%) rename examples/{win32 => workstation}/dpp/philo.c (100%) create mode 100644 examples/workstation/dpp/qspyview/dpp.tcl create mode 100644 examples/workstation/dpp/qspyview/img/BTN_DWN.gif create mode 100644 examples/workstation/dpp/qspyview/img/BTN_UP.gif create mode 100644 examples/workstation/dpp/qspyview/img/eating.gif create mode 100644 examples/workstation/dpp/qspyview/img/hungry.gif create mode 100644 examples/workstation/dpp/qspyview/img/thinking.gif create mode 100644 examples/workstation/dpp/qspyview/qspyview.bat create mode 100644 examples/workstation/dpp/qspyview/qspyview.lnk rename examples/{win32 => workstation}/dpp/table.c (100%) rename examples/{win32 => workstation}/game-gui/README.txt (86%) create mode 100644 examples/workstation/history_qhsm/Makefile rename examples/{win32 => workstation}/history_qhsm/history.c (77%) rename examples/{win32 => workstation}/history_qhsm/history.h (66%) rename examples/{win32 => workstation}/history_qhsm/history.qm (98%) rename examples/{win32 => workstation}/history_qhsm/main.c (72%) create mode 100644 examples/workstation/history_qmsm/Makefile rename examples/{win32 => workstation}/history_qmsm/history.c (99%) rename examples/{win32 => workstation}/history_qmsm/history.h (95%) rename examples/{win32 => workstation}/history_qmsm/history.qm (98%) rename examples/{win32 => workstation}/history_qmsm/main.c (71%) create mode 100644 examples/workstation/qhsmtst/Makefile rename examples/{win32 => workstation}/qhsmtst/log.txt (95%) rename examples/{win32 => workstation}/qhsmtst/main.c (76%) rename examples/{win32 => workstation}/qhsmtst/qhsmtst.c (98%) rename examples/{win32 => workstation}/qhsmtst/qhsmtst.h (95%) rename examples/{win32 => workstation}/qhsmtst/qhsmtst.qm (99%) rename examples/{win32 => workstation}/qhsmtst/qhsmtst.sln (100%) rename examples/{win32 => workstation}/qhsmtst/qhsmtst.vcxproj (79%) create mode 100644 examples/workstation/qhsmtst/qhsmtst.vcxproj.filters create mode 100644 examples/workstation/qmsmtst/Makefile rename examples/{win32 => workstation}/qmsmtst/log.txt (95%) rename examples/{win32 => workstation}/qmsmtst/main.c (76%) rename examples/{win32 => workstation}/qmsmtst/qmsmtst.c (99%) rename examples/{win32 => workstation}/qmsmtst/qmsmtst.h (95%) rename examples/{win32 => workstation}/qmsmtst/qmsmtst.qm (99%) create mode 100644 examples/workstation/reminder/Makefile rename examples/{win32-qv/reminder2 => workstation/reminder}/bsp.c (81%) rename examples/{win32/comp => workstation/reminder}/bsp.h (100%) rename examples/{win32 => workstation}/reminder/reminder.c (99%) create mode 100644 examples/workstation/reminder2/Makefile rename examples/{win32/comp => workstation/reminder2}/bsp.c (81%) rename examples/{win32/defer => workstation/reminder2}/bsp.h (100%) rename examples/{win32 => workstation}/reminder2/reminder2.c (98%) create mode 100644 ports/posix-qv/qs_port.c delete mode 100644 ports/posix/README.url create mode 100644 ports/posix/qs_port.c create mode 100644 ports/win32-qv/qs_port.c create mode 100644 ports/win32/qs_port.c delete mode 100644 version-6.3.4 create mode 100644 version-6.3.6 diff --git a/3rd_party/FreeRTOS/Source/croutine.c b/3rd_party/FreeRTOS/Source/croutine.c index 14e3e0c8..453ff407 100644 --- a/3rd_party/FreeRTOS/Source/croutine.c +++ b/3rd_party/FreeRTOS/Source/croutine.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/event_groups.c b/3rd_party/FreeRTOS/Source/event_groups.c index 04f369db..b12b0e6a 100644 --- a/3rd_party/FreeRTOS/Source/event_groups.c +++ b/3rd_party/FreeRTOS/Source/event_groups.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/FreeRTOS.h b/3rd_party/FreeRTOS/Source/include/FreeRTOS.h index 50cbbd99..c5a409a6 100644 --- a/3rd_party/FreeRTOS/Source/include/FreeRTOS.h +++ b/3rd_party/FreeRTOS/Source/include/FreeRTOS.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/StackMacros.h b/3rd_party/FreeRTOS/Source/include/StackMacros.h index 64436606..f4678ccc 100644 --- a/3rd_party/FreeRTOS/Source/include/StackMacros.h +++ b/3rd_party/FreeRTOS/Source/include/StackMacros.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/croutine.h b/3rd_party/FreeRTOS/Source/include/croutine.h index 7723aaf7..87abc414 100644 --- a/3rd_party/FreeRTOS/Source/include/croutine.h +++ b/3rd_party/FreeRTOS/Source/include/croutine.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/deprecated_definitions.h b/3rd_party/FreeRTOS/Source/include/deprecated_definitions.h index 5c727b9e..c091fceb 100644 --- a/3rd_party/FreeRTOS/Source/include/deprecated_definitions.h +++ b/3rd_party/FreeRTOS/Source/include/deprecated_definitions.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/event_groups.h b/3rd_party/FreeRTOS/Source/include/event_groups.h index 4d4b1c0e..61fccb08 100644 --- a/3rd_party/FreeRTOS/Source/include/event_groups.h +++ b/3rd_party/FreeRTOS/Source/include/event_groups.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/list.h b/3rd_party/FreeRTOS/Source/include/list.h index b814a13a..e81b200d 100644 --- a/3rd_party/FreeRTOS/Source/include/list.h +++ b/3rd_party/FreeRTOS/Source/include/list.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/message_buffer.h b/3rd_party/FreeRTOS/Source/include/message_buffer.h index c21d9bee..1fa846e0 100644 --- a/3rd_party/FreeRTOS/Source/include/message_buffer.h +++ b/3rd_party/FreeRTOS/Source/include/message_buffer.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/mpu_prototypes.h b/3rd_party/FreeRTOS/Source/include/mpu_prototypes.h index c0e5ba31..8510d402 100644 --- a/3rd_party/FreeRTOS/Source/include/mpu_prototypes.h +++ b/3rd_party/FreeRTOS/Source/include/mpu_prototypes.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/mpu_wrappers.h b/3rd_party/FreeRTOS/Source/include/mpu_wrappers.h index a45302c2..fa5cd5bf 100644 --- a/3rd_party/FreeRTOS/Source/include/mpu_wrappers.h +++ b/3rd_party/FreeRTOS/Source/include/mpu_wrappers.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/portable.h b/3rd_party/FreeRTOS/Source/include/portable.h index 1e6268dc..500c2917 100644 --- a/3rd_party/FreeRTOS/Source/include/portable.h +++ b/3rd_party/FreeRTOS/Source/include/portable.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/projdefs.h b/3rd_party/FreeRTOS/Source/include/projdefs.h index d334b51f..d245c3ff 100644 --- a/3rd_party/FreeRTOS/Source/include/projdefs.h +++ b/3rd_party/FreeRTOS/Source/include/projdefs.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/queue.h b/3rd_party/FreeRTOS/Source/include/queue.h index 416abd18..6715d9ea 100644 --- a/3rd_party/FreeRTOS/Source/include/queue.h +++ b/3rd_party/FreeRTOS/Source/include/queue.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -44,22 +44,22 @@ extern "C" { * returns an QueueHandle_t variable that can then be used as a parameter to * xQueueSend(), xQueueReceive(), etc. */ -struct QueueDef_t; -typedef struct QueueDef_t * QueueHandle_t; +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition * QueueHandle_t; /** * Type by which queue sets are referenced. For example, a call to * xQueueCreateSet() returns an xQueueSet variable that can then be used as a * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. */ -typedef struct QueueDef_t * QueueSetHandle_t; +typedef struct QueueDefinition * QueueSetHandle_t; /** * Queue sets can contain both queues and semaphores, so the * QueueSetMemberHandle_t is defined as a type to be used where a parameter or * return value can be either an QueueHandle_t or an SemaphoreHandle_t. */ -typedef struct QueueDef_t * QueueSetMemberHandle_t; +typedef struct QueueDefinition * QueueSetMemberHandle_t; /* For internal use only. */ #define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) diff --git a/3rd_party/FreeRTOS/Source/include/semphr.h b/3rd_party/FreeRTOS/Source/include/semphr.h index 061ad099..7056ebfb 100644 --- a/3rd_party/FreeRTOS/Source/include/semphr.h +++ b/3rd_party/FreeRTOS/Source/include/semphr.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/stack_macros.h b/3rd_party/FreeRTOS/Source/include/stack_macros.h index a74ff426..26b1bfd5 100644 --- a/3rd_party/FreeRTOS/Source/include/stack_macros.h +++ b/3rd_party/FreeRTOS/Source/include/stack_macros.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/include/stream_buffer.h b/3rd_party/FreeRTOS/Source/include/stream_buffer.h index 8e2cfd5d..e39a6c58 100644 --- a/3rd_party/FreeRTOS/Source/include/stream_buffer.h +++ b/3rd_party/FreeRTOS/Source/include/stream_buffer.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -221,7 +221,7 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ); -
+
* * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. * @@ -318,7 +318,7 @@ size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t *pxHigherPriorityTaskWoken ); -
+
* * Interrupt safe version of the API function that sends a stream of bytes to * the stream buffer. diff --git a/3rd_party/FreeRTOS/Source/include/task.h b/3rd_party/FreeRTOS/Source/include/task.h index 6f5928e5..a03036cb 100644 --- a/3rd_party/FreeRTOS/Source/include/task.h +++ b/3rd_party/FreeRTOS/Source/include/task.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -43,10 +43,10 @@ extern "C" { * MACROS AND DEFINITIONS *----------------------------------------------------------*/ -#define tskKERNEL_VERSION_NUMBER "V10.1.0" +#define tskKERNEL_VERSION_NUMBER "V10.1.1" #define tskKERNEL_VERSION_MAJOR 10 #define tskKERNEL_VERSION_MINOR 1 -#define tskKERNEL_VERSION_BUILD 0 +#define tskKERNEL_VERSION_BUILD 1 /** * task. h @@ -58,8 +58,8 @@ extern "C" { * \defgroup TaskHandle_t TaskHandle_t * \ingroup Tasks */ -struct TaskControlBlock_t; -typedef struct TaskControlBlock_t* TaskHandle_t; +struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tskTaskControlBlock* TaskHandle_t; /* * Defines the prototype to which the application task hook function must diff --git a/3rd_party/FreeRTOS/Source/include/timers.h b/3rd_party/FreeRTOS/Source/include/timers.h index 732f683b..9a96ca78 100644 --- a/3rd_party/FreeRTOS/Source/include/timers.h +++ b/3rd_party/FreeRTOS/Source/include/timers.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -73,8 +73,8 @@ or interrupt version of the queue send function should be used. */ * reference the subject timer in calls to other software timer API functions * (for example, xTimerStart(), xTimerReset(), etc.). */ -struct TimerDef_t; -typedef struct TimerDef_t * TimerHandle_t; +struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tmrTimerControl * TimerHandle_t; /* * Defines the prototype to which timer callback functions must conform. diff --git a/3rd_party/FreeRTOS/Source/list.c b/3rd_party/FreeRTOS/Source/list.c index 456850c7..8fcc904e 100644 --- a/3rd_party/FreeRTOS/Source/list.c +++ b/3rd_party/FreeRTOS/Source/list.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/port.c b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/port.c index ab87b82a..625cf07c 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/port.c +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portasm.asm b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portasm.asm index c94e9584..f7db5a24 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portasm.asm +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portasm.asm @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portmacro.h b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portmacro.h index cf8e8345..980968fb 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM3/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c index 38acb8d7..33c92219 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm index e3e6c482..bba454f0 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portasm.asm @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portmacro.h b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portmacro.h index 0c8055d8..c3634331 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_CM4F/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/port.c b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/port.c index d0f4c562..cf80f72b 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/port.c +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portASM.asm b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portASM.asm index 90e69959..b4559e5d 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portASM.asm +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portASM.asm @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portmacro.h b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portmacro.h index d0af7b06..a8d13856 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/data_model.h b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/data_model.h index 94b1ca52..b8a6b171 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/data_model.h +++ b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/data_model.h @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/port.c b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/port.c index 1027362f..4c6c0e0a 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/port.c +++ b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm index c12247f3..f1a6e51b 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm +++ b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portext.asm @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portmacro.h b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portmacro.h index 64a664af..5b13ca51 100644 --- a/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/CCS/MSP430X/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/Common/mpu_wrappers.c b/3rd_party/FreeRTOS/Source/portable/Common/mpu_wrappers.c index 5796fddc..29dc9d11 100644 --- a/3rd_party/FreeRTOS/Source/portable/Common/mpu_wrappers.c +++ b/3rd_party/FreeRTOS/Source/portable/Common/mpu_wrappers.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/port.c index 42029bf2..2b2ac887 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portASM.S b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portASM.S index 035e16a4..4417b2ce 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portASM.S +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portASM.S @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portmacro.h index d7d276be..3b374cbf 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c index 5224bf39..224f23b1 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S index 74aa2f68..60793298 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portmacro.h index 371517f6..15f53d5c 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CA9/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c index 91cecd42..9019d9b8 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h index e5f929f4..51f02e7a 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c index ebef2c7d..63f92ae5 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h index b0bcd9a1..76739815 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c index db616e91..85d61920 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h index 8d460306..d366fc28 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c index d033059a..08495a73 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h index a1736806..b2099c4c 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c index b96ef3a0..d3a2dce6 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h index 8d460306..d366fc28 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c index 15c213f8..3908ed83 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/portmacro.h index cdf6f75c..37305ed5 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/port.c index 314cec8e..78f1ffbe 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portASM.S b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portASM.S index 5b92487f..c5095306 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portASM.S +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portASM.S @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portmacro.h index caecaf4d..a159d2d1 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CR5/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/port.c b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/port.c index 6388cec8..d09aa967 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/port.c +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portASM.S b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portASM.S index c6550556..dc09231d 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portASM.S +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portASM.S @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portmacro.h b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portmacro.h index 2dd7f1c3..42cc7238 100644 --- a/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/GCC/ARM_CRx_No_GIC/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/port.c index 0a584ba6..f43e1ebf 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.h index 36202ed5..5fa6ba0d 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.h @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.s index d1ec8555..8753d599 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portASM.s @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portmacro.h index 7f168da6..a938e1a9 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA5_No_GIC/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/port.c index 7ead127d..f26cdfc3 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.h index 975e6ed8..b9259db4 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.h @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.s index 531c7aa8..d13d1009 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portASM.s @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portmacro.h index cc38c40b..e92a4206 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CA9/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c index 931355a7..1aa9357c 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s index 80ee4489..e5b76aff 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h index a07a8f61..7a83e8e3 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c index 0478dea9..dcb05cb1 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portasm.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portasm.s index 0d836338..59409e28 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portasm.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portasm.s @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h index e179e9be..2395bf0a 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c index 280e1eeb..0285dc55 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s index c55ebeb5..5422cded 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h index c5adb544..96f5c210 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/port.c index 563e558e..70b4bea3 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portasm.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portasm.s index bc899d19..7d782308 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portasm.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portasm.s @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portmacro.h index 2e740f7e..877357ec 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM4F_MPU/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c index 16d6c82c..0aef1e66 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s index ead1d936..18f5102c 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portasm.s @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portmacro.h b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portmacro.h index 098e33c8..0a68219e 100644 --- a/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/IAR/ARM_CM7/r0p1/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/port.c b/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/port.c index 7758b803..60f1abcf 100644 --- a/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/port.c +++ b/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h b/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h index ded78f7d..20f7bae0 100644 --- a/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/MSVC-MingW/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_1.c b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_1.c index 7de8df23..98906729 100644 --- a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_1.c +++ b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_1.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -52,7 +52,6 @@ task.h is included from an application file. */ /* A few bytes might be lost to byte aligning the heap start address. */ #define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) -/* Allocate the memory for the heap. */ /* Allocate the memory for the heap. */ #if( configAPPLICATION_ALLOCATED_HEAP == 1 ) /* The application writer has already defined the array used for the RTOS diff --git a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_2.c b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_2.c index 689f1a1b..cd1101e1 100644 --- a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_2.c +++ b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_2.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_3.c b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_3.c index 9d9ccd69..abde86c2 100644 --- a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_3.c +++ b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_3.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_4.c b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_4.c index f81136bb..ae8cc516 100644 --- a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_4.c +++ b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_4.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_5.c b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_5.c index 3be8addd..17089368 100644 --- a/3rd_party/FreeRTOS/Source/portable/MemMang/heap_5.c +++ b/3rd_party/FreeRTOS/Source/portable/MemMang/heap_5.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c index d98c902c..9a4e375a 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s index 5944d6c7..e40f0abf 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portASM.s @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h index ef840645..3370641c 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc index f51a7fe8..0636a69a 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CA9/portmacro.inc @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c index 6bbe636f..ee5def3e 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h index 6c18f525..4082fe15 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c index fd43f71f..ce92339d 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h index de077ffe..8d60e74f 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM3/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c index 5be328d7..d436fae2 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h index de077ffe..8d60e74f 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4F/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c index 1baa8b2d..6afb23e5 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h index 6a926860..b2880a63 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c index b98e07fd..55e47a12 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/portmacro.h b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/portmacro.h index b8067aa9..2f93784d 100644 --- a/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/RVDS/ARM_CM7/r0p1/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port.c b/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port.c index cde7564a..a8b31cc7 100644 --- a/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port.c +++ b/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port_asm.asm b/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port_asm.asm index aaeb8d6b..e8fd8279 100644 --- a/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port_asm.asm +++ b/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/port_asm.asm @@ -1,5 +1,5 @@ ;/* -; * FreeRTOS Kernel V10.1.0 +; * FreeRTOS Kernel V10.1.1 ; * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. ; * ; * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/portmacro.h b/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/portmacro.h index 14c69e1a..7bfeeb1d 100644 --- a/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/portmacro.h +++ b/3rd_party/FreeRTOS/Source/portable/Tasking/ARM_CM4F/portmacro.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/3rd_party/FreeRTOS/Source/queue.c b/3rd_party/FreeRTOS/Source/queue.c index b3d074c0..9ce3f8a7 100644 --- a/3rd_party/FreeRTOS/Source/queue.c +++ b/3rd_party/FreeRTOS/Source/queue.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -94,7 +94,7 @@ zero. */ * Items are queued by copy, not reference. See the following link for the * rationale: https://www.freertos.org/Embedded-RTOS-Queues.html */ -typedef struct QueueDef_t +typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ @@ -120,7 +120,7 @@ typedef struct QueueDef_t #endif #if ( configUSE_QUEUE_SETS == 1 ) - struct QueueDef_t *pxQueueSetContainer; + struct QueueDefinition *pxQueueSetContainer; #endif #if ( configUSE_TRACE_FACILITY == 1 ) diff --git a/3rd_party/FreeRTOS/Source/stream_buffer.c b/3rd_party/FreeRTOS/Source/stream_buffer.c index c455c0ce..f583589f 100644 --- a/3rd_party/FreeRTOS/Source/stream_buffer.c +++ b/3rd_party/FreeRTOS/Source/stream_buffer.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -384,7 +384,7 @@ StreamBuffer_t * pxStreamBuffer = xStreamBuffer; { /* The structure and buffer were not allocated dynamically and cannot be freed - just scrub the structure so future use will assert. */ - memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); + ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); } } /*-----------------------------------------------------------*/ @@ -1100,7 +1100,7 @@ size_t xNextHead, xFirstLength; /* Write as many bytes as can be written in the first write. */ configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength ); - memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + ( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ /* If the number of bytes written was less than the number that could be written in the first write... */ @@ -1108,7 +1108,7 @@ size_t xNextHead, xFirstLength; { /* ...then write the remaining bytes to the start of the buffer. */ configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength ); - memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ } else { @@ -1151,7 +1151,7 @@ size_t xCount, xFirstLength, xNextTail; read. Asserts check bounds of read and write. */ configASSERT( xFirstLength <= xMaxCount ); configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength ); - memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ /* If the total number of wanted bytes is greater than the number that could be read in the first read... */ @@ -1159,7 +1159,7 @@ size_t xCount, xFirstLength, xNextTail; { /*...then read the remaining bytes from the start of the buffer. */ configASSERT( xCount <= xMaxCount ); - memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ } else { @@ -1225,7 +1225,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ #endif - memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ + ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ pxStreamBuffer->pucBuffer = pucBuffer; pxStreamBuffer->xLength = xBufferSizeBytes; pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; diff --git a/3rd_party/FreeRTOS/Source/tasks.c b/3rd_party/FreeRTOS/Source/tasks.c index 81411f7a..576fdaf4 100644 --- a/3rd_party/FreeRTOS/Source/tasks.c +++ b/3rd_party/FreeRTOS/Source/tasks.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -266,7 +266,7 @@ to its original value when it is released. */ * and stores task state information, including a pointer to the task's context * (the task's run time environment, including register values) */ -typedef struct TaskControlBlock_t +typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ @@ -350,8 +350,13 @@ typedef tskTCB TCB_t; which static variables must be declared volatile. */ PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; -/* Lists for ready and blocked tasks. --------------------*/ +/* Lists for ready and blocked tasks. -------------------- +xDelayedTaskList1 and xDelayedTaskList2 could be move to function scople but +doing so breaks some kernel aware debuggers and debuggers that rely on removing +the static qualifier. */ PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ @@ -397,6 +402,15 @@ when the scheduler is unsuspended. The pending ready list itself can only be accessed from a critical section. */ PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + /* Do not move these variables to function scope as doing so prevents the + code working with debuggers that need to remove the static qualifier. */ + PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ + +#endif + /*lint -restore */ /*-----------------------------------------------------------*/ @@ -2898,9 +2912,6 @@ void vTaskSwitchContext( void ) #if ( configGENERATE_RUN_TIME_STATS == 1 ) { - PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ - PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ - #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); #else @@ -3488,8 +3499,6 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) static void prvInitialiseTaskLists( void ) { UBaseType_t uxPriority; -PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ -PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) { diff --git a/3rd_party/FreeRTOS/Source/timers.c b/3rd_party/FreeRTOS/Source/timers.c index 3383e6ed..244dbfe3 100644 --- a/3rd_party/FreeRTOS/Source/timers.c +++ b/3rd_party/FreeRTOS/Source/timers.c @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.1.0 + * FreeRTOS Kernel V10.1.1 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -65,7 +65,7 @@ defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ #endif /* The definition of the timers themselves. */ -typedef struct TimerDef_t +typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ @@ -127,7 +127,12 @@ which static variables must be declared volatile. */ /* The list in which active timers are stored. Timers are referenced in expire time order, with the nearest expiry time at the front of the list. Only the -timer service task is allowed to access these lists. */ +timer service task is allowed to access these lists. +xActiveTimerList1 and xActiveTimerList2 could be at function scope but that +breaks some kernel aware debuggers, and debuggers that reply on removing the +static qualifier. */ +PRIVILEGED_DATA static List_t xActiveTimerList1; +PRIVILEGED_DATA static List_t xActiveTimerList2; PRIVILEGED_DATA static List_t *pxCurrentTimerList; PRIVILEGED_DATA static List_t *pxOverflowTimerList; @@ -892,9 +897,6 @@ BaseType_t xResult; static void prvCheckForValidListAndQueue( void ) { -PRIVILEGED_DATA static List_t xActiveTimerList1; -PRIVILEGED_DATA static List_t xActiveTimerList2; - /* Check that the list from which active timers are referenced, and the queue used to communicate with the timer service, have been initialised. */ diff --git a/doxygen/Doxyfile b/doxygen/Doxyfile index 10de48bf..c613c770 100644 --- a/doxygen/Doxyfile +++ b/doxygen/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "QP/C" -PROJECT_NUMBER = "6.3.4" +PROJECT_NUMBER = "6.3.6" PROJECT_BRIEF = PROJECT_LOGO = images/header_logo_ql.png OUTPUT_DIRECTORY = @@ -119,6 +119,7 @@ INPUT = \ exa_apps.dox \ exa_native.dox \ exa_rtos.dox \ + exa_qutest.dox \ exa_os.dox \ exa_mware.dox \ ports.dox \ @@ -150,7 +151,6 @@ EXCLUDE = \ ../include/qs_dummy.h \ ../src/qk \ ../src/qxk \ - ../src/qs/qutest.c \ ../ports/lint/MISRA_Exemplar_Suite_test EXCLUDE_SYMLINKS = NO diff --git a/doxygen/Doxyfile-CHM b/doxygen/Doxyfile-CHM index dceb0198..7a0c1ef1 100644 --- a/doxygen/Doxyfile-CHM +++ b/doxygen/Doxyfile-CHM @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "QP/C" -PROJECT_NUMBER = "6.3.4" +PROJECT_NUMBER = "6.3.6" PROJECT_BRIEF = PROJECT_LOGO = images/header_logo_ql.png OUTPUT_DIRECTORY = @@ -119,6 +119,7 @@ INPUT = \ exa_apps.dox \ exa_native.dox \ exa_rtos.dox \ + exa_qutest.dox \ exa_os.dox \ exa_mware.dox \ ports.dox \ @@ -150,7 +151,6 @@ EXCLUDE = \ ../include/qs_dummy.h \ ../src/qk \ ../src/qxk \ - ../src/qs/qutest.c \ ../ports/lint/MISRA_Exemplar_Suite_test EXCLUDE_SYMLINKS = NO diff --git a/doxygen/Doxyfile-DOC b/doxygen/Doxyfile-DOC index 1daf46c1..390e2171 100644 --- a/doxygen/Doxyfile-DOC +++ b/doxygen/Doxyfile-DOC @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "QP/C" -PROJECT_NUMBER = "6.3.4" +PROJECT_NUMBER = "6.3.6" PROJECT_BRIEF = PROJECT_LOGO = images/header_logo_ql.png OUTPUT_DIRECTORY = @@ -123,6 +123,7 @@ INPUT = \ exa_apps.dox \ exa_native.dox \ exa_rtos.dox \ + exa_qutest.dox \ exa_os.dox \ exa_mware.dox \ ports.dox \ @@ -154,7 +155,6 @@ EXCLUDE = \ ../include/qs_dummy.h \ ../src/qk \ ../src/qxk \ - ../src/qs/qutest.c \ ../ports/lint/MISRA_Exemplar_Suite_test EXCLUDE_SYMLINKS = NO diff --git a/doxygen/exa.dox b/doxygen/exa.dox index c9c08739..c6fedf58 100644 --- a/doxygen/exa.dox +++ b/doxygen/exa.dox @@ -6,7 +6,6 @@ @tableofcontents - @section exa_gen General Comments The QP/C distribution contains many @subpage exa_ref "example projects" to demonstrate various QP/C features. Each example project is described on its own dedicated page that you can find using several criteria (see @ref exa_ref). The example projects have the following main goals: @@ -14,15 +13,15 @@ The QP/C distribution contains many @subpage exa_ref "example projects" to demon - to provide you with a starting point for your own projects — the examples are complete working projects, with correctly pre-configured tools, such as compiler options, linker script, debugger setup, etc. +- to provide you with unit testing support — the [QUTest](/qtools/qutest.html) examples illustrate unit testing techniques both for the development worksations and for embedded targets. + @note It is highly recommended that you create your own projects by **copying and modifying** existing example projects rather than starting your QP/C projects from scratch.
@subsection exa_code Example Code Structure -Starting with QP/C release 5.4.0, **all** examples are bundled into the QP/C download, as opposed to being distributed as separate QP Development Kits (QDKs). The main benefit is of this approach is that it greatly reduces chances of mistakes in combining the mainline QP/C code with various QDKs. The downside is that the QP/C distribution becomes quite large and that examples can't be added or updated independently from the QP/C baseline code. - -All examples are located in sub-directories of the examples top-level folder, with the hierarchical organization outlined below: +QP/C examples are located in sub-directories of the examples top-level folder, with the hierarchical organization outlined below: + +
  • .../ — Native examples for other 3rd-party RTOSes... +
  • lwip/ — Examples for lwIP (3rd-party TCP/IP)       C
  • @@ -127,10 +123,78 @@ All examples are located in sub-directories of the exam +
  • .../ — Examples for other 3rd-party middleware... +
  • + +
  • qutest/ — Examples for QUTest unit testing harness       D +
  • + + +
  • workstation/ — Examples for workstations (Windows, Linux, MacOS)       E +
  • + + + @note -Because the QP distribution contains *all* examples, the number of sub-directories and files in the examples folder may seem daunting. However, knowing the structure of the examples folder, you can simply **delete** the sub-directories that are not interesting to you. +Because the QP distribution contains *all* examples, the number of sub-directories and files in the examples folder may seem daunting. However, knowing the structure of the examples folder, you can simply ignore or even delete the sub-directories that are not interesting to you.
    @@ -155,7 +225,7 @@ To demonstrate QP/C features on an embedded board, you need to create an applica With the exception of the game application, all other example applications can be implemented on a board with just a couple of LEDs. The @ref game application is a bit more involved and requires a small graphic display on the board. Beyond these basic applications for demonstrating and testing the various @ref ports "QP/C ports", the QP/C distribution contains all examples described in the book Practical UML Statecharts in C/C++, 2nd Edition. -@sa @ref exa_win32 +@sa @ref exa_os
    @@ -207,13 +277,20 @@ The Third-Party software components included in the 3rd sub-folders. ------------------------------------------------------------------------------- -@section exa_own Creating your Own QP/C Projects +
    +@subsection exa_own Creating your Own QP/C Projects Perhaps the most important fact of life to remember is that in embedded systems nothing works until everything works. This means that you should always start with a working system and gradually evolve it, changing one thing at a time and making sure that it keeps working every step of the way. Keeping this in mind, the provided QP/C application examples, such as the super-simple Blinky, or a bit more advanced @ref dpp or @ref game, allow you to get started with a working project rather than starting from scratch. You should also always try one of the provided example projects on the same evaluation board that it was designed for, before making any changes. +@note +The evaluation boards used in the examples are all very **inexpensive** and available from major electronic distributors (e.g., [Arrow](https://www.arrow.com/), [DigiKey](https://www.digikey.com/), [Mouser](https://www.mouser.com/), [Avnet](https://www.avnet.com)), as well as directly from the silicon vendors (e.g., a TI board is also available from TI.com). + +@remark +Even before you acquire a specific evaluation board, you can always at least **build** a project that interests you on your workstation. + + Only after convincing yourself that the example project works "as is", you can think about creating your own projects. At this point, the easiest and recommended way is to copy the existing working example project folder (such as the Blinky example) and rename it. After copying the project folder, you still need to change the name of the project/workspace. The easiest and safest way to do this is to open the project/workspace in the corresponding IDE and use the Save As... option to save the project under a different name. You can do this also with the QM model file, which you can open in QM and "Save As" a different model. @@ -222,8 +299,8 @@ After copying the project folder, you still need to change the name of the proje By copying and re-naming an existing, working project, as opposed to creating a new one from scratch, you inherit the correct compiler and linker options an other project settings, which will help you get started much faster. ------------------------------------------------------------------------------- -@section exa_doc Next Steps and Further Reading About QP and QM +
    +@subsection exa_doc Next Steps and Further Reading About QP and QM To work with QP/C effectively, you need to learn a bit more about active objects and state machines. Below is a list of links to enable you to further your knowledge: @@ -231,7 +308,7 @@ To work with QP/C effectively, you need to learn a bit more about active objects 2. Free Support Forum for QP/QM (https://sourceforge.net/p/qpc/discussion/668726 ) 3. QP Code Downloads summary (https://www.state-machine.com/downloads ) 4. QP Application Notes (https://www.state-machine.com/doc/an ) -5. "State Space" Blog (http://embeddedgurus.com/state-space/ ) +5. "State Space" Blog (https://embeddedgurus.com/state-space/ ) @next{exa_ref} */ @@ -257,13 +334,6 @@ To work with QP/C effectively, you need to learn a bit more about active objects @section exa_ref_tool Native Examples (by Development Toolchain) @n -@subsection exa_ref_arm-clang ARM-Clang Toolchain (ARM Compiler 6) -- @ref arm-cm_dpp_nucleo-l053r8   (Cortex-M0+) -- @ref arm-cm_dpp_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_stm32f746g-disco   (Cortex-M7) -- @ref arm-cm_dpp_nucleo-h743zi   (Cortex-M7) - -
    @subsection exa_ref_arm-keil ARM-Keil Toolchain (ARM Compiler 5) - @ref arm-cm_blinky_ek-tm4c123gxl   (Cortex-M4) @@ -278,6 +348,13 @@ To work with QP/C effectively, you need to learn a bit more about active objects - @ref arm-cm_dpp_stm32f746g-disco   (Cortex-M7) +@subsection exa_ref_arm-clang ARM-Clang Toolchain (ARM Compiler 6) +- @ref arm-cm_dpp_nucleo-l053r8   (Cortex-M0+) +- @ref arm-cm_dpp_efm32-slstk3401a   (Cortex-M4) +- @ref arm-cm_dpp_stm32f746g-disco   (Cortex-M7) +- @ref arm-cm_dpp_nucleo-h743zi   (Cortex-M7) + +
    @subsection exa_ref_gnu-arm GNU-ARM (command-line with Makefile, importable to Eclipse) - @ref arm-cm_blinky_ek-tm4c123gxl   (Cortex-M4) @@ -316,13 +393,6 @@ To work with QP/C effectively, you need to learn a bit more about active objects - @ref arm7-9_dpp_at91sam7s-ek   (ARM7TDMI) -
    -@subsection exa_ref_ti-arm TI ARM with CCS IDE -- @ref arm-cm_dpp_ek-tm4c123gxl   (Cortex-M4) -- @ref arm-cr_blinky_launchxl2-tms57012   (Cortex-R4) -- @ref arm-cr_dpp_launchxl2-tms57012   (Cortex-R4) - -
    @subsection exa_ref_ccs-430 CCS for MSP430 - @ref msp430_blinky_msp-exp430g2 @@ -354,10 +424,13 @@ To work with QP/C effectively, you need to learn a bit more about active objects ------------------------------------------------------------------------------ -@section exa_ref_os Examples for Third-Party OS -- @ref exa_posix -- @ref exa_win32 -- @ref exa_win32-qv +@section exa_ref_os Examples for Workstations (Windows, Linux, MacOS) +The examples in the "workstation" directory are designed for workstations (running Windows, Linux, or MacOS), but they can also be used for projects intended for the **embedded** versions of the "big" operating systems (e.g., embedded-Linux or Windows-embedded). These examples are based on the following QP ports: + +- @ref exa_os "POSIX-QV" — single-threaded examples for POSIX-QV (Linux, MacOS) +- @ref exa_os "POSIX" — multi-threaded examples for POSIX (Linux, MacOS, QNX, etc.) +- @ref exa_os "Windows-QV" — single-threaded examples for Windows +- @ref exa_os "Windows" — multi-threaded examples for Windows ------------------------------------------------------------------------------ diff --git a/doxygen/exa_native.dox b/doxygen/exa_native.dox index 6413c5b3..45ca786f 100644 --- a/doxygen/exa_native.dox +++ b/doxygen/exa_native.dox @@ -392,7 +392,7 @@ The examples demonstrates the QUTest unit tests for the application. ------------------------------------------------------------------------------ @section arm-cm_dpp_ek-tm4c123gxl_spy QP/Spy Software Tracing -The application also demonstrates QP/Spy software tracing output and input. To exercise this feature, you need to build and upload the Spy build configuration into the board. +The application also demonstrates QP/Spy software tracing output and input. To exercise this feature, you need to build and upload the Spy build configuration into the board. */ /*##########################################################################*/ @@ -477,7 +477,7 @@ Once programmed into the board, the example rapidly toggles the LED1 from the id ------------------------------------------------------------------------------ @section arm-cm_dpp_efm32-slstk3401a_spy QP/Spy Software Tracing -The application also demonstrates QP/Spy software tracing output and input. To exercise this feature, you need to build and upload the Spy build configuration into the board. +The application also demonstrates QP/Spy software tracing output and input. To exercise this feature, you need to build and upload the Spy build configuration into the board. */ /*##########################################################################*/ diff --git a/doxygen/exa_os.dox b/doxygen/exa_os.dox index a3b4d7e7..db0cba19 100644 --- a/doxygen/exa_os.dox +++ b/doxygen/exa_os.dox @@ -1,66 +1,136 @@ -/*! @page exa_os Examples for Third-Party OS +/*! @page exa_os Examples for Workstations (Windows/POSIX) -- @subpage exa_posix "POSIX" -- @subpage exa_win32 -- @subpage exa_win32-qv +@tableofcontents -@next{exa_posix} -*/ -/*##########################################################################*/ -/*! @page exa_posix POSIX (Linux, VxWorks, QNX, INTEGRITY, etc.) - -

    The examples/posix folder contains the following examples: +

    The examples in the qpc/examples/workstation directory are designed for workstations (running Windows, Linux, or MacOS). Currently, the following examples are provided:

    -- blinky Simple "Blinky" (command-line) -- dpp DPP (command-line) -- qmsmtst Test State Machine based on QP::QMsm with QM model -- qhsmtst Test State Machine based on QP::QHsm with QM model +- blinky — Simple "Blinky" active object (command-line) +- calc — Calculator example from Chapter 2 of [PSiCC2](https://www.state-machine.com/psicc2) +- calc1 — Improved Calculator example from Chapter 2 of [PSiCC2](https://www.state-machine.com/psicc2) +- calc1_sub — Calculator example with sub-machines +- comp — Orthogonal Component design pattern +- defer — Deferred Event design pattern +- dpp — DPP application from Chapter 9 of [PSiCC2](https://www.state-machine.com/psicc2) (**Spy**) +- dpp_comp — DPP with Orthogonal-Component pattern (**Spy**) +- dpp-gui — DPP (with GUI on Windows) (**Spy**) +- game-gui — "Fly 'n' Shoot" game from Chapter 1 of [PSiCC2](https://www.state-machine.com/psicc2) (**Spy**) +- history_qhsm — Transition-to-History (with ::QHsm class) +- history_qmsm — Transition-to-History (with ::QMsm class) +- qhsmtst — Test State Machine based on ::QHsm from Chapter 2 of [PSiCC2](https://www.state-machine.com/psicc2) (**Spy**) +- qmsmtst — Test State Machine based on ::QMsm (**Spy**) +- reminder — Reminder design pattern from Chapter 5 of PSiCC2 +- reminder2 — Reminder design pattern different version -@next{exa_win32} -*/ +@remark +The examples marked with (**Spy**) provide the @ref exa_os-spy "Spy Configuration". -/*##########################################################################*/ -/*! @page exa_win32 Win32 API (Windows) -

    The examples/win32 folder contains all examples described in the book Practical UML Statecharts in C/C++, 2nd Edition. These examples include: -

    +------------------------------------------------------------------------------ +@section exa_win_posix Windows and POSIX Workstations +All examples in the qpc/examples/workstation directory work both on Windows as well as on POSIX (Linux, MacOS). On each of these operating systems you use the same cross-platform `Makefile` co-located with each example. The provided cross-platform `Makefiles` assume the **GNU GCC toolchain**. The `Makefile` discovers the host operating system and chooses the appropriate QP port version: -- blinky Simple "Blinky" for Windows (command line) -- calc Calculator example from Chapter 2 of PSiCC2 -- comp Orthogonal Component design pattern -- comp_qm Orthogonal Component with QM model design pattern -- defer Deferred Event design pattern -- dpp DPP (command-line) -- dpp-gui DPP (with GUI on Windows) -- game-gui "Fly 'n' Shoot" game from Chapter 1 of PSiCC2 -- history_qhsm Transition-to-History (with ::QHsm class) -- history_qmsm Transition-to-History (with ::QMsm class) -- qmsmtst Test State Machine based on ::QMsm with QM model -- qhsmtst Test State Machine based on ::QHsm with QM model -- reminder Reminder design pattern from Chapter 5 of PSiCC2 -- reminder Reminder design pattern different version - -@sa -- @ref exa_win32-qv -- @ref win32 - -@next{exa_win32-qv} -*/ - -/*##########################################################################*/ -/*! @page exa_win32-qv Win32-QV (Windows) - -

    The examples/win32-qv folder contains examples for Win32 API with the cooperative QV kernel. In the Win32-QV port all active objects share only one Win32 thread and are scheduled exactly as in the \ref comp_qv "cooperative QV kernel". The following examples are provided: -

    - -- dpp DPP (command-line) -- game-gui "Fly 'n' Shoot" game from Chapter 1 of PSiCC2 +- On Windows — @ref win32 "win32" or @ref win32-qv "win32-qv"; and +- On POSIX — @ref posix "posix" or @ref posix-qv "posix-qv" (Linux, MacOS, etc.) @note -All examples for @ref exa_win32 will also work with the @ref win32-qv "Win32-QV port" without any modifications to the source code, because @ref win32-qv "Win32-QV port" is designed as a drop-in replacement for the standard @ref win32 "Win32 port". To build the examples with @ref win32-qv "Win32-QV port" you merely need to include ports/win32-qv instead of ports/win32 and you need to link the @ref win32-qv "Win32-QV" QP library. +On Windows, the **make** utility and the GNU GCC toolchain (**MinGW**) are provided in the [QTools collection](https://www.state-machine.com/qtools), which is available for a separate download. The code can be also built with other tools as well, such as the Microsoft Visual Studio 2013 and newer. -@sa -- @ref exa_win32 -- @ref win32-qv -*/ \ No newline at end of file + +@n +![Blinky example on Windows (QP linked from a library)](blinky_win.png) +@n +![Blinky example on Linux (QP built from sources)](blinky_posix.png) + + +------------------------------------------------------------------------------ +@section exa_os-qv Single-Threaded and Multi-Threaded QP/C Ports +Each of the examples can be linked to either the single-threaded QP/C ports (@ref win32-qv or @ref posix-qv) or multi-threaded ports (@ref win32 or @ref posix). The choice is made in the `Makefiles`, by editing the line, which defines the `QP_PORT_DIR` symbol. For instance, the following lines select the @ref win32-qv port and leave the @ref win32 port commented-out: + +@code +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +@endcode + +To reverse the selection, you need to move the comment `#` character. + +@remarks +The single-threaded QP/C ports (@ref win32-qv "win32-qv" and @ref posix-qv "posix-qv") are recommended for **emulating** software intended for deeply-embedded targets ("dual-targeting" the embedded software development).@n + + +@attention +Examples in the workstation directory can also be used on the **embedded versions** of the desktop operating systems, such as **Embedded Linux** and **Windows Embedded**. For the embedded applications, the **multi-threaded** @ref ports_os "QP ports" ( @ref posix "posix" and @ref win32 "win32", respectively) are recommended. + + +------------------------------------------------------------------------------ +@section exa_os_conf Debug, Release, and Spy Build Configurations +The `Makefiles` for the examples generally support the following three build configurations. + + +
    +@subsection exa_os-dbg Debug Configuration +This is the default build configuration, with full debugging information and minimal optimization. To build this configuration, type: + +@code +make +@endcode + +To clean this build, type + +@code +make clean +@endcode + +The object files and the executable is located in the build sub-directory. + + +
    +@subsection exa_os-rel Release Configuration +This configuration is built with no debugging information and high optimization. Single-stepping and debugging might be difficult due +to the lack of debugging information and optimized code. To build this configuration, type: + +@code +make CONF=rel +@endcode + +To clean this build, type + +@code +make CONF=rel clean +@endcode + +The object files and the executable is located in the build_rel directory. + + +
    +@subsection exa_os-spy Spy Configuration +This configuration is built with the QP's Q-SPY trace functionality. The QP/Spy output is performed by a TCP/IP socket and requires launching the QSPY host application with the -t option. To build this configuration, type: + +@code +make CONF=spy +@endcode + +To clean this build, type + +@code +make CONF=spy clean +@endcode + +The object files and the executable are located in the build_spy sub-directory. + +@note +The Spy build configuration requires launching the [QSPY host utility](https://www.state-machine.com/qtools/qspy.html) with the `-t` command-line option **before** running the example. This is so that the example code can output the QS software tracing to the TCP/IP socket of QSPY. + + +@remark +Only specific examples support the Spy build configuration. The examples that don't support it, will report an error or will fail the linking stage. + + +@n +![DPP with QSPY example on Windows (QSPY running in a separate command-prompt)](dpp_win.png) +@n +![DPP with QSPY example on Linux (QSPY running in a separate terminal)](dpp_posix.png) + + +@next{exa_mware} +*/ diff --git a/doxygen/exa_qutest.dox b/doxygen/exa_qutest.dox new file mode 100644 index 00000000..38ec1930 --- /dev/null +++ b/doxygen/exa_qutest.dox @@ -0,0 +1,158 @@ +/*! @page exa_qutest Examples for QUTest Unit Testing Harness + +@tableofcontents + +

    The examples in the qpc/examples/qutest directory demonstrate how to test embedded code with the [QUTest](https://www.state-machine.com/qtools/qutest.html) unit testing harness. Currently, the following examples are provided: +

    + +- blinky — Simple "Blinky" single-active-object application +- dpp — DPP application from Chapter 9 of PSiCC2 +- evt-par — testing events with parameters +- qhsmtst — Test State Machine based on ::QHsm with QM model +- qmsmtst — Test State Machine based on ::QMsm with QM model +- unity_basic — Comparison of a basic testing with Unity and QUTest +- unity_mock — Comparison of a advanced testing (mocking) with Unity and QUTest + + +------------------------------------------------------------------------------ +@section exa_qutest-dir General Code Organization +The projects within the examples/qutest directory have the customary structure used for testing. The production code to be tested is located in the src sub-directory. The testing code is located in the test_... sub-folder(s). The following directory tree illustrates the structure for the `dpp` example: + + +
      +
    • examples/ +
    • +
        +
      • qutest/ — Examples for QUTest unit testing harness +
      • +
          +
        • dpp/ — The simple Blinky example +
        • +
            +
          • src/ — source code under test       A +
          • +
              +
            • bsp.h — BSP header +
            • +
            • dpp.h — DPP header +
            • +
            • dpp.qm — DPP model +
            • +
            • philo.c — `Philo` active object +
            • +
            • table.c — `Table` active object +
            • +
            +
          +
            +
          • test_philo/ — code for unit testing of `Philo` AO        B +
          • +
              +
            • Makefile — cross-platform makefile (host) +
            • +
            • test_philo.c — test fixture for `Philo` AO +
            • +
            • test_philo.tcl — test script for `Philo` (Tcl) +
            • +
            • test_philo.py — test script for `Philo` (Python) +
            • +
            +
          +
            +
          • test_table/ — code for unit testing of `Table` AO        B +
          • +
              +
            • Makefile — cross-platform makefile (host) +
            • +
            • test_philo.c — test fixture for `Table` AO +
            • +
            • test_philo.tcl — test script for `Table` (Tcl) +
            • +
            • test_philo.py — test script for `Table` (Python) +
            • +
            +
          +
            +
          • test_dpp/ — code for unit testing of DPP application        C +
          • +
              +
            • Makefile — cross-platform makefile (host) +
            • +
            • make_efm32 — makefile for the EFM32 **embedded board** +
            • +
            • make_tm4c123 — makefile for the TM4C123 **embedded board** +
            • +
            • main.c — `main()` function for DPP application +
            • +
            • test_dpp.c — test fixture for DPP application +
            • +
            • test_init.tcl — test script for DPP initialization (Tcl) +
            • +
            • test_init.py — test script for DPP initialization (Python) +
            • +
            • test_tick.tcl — test script for DPP tick processing (Tcl) +
            • +
            • test_tick.py — test script for DPP tick processing (Python) +
            • +
            +
          +
        • .../ — Other QUTest examples... +
        • +
        • target_efm32/ — Code for the **embedded target** (EFM32)         D +
        • +
        • target_tm4c123/ — Code for the **embedded target** (TM4C123)        D +
        • +
        +
      +
    + +
      +
    • A The src sub-directory contains the production code to be tested. This directory contains the .qm model file as well as the generated code from the model. +
    • + +
    • B The test_philo sub-directory contains the unit test code for a component, such as `Philo` in this case. Here, you can find the test_*.c **test fixture**, the test scripts test_*.tcl (Tcl) and test_*.py (Python) as well as the cross-platform Makefile to build the code and *run* the tests on the host. +
    • + +
    • C The test_dpp sub-directory contains integration-test code for the application, such as `DPP` in this case. The objective is to test the initialization and interactions *among* components. Here, you can find the main.c `main()` function as well as the test_dpp.c *test fixture*. This directory also contains make_* *makefiles* to build and run the code on the **embedded targets**. +
    • + +
    • D The target_efm32 sub-directory contains the Code needed to build and run the test code on the **embedded target**, like EFM32 in this case. +
    • +
    + + +------------------------------------------------------------------------------ +@section exa_qutest-test Building and Running the Tests +As usual in Test-Driven Development (TDD), the provided Makefiles both *build* the code and *run* the tests. + + +
    +@subsection exa_qutest_host Host Computers +Typically, you start testing on your host computer. Before building/running the code, you need to open a terminal window and launch the [QSPY host application](https://www.state-machine.com/qtools/qspy.html) with the `-t` [command-line option](https://www.state-machine.com/qtools/qspy.html#qspy_command). + +Next, you open another terminal window, change directory to the test_... folder of interest, and type `make`. This will build the application and run the tests (Tcl), as shown in the screen shot below: + +![Testing on the host (Tcl)](qutest_tcl.png) + +To use the Python scripts, you invoke the `make` with the `SCRIPT=py` symbol: + +![Testing on the host (Python)](qutest_py.png) + + +
    +@subsection exa_qutest_target Embedded Targets +The QUTest testing system allows you also to easily test the code directly on the embedded target board. The dpp/test_dpp/ directory illustrates this option by providing the `makefiles` for embedded boards, such as the TM4C123 (Tiva LaunchPad) make_tm4c123. + +To test the code on an embedded board, you need to connect the board to the host computer and launch the and launch the [QSPY host application](https://www.state-machine.com/qtools/qspy.html) with the `-c COM` [command-line option](https://www.state-machine.com/qtools/qspy.html#qspy_command), where `` is the specific COM port number on your host that the board is using. + +Next, you open another terminal window, change directory to the test_... folder of interest, and type `make -f make_tm4c123`. This will build the application and run the tests (Tcl), as shown in the screen shot below: + +![Testing on the TM4C123 embedded target (Tcl)](qutest_tm4c123_tcl.png) + +To use the Python scripts, you invoke the `make -f make_tm4c123` with the `SCRIPT=py` symbol: + +![Testing on the TM4C123 embedded target (Python)](qutest_tm4c123_py.png) + + +@next{exa_os} +*/ diff --git a/doxygen/history.dox b/doxygen/history.dox index a2400fe5..14796e60 100644 --- a/doxygen/history.dox +++ b/doxygen/history.dox @@ -1,10 +1,38 @@ /** @page history Revision History -@section qpc_6_3_4 Version 6.3.4, 2018-08-10 +@section qpc_6_3_6 Version 6.3.6, 2018-10-20 +This release brings important changes and improvements to the unit-testing support for [QUTest](https://www.state-machine.com/qtools/qutest.html). Specifically, a new "dummy" active object class ::QActiveDummy for testing has been added. Instances of this "dummy" AO can be now used as test-doubles for active objects that are recipients of events directly posted by the active object under test (AOUT). This, in turn, eliminates the need to alter the existing event-posting implementation, so that more of the actual QP code can be used in the QP test-stub (qutest.c). + +@note +The QUTest projects that are built QP from sources need to include the qf_time.c file. + + +As a consequence of the changes in the [QUTest](https://www.state-machine.com/qtools/qutest.html) support, the @ref exa_qutest "QUTest examples" have been re-designed and improved. Here, the most important changes include the new code organization, which reflects the customary separation of the code-under-test (CUT) from the code for testing. Also, the tests based on the ["TDD book" by James Grenning](https://www.amazon.com/Driven-Development-Embedded-Pragmatic-Programmers/dp/193435662X) have been replaced with fully functional tests based on the [Unity testing framework](http://www.throwtheswitch.org/unity/). This is to directly compare the traditional approach (Unity) with QUTest. + +The next change related to unit testing is adding ::QS_RX_QUERY_CURR facility to QS-RX (software tracing input channel) and the reply ::QS_QUERY_DATA to the QS output channel. These two extensions allow you to query the status of the "current object" inside the target. The most important example is querying the current state-machine object (::SM_OBJ), which returns the **current state**. + +@note +The new "query" facilities in QP/C match the latest additions to the [QSPY host application](https://www.state-machine.com/qtools/qspy.html). + +Also this release adds [QS dictionary](https://www.state-machine.com/qtools/qs.html#qs_dict) generation for all registered event pools. The generated object dictionaries are `EvtPool1` for pool-1, `EvtPool2` for pool-2, etc. + +@note +Applications no longer need to generate QS object dictionaries for the event pool storage buffers, such as `smlPoolSto[]`, etc. + + +Another big change in this release is re-designing of the @ref exa_os "examples for workstations" (previously `win32`, `win32-qv`, `posix` and `posix-qv`). All these types of examples have been consolidated in the @ref exa_os "exampes/workstation" folder, where the provided `Makefiles` have been extended to be cross-platform so that they work on Windows, Linux, and MacOS without changes. + +To facilitate the creation of truly portable, cross-platform examples, the existing @ref ports_os "QP ports to Windows/POSIX" have been augmented with abstractions for portable console access. Also, the [QS software tracing](https://www.state-machine.com/qtools/qs.html) support via TCP/IP has been now added to the ports themselves. This means that applications no longer need to repeat the code for QS callbacks in the BSP implementation. + +Finally, this release fixes a bug in the @ref posix-qv "POSIX-QV port", where the internal condition variable `QV_condVar_` has not been initialized. + + +------------------------------------------------------------------------------ +@section qpc_6_3_4 Version 6.3.4, 2018-08-10 This release adds new API QTimeEvt_wasDisarmed() for checking the status of a ::QTimeEvt object after it has been disarmed. Specifically, the status of the last call to QTimeEvt_disarm() is kept inside the time event object and can be subsequently checked with the QTimeEvt_wasDisarmed() API. This new function is designed to be used directly as a guard condition on the timeout event, as described in the [PSiCC2 book](/psicc2), Section 7.7.3 "Arming and Disarming a Time Event" on page 359. The QTimeEvt_wasDisarmed() has a side effect of setting the "was disabled" status, so the guard evaluates to 'true' the next time it is checked. - - + + ------------------------------------------------------------------------------ @section qpc_6_3_3a Version 6.3.3a, 2018-07-16 This release adds Python test scripts to the QUTest examples (folder `qpc/examples/qutest`). Specifically, the makefiles have been augmented to accept symbol `SCRIPT=py`, in which case the Python test scripts (`*.py`) are used instead of the default Tcl test scripts (`*.tcl`). @@ -365,7 +393,7 @@ structure provided in the `qpc/src` directory. ------------------------------------------------------------------------------ @section qpc_5_9_0 Version 5.9.0, 2017-05-19 The main purpose of this milestone QP/C release is to provide support for the powerful **Unit Testing Framework** called -QUTest™ (pronounced *cutest*). +QUTest™ (pronounced *cutest*). QUTest™ is the fundamental tooling for Test-Driven Development (TDD) of QP/C applications, which is a highly recommended best-practice. This release introduces changes in the QS-RX (receive) channel and adds several new callbacks. @note The signature of the QS_onCommand() has changed and the function now takes 3 arbitrary 32-bit parameters instead of one. This introduces backwards-incompatibility with previous code that used QS_onCommand(). @@ -878,7 +906,7 @@ This release changes the basic philosophy of distributing the QP frameworks by * Additionally, this release changes the basic philosophy of building your embedded applications with the QP/C framework. Starting with this release, all @ref exa "examples" for embedded boards include the QP/C framework as **source code** within the projects, instead of statically linking with a QP/C library. (**NOTE:** It is still possible to use QP/C as a library, but you need to build such libraries yourself, as they are no longer provided in the QP/C distribution.) -The move to building QP/C from sources ensures the consistent toolset version and compiler options applied to the application code as well as the QP/C framework code. (**NOTE:** The QP/C examples for "big operating systems", like @ref exa_win32 "Windows" or @ref exa_posix "Linux", still use QP/C as a pre-compiled library that is statically linked with the application code.) +The move to building QP/C from sources ensures the consistent toolset version and compiler options applied to the application code as well as the QP/C framework code. (**NOTE:** The QP/C examples for "big operating systems", like @ref exa_os "Windows/POSIX", still use QP/C as a pre-compiled library that is statically linked with the application code.) @note Even though the QP/C source has been re-packaged in this release, there are no API changes to the code, so it remains **backwards compatible** with the existing applications. (Except the build process, which builds QP/C from sources rather than linking to the QP/C library.) @@ -2369,4 +2397,4 @@ P-Thread mutex. updated to the latest QP API changes. - all examples that use QF now contain the QS software tracing support. -*/ \ No newline at end of file +*/can be now used as test-doubles \ No newline at end of file diff --git a/doxygen/images/blinky_posix.png b/doxygen/images/blinky_posix.png new file mode 100644 index 0000000000000000000000000000000000000000..48cc3793e57a5798ba5fac95fcb67be874c2ee5c GIT binary patch literal 183278 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

    %Zx96$YK6`}y^E?krt&t@BZ2 z7Y1!zaz25&`We{>H8s5lBORB=zM6&)yLcntZgUn!>SPc%XbTy)OUOOc0Z$dW3mC3k zW{1pD^oSxBffGn%EyJZai(y)zlpO&up-hg=IK2LJYOe6*2V0y#?E=62Ls)Qe+ExUy z;ga1II@HozFR#{1W1<*kwNQxy`c-7MT#th$mR$aclg zz49r!&Zz;Le!&X8HpAM9kL*pgBU{Kx(ImP08WYE80&&+qN>=J{x=gBoW8zYMv%=Ph z#oreZ8PtCR0vp!_b#%#^@1k6UHEzwg7H#mYRlH6>QjTJMrp*5^)Gu~P6^J};BEOLX zq%47u@9Zi=c_`ityMM0xc0_?)Xa`dMc5nl=$tRjBMPEcl`p~5CFUwDhs8?;Kg$m86 z8W1Yg_p%iWn7q%Zw|0*WE^+K2l8%ULH|fi13@F7NzSMc2t0S z@Z-HRr?&QIu?f@mwm~rqfi)##InFP56i$;|4uQ$H+ScGS(=4Lcw*qI8P8DnksciZ9 zEdg=sO0#i>1Py|){gx;(_+TAyXw4J0bX9V}T;b3WdfDib57JIUjzfoWhVv`vUXych zbj=qKrnGolWW0jF>=g_A^~7GLfa`UjnhDPcb)-i7H=ljAFk#Apr^G z8iN8&L$($w%AOzrr~O4T0d~$iz+5JP>}geAcD-na>2wb0&{_FCGeCC&cQ)OPjAW5b z=OWacZ@3%BUtNW8=u$vNye-nk7$2{N6$#H<`1es$q0@V(sJsBKcKI6!hEY#=n;1!; zNnd){;;Boo;uexSz9Et5z9t^;T{D=~PK!C|k^|>gZ=G0(w36; zi$VHt4b1@08Xnl)boNb|0)GKl;VX1zK&dA*2DpQa9i&=dDJDl~^c`cd(6?dGCspP- zg!h3D2T(QEGkdUFxScv-#Y^Z}?nEWyvTJqz$x|~N_O0d2&5I&hg+CL`l5{eP43}DF zfjjLo-CWH=WBlvgpyKuj79|!77N>`2cba*tJ8g=!i&FueKB=5LrG7(lC)v)MWq~0H z`d}M_j(eoEmcLP~2{mlVUlL-&jiwPdc%FY{e0@w9GDq30r=?w}%$P(Y*nIc?ab79s z4lP=(bYqsDbl{FhsYjbID%FfuZ{b;V>9$LyrKaX>t6TyTqHB=FvZlf%HCMuoWqJD( z%ydbiw~)V;UIka72rLk=QNm{!^9mMpEEB;H8(K8S zfwqA^TD7;Gi|x-krxPKOoa*LAM;$o6a;>q8zs1vimu5;cHa#n0NWb|rj_Cd7w_hFt zgFM~;u=|||K|T>kd^DRV$;N(P4Kv8MWC)4Jp%HCFW_Prk#=Gn3LKQ_VPVGzuRgXDcklH6 z?)m5U)E{Dn>9paSja*_{$D2Xs9K(Ok)w|})_ajUwDteO1WjlxbXk_iT7O(%8SK&<- z!&hy%3YURDm-t1{g0!KB&kS+gIFE8K7q2g46-;f11R_KH76N*;i3(?ZPu~8_2}w2{ z#y<4bc?%J?;njKYjuwHN_bfe41T})on@jmU^7xK-^8tl?W&8~KKq6ARBBhQ2-S$wr z-g5Ja@0TtCfm&Ho_QTACn}(3T;Qhn#>N5cZI?fdHx9N9NDLx7@-1J2O<%0@DoN2Gj zNPiY$?0hfCy%?|RdG^f06U#0f8$W(^g|kUc`pDpM9Kj;`VF%Yl{*oQiJn}aEm_ZW( zSKsdmzuw5#9c4Wy&CKzvZV0^M*%L$eeV7%FaOfh9fT~satsd_>BiWbmslO^ za|#!NagZ}%!_T>K&N2xVAx!;rT5D0MD81H2NuQ1Kl_`uV?>~lWuRXIyctQuY<^spZ(h?U9vx4iEBEgnWQ4i z23`YMd+&nj1X6nt7@!3H*FK=hm)GvvSE-M-wS-t7lst+ss7&y4`bm=m&(daCxvY3~ zGh})!T*OhO4Jp?P`i!!J@dV01<|VBNl$+dFK}FO*TtxPBgS1C-Jm^FGa*vS3|C-d9 z?Y`EqAjg>ooqrXHyfD2n{3k1pbzRq(#$$MbL?uYW>*}SnhWPxSxP@ugBV)F7uTdLE z4ySP`$iuYLfmxzk{-?65@Py~q2ckr}6mMrvX875M84uS zdacK(H=J*%!aefIu5e{{%jS?#$B^n@4xTodcPVEG)`udVs`1DzNR(ikXksLgv7PSD zSGQcnHGakvQzg$%0so9F0Sgin6hFs$BJWVkc_M4-Fr)2gzH2PRxetYkvgE8}SRawS zs$x&m-#@pJ)YLmE$a1xJf)VF({KqH?F;hClHMI!`<)IH8&7O;x)fpVLn{ZBg?XN@@ zEB{SAkDJmuI2JJiN=7OYm+B^jF{O>o#B#_clJ=6xzW2}mu>J*JP*aU7W0hXCXD1F0be6&jU1dsYK`^R z2aTyFrN8?9?b(ov!GC0(VpxoCaWhfL>wgOm@r>G>bQlPiF(_Wj9wJSMi6(bekT`?U zQDW4n>~A{H#UtL@7*aI<`Ej)Q9p@%4pf!gPLBBqqg9%nASU+DRvo7HvR|93m9yAwzqOC}wPT2!FfQJ7w`7YQ}~xgvQ#|6iYJmA%*gdN%*W<4 z))~;MVOS^JBCM0y-TTgB8-7aFp)v%?B7L6c#xSgx!{2AM+|ZT9aBUoVGFQ}W0DQ~o zpjsE<#MCdK1bK)sLdAin`2&({>y{=}n}n9uRioSdTVgf@b|Vg!r0x#yH3%n0$;k=9 zI8l0w9W=Jt!s&U7SPVA~JyH8(RNzu59d}wy&XD%)gP^m?c8=4u*6U>`8FJ0T=ahkZ zg~DB2aRn)k5cwZAh9^reHGq_`&zbYRb7b2e0$?ycjvaz5V&)!s8#S;B@rBn2T?AU{ z4XdD=pQ-R_-f6a}Y+kRv++#+*7UI48Z>Si^g~axNMWgV+h^=ckIcG>9v$q*_7x@6k z=tPR_7L!xEBW~^&L8`8VyFccBy?UhzH*>BRT%1zWtM9DrTOOZRN)ZB8A;{!@n86gO zwww*t`n(disa|bO`Kn2J zcL%{Yu~zhCN}Lb>>3*_vxK@U7I#&`r#@jSTQzy|Za+_nohVfYM%;(=2C?6i<9Sy-m zzoVP_dTdb$qyMr(N^ma(&PvtK6!*26(0|kfp(Xt`*kkhCuYEEk9ft*ix!LLlsN2wLoW%=48&!8EHF^H3WZnR`uUCtq&OI0I8!?_T*hZ_Oxr z>jMU{hl}2CpU?uf8T+{w7R9ZFZF_JE5Wv(LL5Mi5uTkD9kuUX_*Y+uaD`0&d2Do;eeEkuVo!@v6U6j#{s zD);ErcsLmdEa!g^b9o6H+k>7#h9yPT=g5_+js+|We7nom1w6hjc!E!!IpaH)y_%!# zvEPpvU(Pl+ul2_fsb-JyQ!ZEeb&XSl?^HZcGbz|B_8N(EGv(moY(Q{{+^M?r1{-C) z){i>K(I3Ho``L*$x8gYEO7?uepC3cN5S^K1mOV=ULZT1z-@3<;l8sV6gkbzSE~ z-~cb$&{8&a$p6jcj4#t`)G{;SNoKx=Inl+hlDS{rOV^<^eyYAUN+h#BvgY_iwe!dK z3>)U#lfD>~*?hG8tN;^8dR7XPM$<}=fGt-%rN#L12M;@2mkL|vwj_SI*(x;~${ec12mX|XjjMvj2Zbyb|v zUlbGWr9I#}z{~c34I!AHrom&EVbM(Z=Tok5O!=YwKO}37eTBeRWz+Ri7{0glW+9+#ToX0f#=15NaL(QuI^;oOC+96*P0vYL8wi}ppf z`@HIgK34OEM`XkxAzmW~xk{0kL z$7%XtwOq&Qn#|+|6vl;k-M!1q=-VS^i2*wUh&fBjy0fu8YEL;y#&p?OG%*QBS%m@H zp?|$->&|AuA>q70+Hy0J<35*%1qBsU%Zq~}J4q-OstPjuLfsAazE*CjiM43)kgXlt zo*T{e=T`AtdRj`+J=)5BDSADuH0kehZZ?mF(B}2rHr|YE6rKKb*1rjsK>SfMkXj@ZKP?r% zC=uvevf8a1D@QeEEhu~QtE}Y0-KwzpH@QpP>gIyTAZI0Z=!)8LoMWGoHCvK=)~#_W zU7PM#@CRD{g+*%H6CI>4rb~`?#XTg$0z39D_1{IOmEV|8H{y^eqEOST$f5FWAaSS3 zNs00t^dCCfES$VhUuSrL6Qxuc^K_KA?ZUD{UBrtZ0SSPtxTQ04zE1WgProJ8*@b;J z9@DA8=CVdmQ_N+#{e25R zT<+->aZCc|{R$#Kx7^mcrD*3%J}5z5?eHIiAZm-Pkh*D~T5bH4vVfaH~^$i;CV-q8O=t=Wt-AzjumtmU~2^ICT z|HF#==TEYnPV7$R=II^nfNaaeo0P6++;_))4prpKlrgqzI!;#^-yDcask5tG36Sac z>w8VP=fKyq0@1W1jV@PIUB{@7V%5Xeos2i7MEWA@UC10QfgHg#XZP8{v+lf zVBiRi`&J~|lq;0SAF%7zzW_sc3w3j(9KzmyV%7P<#>v~WM!?Kk+b(MZf86V#b{wPE z+b57uENt7yj1zxvYscv&?m`sqwD5*uj)x_>EAM5WmCefKS;%MB?>a*YTR80X7TR#g z1Kc-;?rjm*m&&jAi{XVlG%d|e96wHV{m2%Xza8R>i45D@UE>;FP@Euf-+13Ai%usF z2YkV}3y^e~y^!;k%JP(}^L>k!o#0ZfCx=^pSfB*O0wEeI`=@eXMCII6n%|-<4I_Rt z8{_lV{vG68hG5DXUunw}H(677J ze^>R>A4cE2L+O6W?%RSuYNqN zonf`~(4;qjAjk@F%oL8}v!9|+k@8yFxeDW+^9FsE*Bje4xm@aQY74b>{aR6YD5zU` zRNXN>JCD4WcB&-!FBn8x=7Lr6q!3fCj7~h|c~rG#)Oc91u&xHmyP4(WXy4DrEU;sB`XEJ_9B1oN%25YQCYwFk0u?ZDiQ}sc-q$J1J3axa7C5+rr zb~dLulI(JTLL8tHJ0S&^8sUIEq?@q35S$u0qU6oO#GVdtC6Kfz3N$~sk`osfZ3XoZ zFcQkKSFh&pKhVcAe>ewYyOnV@h^8UE=~MmiF3Mko*C-o*urzmYS1Slwb~)OpV3l*E zX*t(Om`4C#=lOW{xK%q^yw<_EpE2^$pS|yTfJ$FXRH?$5`S9DRDi)8xQ-An%^iAYZ z`jFg%g8CFPKkEUMvdhANYAz!}fVHf5>2ucIom7_fqwhD$Tt8OfeQBM0){2aBA#nEA zTxlZTX8 z6*b38%<9EV%+_(tjX-bkxTR-|`+B83t`6%m4&ecQ3U8Nfa|6N`W4iuf?;<`Qb3xeE z`dymAQcH_8FpxO%l*k|PmQvP(%+(0>B=7sFj=x{(9;uZ_?n~k{)^G6!upG*NCT++7 zEQ1CYy6pQ&vNq@&r*IrO>fx(6U5@>PJ0jHoaiW6Fa(jlqRaRM`MweJqY)nLA4}9OR zKg8Q)F66Art?`(u_|*5w+Vs~q^re3A?m=d_nd6i#&aZF~DYo2z7CFVwyze*i+WI_} zpRE>B1%ucF?GjKB>751|-0xA3WRitRp#f3mV(<@rjBQ$6*+$K==bSXFtf9$fgOfFy z%!a>r`^g*f%it65ey1}_Uv)r42oV#14y$U#q0<#@qnq>PSRORmQ=2d|<<181HFm>t zLoKlx%?T91V6}|b=OoR;T3hb?QHquX=H!#LeA?E1DCVaaC{exXP6DN0Y)(0u*cI8C z0+npdCowl2AleO|8O_J$b17zC55HV1LC|++VGXAE#U!`^pY9vD*#L)d;KQGk?i%NJ z?YB55%Oa=z$&u}%?Aj)OX!jR3Y&pml25`j$pQrU{T3h}=4-h63aZykgby3CV3ZAz= z7yve};iT?6WJRDdb@={jDpTyXZX&9sZc9-1k4S2RPYRdyFh~`_Ag!BaJ5iI3OKuax zr}Rm;!s$r6UiH(z?#TQ?t5S#EYN@b89#@wW(>i_rD__Y?&-2;q98pfv05Cfm~?*KGGK z_&|Lr7Uj7GZhlTx%U^nNv|d11ASUF`_V-K_CQVGp(<%Kyj4S@OtqsVPZeY!bWxZ&j z?xod6atzpPXZ=^}PpK^gm~!5orUvrbP+R&ARo8nWdh+=>)PUeefY0kLgo|ZtB0f4y z6Dj}oy2kZ_SsvTw-ylN&Oj z=YTE$PPM^FXqI`lhMix}sVXs-uv`EM+rK1MNYQ_q6^uVAyojs${4z~Nvqx?u zpzZx*Gx%yQRf~cN`#BljPtOocK&``rwe6GxSKwp_1l7Jjo~(F6m5osJnor0kKdI+U z^@^%??XsBgnG9pO-sSM~n3X6-*Yem^3w$6IpkXQ1ZH=_Y;~qnrr-=FY-R4oO$u9Ye za|N3Tb5pkgkuAQnFbb>B2T=&bBvu4Te6Fx93ccB_>qyV23PH3fU^qc~j*1?W*KE>M zk81f~T@qJBP`3vfY4#x?kSmoyou*NK_SYBia%DobCIU+M1e@hQu#Vqbh~e%)3*&m( zXZ*#)Wua#0a$$VII(Eyn%D%!b7S=q}1g(k>eYDhpGmaG-K6iQuMCTa2$QB;kWDvn` z4??{C?PI?-JD`2S^+K2F>~m!q(qlD5Kt4~tan zW(rp3RH?Ln&YmY8Mg4Xf`CbJCYUS|$cUa05o2~Z669fHmT;myXpH2zUI%~uS zl6Q^!7PzyVYbdA@GzYyzI8GBoD5lQwK)*n(KIXIRcEEw7O%ju*NXkorg#*~@%@tf2cWZ1maS6L#$md}l9Fd{Gd-8J z?tmQJ)`QH%hYHGfxf*KLp!#dm=Sjus?T`xHscb;zdHARw;)(EWq)`q29C^6=ho#;C;Xa)^& zEStRa2~Fo`X-GnGe;^Bb)|jcE;5v(d%4-DZ-YBe0gYk_hfo@6L|BJ^1Fc zjSgg91QEFwb%{w36+i*Pd-;aP+vkKcm3apAPg*u+TxKLe>}YEB9Q?37F+Vks5S$C} zBF|}bU&hkdL@XV*;-os~+>H8wKC{M%48`}MWIieVC{VQiRK{3hlA}z~`G;|fFJNiL z8@hmi%*kp87-1}~PYPm1g%ZPsNs{e6ohAHVr;jmW2sECT%CNnb%Z6K;)hDliJVjz* zJZgnx*I_nY3Y;(=^DC0N|5djk#2?#=@=Tx zk?xKGhJn5Q_t|~+6)%UGd++alY&ognqJ0bOdYk-BJ<9qTPGto8*kiQ1Q`HI583YB$PF!9kQrsf1q*BMA`Ii+~8jGJCVg z^2Lgd97ox^R^D>xUV5}(^VRTkNg@CJ&PI+s#r&9jY?rFm*Qx6$<8ab3Na8cn9(h9|VwZL$~IC}H+n#Cj=xb`5tcQpHz2ZR$`5J%l?Si{XXmtJ)XAByTp=TUQ-( z^y(Jvg>YMo3KxCFXydEiz_2cxZeD=EU2DF_nM8WI(q9R`*n`jgxtn#m;QpA@9M1EZ zmhc@#2mU|;>j9*IvyfA1g3jmWM!-9(nWK6khHh{S0p88=`S?}mu~Km0!^(;--LTL? zVDnbLf$&NV5=!`LlWwEw!@kj}hjC7ukf-)kfd@9fPIZXrr>H zjlHo^S^mYis{hoW+$h@jdaB)6xy|th{Ev)73pBxqre%jpg(?Ta zLsN*F?X%>u6b?h`MK@QtFhTS{5wEGKG+YA7lgv&r=Ye#jTcKjr&|}d(A@kLz+4ISc z`_zcSKmw$QJVKul>~L*;MX1GxDKVoWL_v+C5Oc{&2U_ASLKCmLvT;7cxqGWVw}We* zT6Nk;t$R0ARY_=Q)WCv92jjX28eQyt?d9ARfv(~{A{f>NO94Jbb-IXjlo$YT@e-wd zT)45iunH#2-ikD!rT%-}&P$(^dmeL);v4NJd^y(jO8a}&x4S$JY<%Y-xfuH5G3k=_ z%k0w_)u6HGw#TV@wq+axe>86Nhr87-rlX?Wb1@a3rtmuBO9ML`A?e((VQd(86LkRL z$QOe>@V+Spn(Dm_`>DaJIHhuPEDMkfgu zcqi=0ohGf&oDu(P@K-ayV0ach9r0TXiy^UUl9*n#;y6JOIO(2Y%ZBg#Ni;t&AKk*v zk5TpKM*X12(7`T~%9VUvzqCxcH`6K8cUZyw;~h?%TYyZ;FzZ0i7R7RVCsC1nydbX@ z*;G^yut_VkJUvY*UWI-|QVM4om8pv4U$y^&MoCPobdV+sV*h2;jJ1?dKHksA-cNr+pnoF0Do*PiTHK(%M?WqFINpV*`G`(%Q%$lN(JY6xnUYn)4QS z7O0@E7GQ{pYpF8%RJ$tC1t8I|(_USun6Gk~Qg}seM#WxqTY=$sf*7Z}nZ@(JTIH33 zhGUdYP0-M?{9^ppS5%a1E)3LWxeIta7RuG6GRs8?(Eu@ z_o&sL=jzd`_v_j`T(J+O@E5nH(eWDj@M||bIA}iX?cW|jtM0c(R$><;#F{za>v?^l zQX`F@g^JkWjvy%Y7@2w1O?1GO&eRIOOC8#dQ#oPQGeHJgresLf(ogDom7;}d!(Q^E_Fss)V@+%LSI$EI zxRG^$($aTqlt_O(_Xe(J+$taocr93cOPZKkimRBgz=+9t8}Vb#c&fy#J) z(QDPjn7pNi^)aYi+8yT6-0;uKPEI%@-;0`w?tozIkTK7tCC|9CtGGEyA9wi4%vXd| z5;EW5~YIdYv@=<3xOGQr7$4{h}t|z4N><@6$a}LI4?aarob9K7vyTh2Rjrbxn!8 z6%frN7rr~39x+bhZ2X{moM3T1D>f?G+=mS&1qRYj*p^F5mN_sH5 z0w<6t@0YTRal<@gC^{+up|Cttlqc%#Ou`1Ey`}+OKDxD&{?>gmLhTE~43}U)@5S{_ zwnQfz*|)xDfrWR!XE}tf`i?h>=t?4yU)FH)-&;d@&0b=eIMBynO-=`#7B(y0nT;V) z=b1R@OeXF#KD}t_Y2AUZG=0mk7zXq3EYdDWyj~?j#OBt6!6fORvmw> zLba{aZGoSiZy|Z{Nd4jn}4~?I=RP$*LLG?`>R5d3-5f_^y4Z4(dk{RvvdqegFHL}XXtw?(rhg0A$^wjk4$ zGXI(+C2aom-YhG*b)RWTJ+cF+`-AdrL^*c#^EFgNE=Zn~;v z)`Ic91J7(8bBycyg-}Yu`{n()h+(+Zqxbk?cw-qmbkr)-z4lO05vRc_F~Txo|6W+| z$zG&FS<7(cFmuf6+Mzs5)S9_J=0g?ClRNI~8U(>z0oSO6icwJyss0|CK9$hvI{0jV zjOw~g{N#gj1>*|*)QCv1v`gmTiG+>${bYvSjX&h&gwuJL4v{`RmCD zv}R6mFz?T;i*U1Zt^Umg)+ z?dVhf6Z+hS8uiCU+sSpYO=5U&@ck7_{m)vb zwAt@7l{Q~pZ+&u~J}`pYPCmqqKhg)Z?&bjeOQ`Ajpg+9L$W8%s-2*_1;(feqv}-)J zz4*=`>b}Wpzu&e5@@;ipW~0v70WI$pf={l68mWlwmx(%dT4D$8k9&4H9Sgh4l8C9? z0>%aq`$-K{82FSVai92ItDSj+7HDCIH*KHM?FuUyvKx{6_^9V%F+Jc~UA!mr{%b0M zf{3LRc#YD@(>G$z+}I?RdNup)>U>03c)4-xlr$KDTb*fDa0#1T>JPJ^ z+C={>Z}!39OFQWRB0l0prbDX(rvu(+>}cz@mCW&_vCx<0;^msl&0x%k&%o|E7Igcy z`DuZn^sujoo2m5n{=Zqx&m6bhwwtMr^fd3;E#HT1KV^_rhG^hiwl9!ldH1&niZHE} zAG=iJy&$`hmJ=L$lT>)Tj7ON9_4_am)C-`3qsh_?0(l(x2f5uLk>da|x_!ro}u%`#G5CJ-#z%#P9X$AE{5*8ZQ==b!E;!=3{S`SYcGY}KL%lD-u^GG{T{{lEkdWxd zQ#K*qBG+Z~;%R7Lg*f?m)-Gf2t}m+&6Kz}lb$5!Sef`M_ve_$!MxVU?9=OR}-!7}0 zZTX2G@(y)90k3!0(pDAjvai!0J{7tz%jW`?!!#Z%LG3&LWnVm(FP=iD|3?yajGXmy z_lOtk>o@#_a<#fYV?6+eA_;Uy^SBED=&r^E8HV&wS{sM#_ZHy zj~&vNl?HzGD)23A^0w^cuvhedXCjQ=?kKm%vfk);5V2c_X0X$8H3KtD53zYSFAn`N zGYva@Q08`Lw}KC3ZkoNMB(CxPzC8(l_jwDBUX$dQR?WZx$#TN_)y{Zc1Fi@naT<^W zkMpU-eQdCgjOHE>JXH+rSh6ku?swZq^S#|bx1@UFm7GnyCO=X0F1+qh(J~iIGG5Ok z`HU)i>mjpLNIM^Ph4?P~$h)V=^~b*1@7~vh__?jIIRC2KYe?29d9%mWOIA_D{_^kU z#<;2nQ7Ekb)B1j@ZEwyw;9{LN{vSXPg&__MIjduUMBiqjTo_4B(t&=*|F-Yd#zrq& zuy3J!|FUjzl7Axh+aPn~G)VN=@w>eh&}Qt9-?#q&u7P2b+Y_3N(iW&MDK-D7NiDRY zb^Rj$$7&g}twsq|5R|~8HH#00hmq!ppCV}b;T6^^8SkyQCWKjkW=#UzL^5d0SuZ|h zl&q`okD(`m!M50C&eoW`LfzC9(HU&;syi);;++pr23`19A5hrm73eCk_F*(s_kQmz zo5-t3xF6D``>9P6+w;I&`?kEJ;#R?)xjHSyk{rQ}z#w4QGki%oZ*d-fUsxC7rFp|v zJ~Qh@9VGCXzYfT5wrA~#z5B7ZsH3^{_h8}|r7nq@P50Be9L4kh(E{Xl2nWHMs4p?s z!oL!+s^~Q`FBSE7J~y-BNNI>tpuYim(-FBIE315XF46C+XS)qp)4qlq}Q?`{D?t5z4(0vHI z-~OedXr|};d&xwx=4Ru&kyNV*fz8!9BV3)i?0!mjSl7BTwke8eXi;^L@a10uhC+9I)lhgns9_VGK(jEOl}_MvgU3CCWCc zKuE$1*^QzXHX1>!z@Ja(N>%l%YuqfAZHUBCpT<5s7!x2~w@+vUHifR10DuHcozc#P zr(wN_$%8^d%;SXO)_G`H3dsU(oGXrod=Xkq^K@Tr%m%?X$x}l}QD3Ca zJrexkNl(_&E7QY0h&zHF9QVK46OHrTdQ;vjsxr^&;2fPUE3&a(JlU~a->}G~m2KOA zGc7bBj4T$ozGV00y2I+|qpJ1-{+1_*;5eH|9|8lE*CjC~q z;f)+~@M2&8=>S74=2kxg=pZ>!NF=ekr>Eq+0rVCOJiK zz`By0T~DpD^}v=l!n5;|YL3ehz`0flvQShN=lG8Sk(`%DZE$w>i$E9?R0}v zY8B@GPg80sc2!=3AMP;lcc@19|1@N8Ue7=?3ML{A5&m9O!tCRGihaM@l1hh6!YaIo zuX+705_1jwto<-efL;MR<;(6hT2rWvz67Szanmx<$c+2L`5;NnY%YoFR{9oa;Z@KS zkR;ZKgu-qvnUQMXGAvBBAN#D|$(#4j?x(nQ8_o8V3aBkkHeR#rCN#Szf7U9?nQPDP-UM1{t##{;pEIK?7I@IR3Hp$L zX2xmJ1=0JhgExL#KiD(TLvpi^6 zYw9^uYV_t0tGiLgKSUO0{sDKAKn1M4?dw)$TzPE>Ts?-aSHYR3gAYRHi!WY6y6o^E&ETQ7f!AKVwl zVU|Lb6W#lOpOyUtox24-_6U25BGIYZ@)XMtj%9#)sRC%oB6gT=`pz;&P8(*vhq#3T zKn-=1iB?pWZp&$s7^-*}c#=hRhuY_^i1Ap%sCCNZA`_jMn|f1PDh54I4BRa8ZEx?n zBM5N>a2qR1+yDGC3I z2jA1E>2suT{x~j7g6AZE{{WHAR{t2f<0wA^SZZt}k>cV@CJRqd#2)b)#5P{UrG0)N zov&wdHsXbL?G-#RE<98BThVe$<`iMUh)0sFHJsG%sP-KK6*Q z;+encK4P~|eTvH9$7Y^$M~=_IY^r+$DmSMBvHuVH@8g| ze!y+tI|ILkHV57`mEH7qjUXu#wl#a$<<9vQ7te!3R_~tVIe>YSAm`ZQH1&oM?MzUh zrDftcGC^K*?0H`GfNEuC0*3*luJOp5xHaKcXv;KLxEDk0VAh5ICO>J;-30gI_IEva z{e-upU*}%B!M~I3-vQ^4k~1v4iWn|_$bK)n9!g{hOjWwlmsd}2-2Wmu5q?vYkw4ui)Y&$z(M2D81BNbZQaDU z!?>-4lDlIY8}$CJ@B}7egBzIb)OHHobNSp)cex8=BA4lysk=mZDcoffTX(y;#zt!- z9PoWzytyHkt-F|W6HzY-a^k=?7*@5uE7F+1z8T&2uE_4vl6|ZierOR2`;jqstm2RiEaXj zq4c|B#{f~+B^#>Bv;_{1NNT?c#rO7R3x=MR*Gs@I7<)|Y@jNb58?=gedVuUEW3CDP zIowjp33x0WZDX%s_nba`T-)(r`~OwNIEIo#+ZEEpygt-^Kk@*Rw1u#0>)f?PdP3*o zWt{Ly3yOfmM@dj6zsd<6J7l5rW)3AXa2wy>$tH;58rzF%n`y)h4VQ`ynaMR{;bY*( zz&RUT7)tK>8c^7(lpBaKW@m$TEH0>wq)aXfqB{*0jLB9+9`w_w($IndYzEw&i)`-- z*MyW~!sdi{$^Y>(SA4SzpjTB$HVO)$TwRO_%@&GG0J-eCo7p!!FrLzW=w*)QoV@uV zX1hSF=&_B1ovAN?TQyx}r+okQeY-=fmnT&`r)Ozo(5HM0!Nm3=K+#1yQa;${bv>s& zS9Zoy)$(Ph8#PyG&wEo)meN@#Y>U0?;Q~cpLLYOh>7B`7->#tYM^x+XJSpv+jcx^X z)TO(kkF(`Q*S{{}mlf%bFCkA#L7?uFyb!!!SKlfiR$`aw>DuiZLl^NQT}QZ?tmSe- z_bm?>G@s?N)e;g^mA@6LP}_y~!-2c}UGI0T6;!1HcW_H!W0qV*hVMincGl>zn_jjy zJYFh?w|dC`AoLN4Ml9Q7#Z2Bjaq%)QLlRPV zR|o!5Ex2dPpKdLVUY1sJrwc_siXJ?k%s#GS!ZUrP508CxFM;nV)(BJXfs00XEOANf z1!7JKFHeh!X^78uoG50?<*5HvpD@KvQu)>QlVt)xHERndPNVn^*2h3@$zLGHBM1RI z0zi1ja=FB}2a5|vmF-4S*YBpMp8JG1;9$lSA>FpQ51Uq`V7Pc`=|?nV8_)AKijW>E z{qJ4Pe>g31__ZE3geQRP?Pmei_Vw#do_LECsuz&tu>67%a!P!@XLWTbUg9GM*A*T} zg4wi{+`dv}VOQTJ0o$aTbe_T)}@$zBTxGuWUK$K3+>KZ?@}?|LAKTwM*k*YGVZcd552O>Z`Bxr<$68A zq1s^3rm{4<5r6C`wctA72VkNKv^&&Wi`Sl}DN>Oe)j2|R{HI6w*D3@Lmt=1ww4M5N zJfDD27JzF>qha!oOJ5w8#v@u>UyHhvJ68CO>V&S6w#~i&--E!U?pg`k)v*nBE!3SP z4CYLBTwA@l>l8E+ymB)n_yn&wN~G*<65HT`)RpuF8nx{p8y8yBLH4`EX{-GFmlIs* z?0&%5*$KwTWLL%aFSoZdNyaSw5)K9J1%H{^@iuoFPTf|`AMSN19naaUb&2@q3a)8- z@z^;T##BT2T|ZOr%zNr>+7KFtVLHC!x^0a&<=>&K!tvu%z`#!onzQ` zy=g5fHs$hIN(kA!wbcVR_6jC0pDteS7`;u(#H17E^)qDpxYkJg!L$1p4l{eYu342$p|ayoC!Udg0+Wwaa1Jhc*vleTAG=*aYdrzb6T{ z`irCv;~sef4f4Q>j0slRK*Vf~XowTp%@2 zL(th#HVi%6j;gZ2LoFHkcu_ZZ(r@<8SgBsQ@~i5lM-uMM9S1pZeX|^gOJ5p}nsRYn z&~wf6+CM*(_uZyy9scBkRN<68OutZQ<#OKY!0wKttr>5M#)_{ZcDMCfqO@)M$Gh}P z$0rZd!-jRX$9IFs^A$0#@!GDbf7sZj zT8-F&-GRu}A|%JSkvSXfG&kzhxH~E%ZNywn(|*DRPYMYC&Ec;0JGQfOaLruSLcReM zrjtPlqhhG(%C$aSo`)30EAu6p4tz;$NLBwT0xkPRHTa*dLCR!Z@4L~qhd-I>My^p8 zhj~Rxb5UET;acCt?&szfNA%W-B8Y+C88M>W$#ppfz-qtvdj^JnxqU}_wVz*3S#$Z` zFo(yw$;qsQyevMjYVf+YtISC4M#!;jn&W_WohS8V;_8HZFV1bqqWAjuG7u^ z{_Ft~;;5dE(Y1i){L*HPDn>}&P?p@hjOww>whsY8Ab60v4MOREYx>!WtMN^Qmyo*c zF2MV;pEI1@rO=6C5j}qS(oZ|ouu?U*eDyXy;=zKsJL@+d^5I++{VovRChoeOoXY-2 zPM-zdgYU087aya33TYI6Atu{rWA(GCP$+?{**H6|ODpjmSwrfszM{Jj;7w+P6t=cP{kWhdnUM`*_>AY-uAu66g9vZ5UDo^JzBNR#lQ8IORH}uM0K64v+%iR0a zP)fz)TCTtPE9Rxi@bGmLamp#m*;@7QlwZ#bKRkh}lmtlTiMPx$5UIX>AGJ99a-_L(SRPnNqzpCIgYbZh;wDl5!heb)mRa^>Lef5{6M z7Yyyyy1~DQZbA!czxVb2vPVbp{q+Uo-uiH=gsOb0n=uC@d8~1=59ul%O$iSl{^{$P z&xQM(Wudqh#biyaFu+*2^YIb(B&LA>DPa(YDnMjc53ihGi8GPYkBVObqZz92*zw$w z8em;QMivz@>@_R#{ih<8MGX&$9XFY%VUG5ebEEeA^jv9KGgYLb`Q`p*VMBi(ZX4sxE%ir`BJL)$eT1!)D2H8Ag zt0}888-WTuGcjY4pH9vBQ3Fdlo2J+{lxgj^8;b^Pyj8$Tp3a9icYK-&r88&v8#>2mL;XN5Ljbl+~8vP&#eLPg*ub zcaSSg8>UOk+n4XJ4x52CLQB6=f`Q$8#PqsH!SpHp^3Y;d16mC;PkE%|dy`{&q>ts~{d6S{#w(Fs58EDe67ud*@=UPVNl7M^|mL z-E8}&%yxZ(^94-K><=Yv0F(`KP1I4qq7#V9`ZlR#lst&asIG~S!>B|T<>f44Ku}z6YJQ14P zZpHO#CDxgOOH&ijmO@6#amb}O1HEh{GzEtLh7|)K-YHpZ@{<+ZLWea zzde2*b}^Ze6hhj0h90s)B{?Z{usjj11hR;me1Yt9RO^@q-iV@k8QZUKS(U?{jGaw^ zgWv9Tsa_bTq3ksy5-7y>-W@Q&kU+T-Ixn*o5B#|%b&i>(HZ*dD9CKu+gwN?)o1g>m zLK;NP(wHs(Qb|Nngs@X!GgEaZa^4^RR&zg~$^CV`v#$D0+@)L8+Q2$`W9Fpk(g|we z!FsCeri`(_aTU(rZkm$Xr9o}=w_m`^sHi>uC6Eo00q?a-@bm`Z#-~T<%zIA zpDs$mxrhsra`@)Yadh+q{1jllW>6&c_0O&<(XO*zoC7Mc!NQvr>ivsr07Lxq(ShbD zh?pwMS)ELrc4OSp-*xyk7jgAJ4rqGXAtj_}!fAe&#h9}*z<9~xXzJP__h~S|w_HMo zA}|kKge+wF(mkz@W;Yua={1!Mid&7dJd%ZS56gk}6^+#oVcDk!B8oVtRTBm`OP6m# zf(V&KTRn@NL#*>m&s(@PZl-}&TgRevAvGF4RlE;H9=Epbj7-Nd)fYClY)?#!%Q56U2 zaG!;$HnF-^{0&FLlNeG%M?T?s*2(h=Z-#|z=_Es|B&uJ2*&e<|?Eu90CBYq#-Kf=t zif+)3rba?qBk>c%`o%LrLuK40^M=D$DWjJG2y4+2AhsJ<_3bmxcBARCHfF~ct^|J* z=bv$-swHunhR7i+`bf&X;p(N+YDK(2p#$Z@+TUQ@@jNryyEJ~>ejs$KJuAFzC@$jA z=SYX-z*lyYkY*A6?Nh|_A;8rx1A;eF9(S3e7lz&z}(5#H43;UMrib17;2UvzGO zVHz>2pT4m-kC7JRbc*UeR@{fj5wF?~Lm3EU*p~d}{b-Dsld`I;b1e^B|5aY4hfVlK zm)-5YfV86qDa-2Z*hc~N?__EqYFhu5O=^CU3LU9nj7@C*XQpcJfy6XNEaSj**{LNe zU{cBJVAjL{jDchB+iD_r)0zd{i9kxswsPsq&q)Lz`h1P}C;Z<7U){-c z-Hlh{e3V}FU}c3=O|pC62*25Lul6xy7APGjN|1bY+fSiaShWCeduROBKuk4s4{-t% z0~R;=C^|cXZ9}%QrJJ|x!Me{b0M%mky_jC{?UntmUvnuYm79r|eSNA|bw>>Bcm3pR z^fLcn?)bU=A$Up&^{i7){TtR-*03s)^^s;8;>BTkMGS62(B$SyH^8SfkCZI>oT+~YV$S(u@QA@p^&`H z5~&M*B^MuMflC~(|L-@{M&U%{Edb;HdGe3T1)Eru#B(K&A0ZQqArmIgtX`}{K-&0* zpllrJr%O2A5y}T=G7A-EsfH)I0~yyvGh|T%an)nHZ1ujazB$8wmRfpG)Ko-(_$m<_ z)L>}d&|rr3+ID#N88h{-P#IR-5-8wjvqeV9y12{LSSuQ@6HI!JA`V2S{elVxzrNMg z2z3js$|d`8_VwlE&%1g`S*KQ#3As#`buX6^mv&UdTn91oLfRHK`y;^7OW zPGuZ2S?fDzz3(``R;?8Q&%e#cC7D`5i~kN_z1%|S%*T(AV)`7j z(>9M~7K82T!{5KDi`;&`SECABc6`b(3*}RJgIwI)1kvqCvcNnz(ab-;;kf~*$Ynxg z>sOh%)}1tBWQ3co18s+hz+zZaj=agV@WyzQCkoQO&lm~=RtbrchpS=bIq2JFm|U9hTBHha0?)CC=6ydyeb02yWC39`NA|yxVnR;5z<`@@!HG_p6%G6u zmtaPxjNgKYe6pPh!fyajZo36Dc@EB1nrrDhv8CFEfk`+-H6sG!E*Ex^UK``bADe6!XcyIKTT9^6-&k|;0U_u}H zEqAW_Ku?vll*lmotHLLM+2l|ebUkLu?S_=(5%p_XQHD~wb=6~;f4%M4*7pXv`%U44 zp|Q7FZ7R*fU-)R?EcQa%iE|uPCgq~Nol>_+Lyix*XPExjj{7HXNZ`!ijeF5(x_1h(T$%QMjVFVaxHE5PVWKL3)Zy=*hA3omZg# zVs7Fx4bu0TKw;2_yuBlW6m{iyF^a5XZRa1M=7F5NqLw&3xB9`m{uM~Zfv=3V>HFY& z*gBki-h-V;XW)QU_tde2X#AJ)*w0aE3oL&8$a)Fn*;eRop3Kt|ZK+?jJBQv!V=5 z;viqdOvEkX8_RCDk0=9$3o1^>qg!v$f6w94YQQzw#4-DZYet#3@QH8nD=jL`^-oz+ z!@{y{jKt;f;Nj;UOI;XWL%_qS{qCY*K|@E~aipHR!{jUBx1 zNGq<;Bhl{C$z3LnVeUoGY9fmFHgximf@=(Gm6UJg(l)mep*m4qrI^B!M$Ib+N#ASq zkxDdH()7ReBajmdMLrG4sd{VSFmxF2MHZ7glCAd$VVZCNZmg$8U6w2EZTa=}jq3wX z1rz}QHQZHQTXPWh_CDfAIL-*~NU-NL#NV^ngD*qysAe|>>8N|F6oV1D@5~Qk9+LoK z0A9?A-Q8~qLf2Y5PSB{rx<@cWSM8`mKZkvJ_Qftb70Yq05~*Oz_x@EJ7d4FEZhUlP zQ*rVl4^xToW=BwIuK*`FVUCK!#up3f9p2@hT}G|yTHFx$4X_7QAic?xNOz;l19xDe zP4YlSfC}jIK$1b5|KrzC51+FmFhsPXUGBU9PTh})b@cUnod)DKUq?YeVJkF?yMi(7 zhuBI9Ki13Hu1)Gu$j+5ybdeH88ZUdc_@1Zv!bLbDpU7P1jed^#n6>-Cm!Va7#(M+a zmp55nJLL5~u$B+~r~y`iNPRim{;81jHYt0NFYThGSuQT;&+vbUZbs6P`YPMxx1CXO z1Xq(WYzj%aV>$`N=__Yr=tSfUQA%JwtE*0;W`BJaFG{~z@uQ1#4T+!*m!==d!S3eT zb^7dkyce#6PnqJY9BUP+xCAWPEa`x zLmArKmx@wl>Ku+~91TQr*Bq;dra*OmG7djRk^QoJz#d-flno6Lt`QC2Sp}74rq+>I zPIIj`r0oVqk6qVH+^ESF!#jYqn984)ut)nrvK2ecgXa|=_>mIL!x{%qo7-0HSu%=* zkUOlOhLs22+-o`qU-qu)EACSbAS?L;bbq6rZVGVPYz}2_R^pFCfSl1SC>v?@9kmd6 zp!{mZaMuHeeb>Agy7XM1L$58&pG4hIGEPce$lKa4l*8R+$U|;6qMr)qXK&AW{DI{* zYA%~YmVuk`fTR5+3wh&R6o?@Vys&&eEKSgh7RrNyhq|^a2CIB7_25zjQvEVFIQkN@ z1-!+Kg84`iAuld+H9E}=rYgKc53PvBEP`JEyZF=~lPmJS`=RG-g2o_K*W>K8t(0AMxel(BY(*;p+#;!E~1^o#If%WRbiu9SCVsV zn99baer}@v4oLtUmW9+>;`WCpGi~6aAs12)S`m1Ol0?4&OSzzEy=8eY*2s9yhaN z@b&ovYtx^0m!h1r&_R3`_kycu_Nk~EkKxoei@WmIh9IWF4| z1uYcLTtw+oJCDQ@f~F&9)Z`-qMWzgZ0$R0Szh{7EUC%|-q+#)umFv===wfNM;kcTL_qB#r1#QXK^55GxWM?jVp zVI|iV3dz(oIgm1jAq*)J5vSH!UmP+S5yoilAW}zLkM{lY` zimzLHq9!>~q!kCI(-F~Hq&8RkW(}UxL^m!Vc;q5u*HtumUSt08PeAT)xy4W#&EKc2 zT@fpjc(Ow4m^v9mJc5IR9P$=ONJU|23$eGGzidTyfc=_pR4|W>L9)Tcy#FeYmc_l% z>uFxhVzMOa=yzCFOw^u>TT|NZxi(dT@*Jl0J>|zu|NR~A(~_r;m9JX@H`9)-O8D^5 zopK(pLaH1xo!tuX8jkOpO<)su$t;feO3i(ygrS78MM+v_kT5MXpAi#_+ehTK66M3N zt>n)H{Y?Jnbcx5Ex8cTnI>@R6vi-Da1eHhO z0)HDPl0{dPpNkGbUAy|>2d5FimmX%KF{5`1-*%!{{0-=kOj$;<86)~ZfYhsWp0cnm z{zbfK@3*eUYjzwF?_5QJAA=}?A0EEx`720@B@xnLHhiHTK$UEOy5M`^CZOH{;ticU zzTtEpm6TV3v*MJ&cU$ijI%T-K&C&!cSWv#U=fY`_A}x*!K-S>V^%OsMLvc^Z@UWVi^LM~VCK#m><)Aq9^WslEY8i%J=Aoc>2jOaXVp+A>~b=f=rN+qE^Y^?uyJ& z+8qa-0%<3TF}kCm7YRXKN5W0^13?OGR!3MhlvInby7-!0GSqZ&Bvhas~g7vpHEY9 z;52Sj{Jx(OrQN^tPCW^~VPS3`bE(bEkqb+R;Mwh9ziFj>T0);ni;m4;&B9b?pKewH| zsr~81k?c-a9lH<*D?w*(LzXgzQ>CJ<`)^lMYg}DI$UEE5%=2IjBHt}P5}X1ZFzIRj zFrWa~wU~rcLI31ZzT4l$<@!1FtPZ(y3VkGgIQ@4yU?8u@7AZIe^pD{7N<(k~DoZuF z_5DqAmoBrDdAJ|)0aae@32vs#WE5k$S#{MuR} zGED!K-B{4n4%v)0kQVHNO*Y8A+qNU=Pr;9%y$&IrB-2wltC?BZGzUDZh$F7hGwhC@ zp(}8f@c>E4OFxfKZ&Q+gaGHM!oYcMW8rHW%C|DWfXUV%Wq<(GQMUqqXPim7QBqIx=cZ=cxn+K6b(?T~ZfurNE zPM7q?#CArLlNh5MR<}4QhajH09_ny?um1eNeVv#P{*+rOc#hN@S?JR-dBTq%MjtDD zk!VjHhdfcVBApgAY8ljc9k~jEQu%FsKVTxXR0+=vj7i)t=w6t={V%P_ClWYRzNglvO*?bvA?QLsl?fJAl^YTA96 ziLCDGd}?0NU!BGIbkFX4cL|HbFAh-)Yne0>J$A$OlFs`2UbQz`>K&qQIlP`Ry*}-U zP-a8fzWMRGUQE7*(R^&!lyUQ1(BJ%eRL!g%sd@MiH?Uc&!WNSj$;in3%6W{lnmjaK z7~*4vRmcrz7BN>MF7>OY*^{y+K1K!(g0s@CN!<8&f_MW_cS3Dli#aaMN?9>koOzsa zv?J-V0&cr(RX?AN?1I{o$I+gIA%O;mv3Z)@AuDtN#_S#Cck#739!oZjV(kXqx;_bM zudfWa5*VM7t9`wKjw2};G za&vKJHl1ge%=)}H-m2YVFD*6Ng(0AVJsw$N*pVB<6x42+{aLYlL7A^qK~l2XdL_V+ zZ9N0k8^zkozCw7D@R=HSW95_}+n9YNXt;d_VI8j&iAw@Tu9`%mKoxt)8zfhz2A91Y4V%FKM})nfmN3&4%%FN zZXcn#^hB=r3N&p~PH&snt6qAtV`bqfeUA%e|wlISP2(#beTdjt+l}3UkVCnkb6? z@>bRB0(7!OVAA}kpVHlYlY=kvM}->Q$ILis?aY5H(j;txsjn%o79oQwf+o*!ilzoj zcS`r^fL)R!$T`eNb%`6ZN&>AbrEb7%!RhquysJMc#*$d&imDc>2J zT4#C}LP?j@NXQgl=G7?F^TC0#^23hdh|}VK@pM*EQMPRxrlh5$yF)spOF+7jZUHIj zZjcn|p(KU|k!~1<)}gx_q`Mhl9Qfzm`2LOAX4ZOG&pr2b9p`bX1x+t>+(=Jeg+A6q zRRxP1a7_wuS~@hlZIv-&X{Fq`_k@gWv;+Y<1Zbyp9ZZ)gVA~djf25arZG?KJR3$8K z=b{}hbiK1Dcc$CO_NPfV4v-5^sd?g+f|e(EJLjZvtENAPE-Xl^n}WD1D#i(AI_T(H z+0L6Z??(^7QQNCL^L8*3d<@5_MyRPgY~9lGqIa-+vtl_orXZ0HzNB?yCs}G{)bmko zpN=9il-;Cv{HEH@(;>pZOBU7K_S0;!3KDaE#@g&~CO3x84;3=d8QGDN+H&lan{9Sj z#YaQG7kJi$b!;EjY3TUGRN|d7O_%R;Hx# zJJof=AlLPA{A7igyT@WcM3`}bUD)bCjkH%CG^o2pIg8g~%Ks*oaT8GhKbV7;U;Z?=d_J zfnYTx#*3mppMnKD5?@ytSBv9FzA{y6$J9IP>>(D5xA z88#+YuMML3LZ^K%V~LhFuwV};TlnWq;~qTmtDfu(4)?2f3f{jq-^5DYmo|JJUpW^f z>c0zkdjlmghlLt;&yp6sxsjGxUtPdA%?uN!IMpBy!v;VP7VG4X?V;-$nO8q| zo4^IdZYTJy(N!>;QIlPIB{28dbFCj!RWnl9}-y;9!-FOAAqYloZOJ-6^qk56i2;J-<7m&R&Ap|MPv>#)S*3kv&tr)LXSe%|=3mZKYos!5Y>N<~9y zx4j*A+VwB*X_{GwhooPkT1_cL%oGtM4R1dNz}Dzcv}11P*1edxNGho6{w#i1y|zRs zC2x4)Z^i`!7!vY!cZxSp(y6Gz#jX{Ty$*KwqxpIE>%7ipuHuqrF~IRa<`|CiW3&G1 z{$)MP0?%b=m=MLTb97ofLV@Vx2y5aV|jD+8{UGex_p_e*{X`Ec)$ zGg*g2Nj@kun_!*y>GXvggKu~1YARurLcP!1+8n9Ka=kZb?|4Mz&Hb4r*w`g2!_m=s z2Ff};?$h!j!bV%*o43tTWZ2QfVJ`G`j1$B#t|6{}ZE-MTDa^a0N%>7E&-Wr)U!QAx zIcZy31>MY0z;?yY%n%l4K9o(e{1QD9PK}q@s!bmdAO$eT$dlTCEu?ZAHP#NYMnr7x z!mcjU*JLn4NMR$JLeN;2bNA6wROj!Dx6U~O3bRp9dX{x{=}18xKRu^*>&APeEoo~U zL33OdB6wOY6&r&gSy}uR3!$2l2Y}B+a@%Lm-x&`Vyb&=_d^{EI+82%Qc)B(|(Scrd z5;&};zjM-FUz3A$Syr{|NM0;2DK(F;B+i<2M~Yq@0rTH%00O0;Cws5oY;ZI2mSO~U zPM&?ck@36mSP;L1WiHxCCS)>U5!{ryOTnVI% z(F;wAgO5)d=I99~qkBae-MGE>#*@)g!9ANdjj+z~x!aj6n&~^$G>w&lHNmmfgA2(8 zJV-OFV02TD=om8dE~LAY$I;G+B`eyWX>j;qFI8f8WQi2NTG{Q~r?qZIHi$>iKTDU# zlbN9Jb;oiE`N31S(Y_=tCrY(IDD67&DIUM5j)RnWNj1!R@>mu6rB&U5{^hd{u3Bq> zf-OXOY83Ee&hV}rbEOU+WMj^2%RMN?%i?A7-noW`Rwa4EkvJ{5@BZUPz1$;r4R_Q= zbWMWFx46AMF^l;0Wn)aZj@iNx)>s~6S0$y8S5Sj-K#ie-bc+w49*FIvD46((p2>(qimSEpD_245h8w3T3f`#>UT;EYoqnl~6-Ro3`=LfaGF$<`DGte_)Feru zcEasiwUiXB!BehmlV0E3lrGpcruI$s38$sts~lbQmUYRsbFd1)Ej`hLv<0^@dY#>v z-*&hB7W8%&pVtUXwofR*Xif(_;{Y1`Y7UA!S}TW2eWym(H9gkP?v3_~lG+g0<+_?i zEKQ9K0@`rWIF2(=lFaFRbDh-#)(qAFq@{!~uchyL3@I#=ziZO1-FdQbz7Vc+%s!0)>4uvZ zZGdU^MrDq}?J;z*F4tDBE$9j?(?@N>Frfy3@BtFb7H^@!2AZ*0-$C&8O&@ z9GKiKMvuv{Mn%!ycXrF=2dnTv+p2395U~0^-_htLW_JD1*-opq{YQw$QYkOA$z8|j) zMO0{5{>0B4bTahXO3ITfRian`sNS|QvXQiS=FW+`5%q0sfhEJ zb=G06i}Mlx<)bHOp}C@SkNvB)rrRjoTq()^BU@HF#k{Gu7XcjZS%qC$#*hg@C67ViAgg z2N1)d+Xq{{#iT1SA3j3Mq@8t@We24&@siQ0eCSq7@?mRe(}D(L@PUX1IR zVI4doYE6?legM*VXU9l>`tJ+k1OM|un$V*smbN|gKdK@>ht;8q&U!zB_+O)+RIobO z-d{_PO3rtHPaElQ#Z3cRYjwn}x(+|^{*-E(*zwlD4&nS*x75=z22CUjpJvO$Jxtg- zvUO5@sMH^7h&Vrt+DkMzaNOM+8HEqIKdN3S`5Mdv`t&vaaBtMkxn2^e{d@d<| zRA3lvvHI*^n9(fhicH(_^AZ&J2N3SKDOQY|XK`R#o%VhwVVDF1(7)F7;ygfX)(ldR zMA(hEi$tnl&fBNv|Cwl+j!O`(zJTFlDDHo*@i_FR?%x7Qhwy@)g-AauVd7WQmY&75 zLI+h3W4}JJh0Y3azhgE@d^gh+5$tW;H5hi|@~X}yLg)J!sZV&=J4=6TA@kNl^z*UH6tuUFJ(3ifzKw#u%q z9`j`1;ORWie#urQFT(lfSHK`-xHnwoL+2UBfDI3K zF)Aga;UGfUS~v(55||5N#0C*!&8GASUyblGP1t5O(e=a{4aIe?o+o@4coETL3m?-K22 z=%eC0^z|neT@>#8hNMuwBk9vTS6RZH^pj-}87Zf~Xf)mkfyjbV7HUO*E%-XVsAX5N z=Ve1b_zuz26zJn%y^eFCejUhc=66)KSt2ORSCp*n4$WU zDgM6=ub`p%9pG&X!7C~jp5V!wSIwo#4r*4wQPXWHgc{QC*T(i@&-46yiQmLwcGK6Y z#}&sN9F(VGPi7}$Th9o)cLQ3-IX0q0LEH(E5hVpMo0i*wWDU5RKLqEZ2%9{V z88!vzu7F~e=(q)=Kly_&-wNH{w-p%VGo41fyLJoCks{CfT1-l56X$bb0Slf{Vf)Cz zAD;PD?|0rJpja+e?sDP%SD8N_9#i=ZEgpA%87nVrVVr!j*o`jkJRigW@wbeSY#v7K zc4#J>sL?1+ZMXAjOKKewnu8{9rVUJkywckyR%pDZ-s_KTNFC~7BqAbHhY@T@bjC2! zhak3{h=?PJ;y1gL&pSHzYnS=(4+k#zH@;eo^3#VR-B))eOghvjK4r3wc5& zfrRG|7@+PrU&n(i)GY7vcM=DA_!&Bf(q1B(HE$5WC<^OJ zo~JGO*1;pbV>`tvsD;SY+b>vrBc2k=PuL8sPB`Ez6r7F{{<$#N$U$iMKNg^Kn-)P+ z&xn~eY`mn8Bs; zq`vQz+)~S8`1evJeUzF9bZ9!?hyK|r??!z9UA#ZF;lXeYllOZ}&gdQ4e(21<8ClF2 zCGB;7RRNWv*(gl*NCco)BAfoFBz#LuhAWi3ip15##jk`?k{33!_T5U7~y@gABq-y&QzbyOT~cohgW6pdi&0%=$ieZD z)-v22f^}5gu=>!vMDHvQVPfH_GzrVoYKhl&EBPDflGmtO+%OcsDY_FcJXpl`W6khzt9g$*k=Uu8$-uz zXw4a*>^hR)pF8pJBuMHRzD(Caab$EcO?du(U|6axnHx|GPa?`RwuIEC(ANWa7#Gkt z69q-z90&+{9j^eI$-W+UiI(XJlaT-K*p%JyJKV~lnY0{#eEO&AFiewZK> zPO7d5Nwv>WDLuj1(sb2vav^k+iWoK#k`?yBi|8C5Nw+zsyOG1!DS^A^e zv7D1qyD9S6DM(R{jC?%7qgA7r>d+EBO|ddy7M{?KclM)TGcv9wZdexd=b~7}*Q?dh zbkSqUx-gw^fHgoov0EvIuW`y*M(WQ-N(6T{t~UL^n4uwY0aotwVi-I$(;$h9FVj`o z*ctDKDE4Wmc!7g9u*+UmXUZUj=e@IeXLqeBd89OCjG2Of@3V`j*%-bNgDFM&Eehzf z5FZNp9mMSgMfihVxYn(PFQ19`L-7sb2%5#%p?ZBUQgeWsX3Gpr;lys|FRnO|`f@h@IG~{|7$?)KCvA;}Iz~wzN(z ze7B~WwDr%XEwOAmIN!9(3LD&@nLAUV>^d1?~lVI@OXtDdH#boXwDr74SW(QQ!4mx+MQcQCKf`!^U^=n3L zV1K|B^;3djxmzzBG=Y$4vA8`=?J^KS`}Tl+sSyGp;Kq*QU6Cg50IA=Y!eWeg3Q z59@XKH6A7N>1A@U_u_^>fHV7F?>Wf&XJ}i4 z0em9$j&M=sBjshGYm_^qmnkYH zjIyapiv%dTPhM5r`{Q%Ia<&YhjF>g>r64m=#_1R`^73CEwJ^CZ#%HD2z3?CW$JZv6 zL8e6E*0z3+O5rydv{8kdwZPt%N&HuZEnoBymg+>Cty>+^&~hM zTw*oL5pD75RAVF>FZ<>hkt}G4oL~VCaP(=H7gF#$%H&RQ)Kj=+@|Wmaso@_Wr95Kr zoJ(D*EA~KO+%?~H^3RQd(VwTI?EiT55-_4RlYa5CjYy8f6R%G#qFST`a6<|(2_6ys zn~{~C7yy((Bm3PzVXH)?X?|K3rlT&Vj`o^$k#mQ zr$<_)K0brgf2O#;cgiu_LsS<{#D5(Ys|r{ZH~u&I5^O<;j@&y+pZB>x3QO_eEnZ)< zSR^4ecQ&=+uFH6LI5Cx6xag0BN69u+3%^;wXYPRz?h1CylTWtYv6RIsl5>9|a2g|-BqWARi45nKk^ zHsi?^rsH02o3C$Xrn3xp5|%A2?2fKU@U{9HS4W8kUbf}M6qFJ(Ibb3o8fmZ1Pt>$m z)V?Y{NO2$&ZqQ`^o9d-{ho}A-j#We*czo~FNmMGkh+}aH?z@@37A$y7C`N9MLQhQe zxI}c_+Yns)%6#YpRm^?zf8g12GhZ~jNg9343ebBh7wKw{Rh09K`gxhI{liQ~Hd7>~ z0-p{ws~GnI@*Gq5WF=s2?9Hrj7z$g6Sk&Y6iJBirL=h=NhFWvr3YWrl$SSK0Y{byKPgN}aVHgr=V9@h zde64WOkE&t0x5KeL6>CeCaHqse=L!*!sHm0Lj z{~V=;kiZFSNPz`_=>&m`SBi;0B;SyHN@>e3tVzxuFw0K}ezscM#c)4p0K0}+{c4B4dA!19BU+FO1E2u#-hbvDj2IqL1u@T4HugLmKkOuPhbYp1<`rG> zXG_F7%K-$@fZsdw6D1CVR6~w!jr@KlHK`9t0?(;X)oZ<=WnCSHXzHxLUHUk<&%Jt> z5?U55s?vX5V3{|nruC5WnwnM&e;$6%sO*BdJ);$o4?EmemyE>0K!hA15^_Vvki@d7VP{Gm&?7<=T76gg6MLjQYq ztiGU%e;8q-76ia3)cu)Rfn2 zFj!I{Y6T&G8YKeuM*FBOm7Teb&yEOw!#eBoQIGJm*)t}|Jn=kjt>YiHP7P0@WxP$> zOe09_p-R3at=d>YGLpt{4=*&j+d*SV;pLL2c*t$}M31bnKT|4vQi<_l#T zG)E~b?EaDDUR^hRMwgw{>yqmPj4-f|PaJHH3S#{$LWZ%JmCl5V4Lho0IyKv0YrZoC z`oree!wlB7NGsbM#}Ti%cd8ymjwmg>%m)hrk?)I6{YlSi2y`G9g28TMv;M4QUxLrQ z4)D*R6mHbr@^3JxFXsdbBk&sOn@4WQ_*7`KUl6HCs9MC!(+80nT!kjd-e(#LhkSpX z0BO`GaeAM&;ue2Uggo}Y=2^{L!_aDpcTZErSG!BT=zXNG-qPOJ$JW%_6Jf#-B~GG0 zN!ErR5^=0XIF*w383JW>Q2afYN{Nf?oYDQ24A|IG!3l(mC^9Frb#+5tT!BPlTy@qd>oYgUZ_Jou;+e`BXzV4679%C`YA{0%uE!{w{I>Ae0E4)*+wu~+Xhh}m}A68Wg4pf7jWq>n?p>lXpcB`{w}8%jChF+ zTU$x?pL#eI73_*r$$(CEu@`9Plv#GBNCIy}{vCJSk{_rza2JYzeoJq0z#KNmFj8Kz zp0!*+rb#DDF9O-{Id=QE7x?#H zLO`&Xm~?+4WbXoVW(E2Eb0U&t52u++zBoQNFO6bC+B=L3Upi~2v%PL}uW`3{dbxiW zfr}Dqm{4broC0^A&o|Nx%tz>mm+QMozJUJf0ZmLTbO2RG15zAgpiTOPH^K+QLts^h z5RDibWJ7?TBuDTcG?XREBK-NVj8sKv&DBe6W85RBa^d#Y5@R#_>LzTsE-%q~Yxtro z_zA2Z&*6|rmFTb4o9$0USb}dHi0KLsLVK4sjcWUa?_-MOkzw5gY;}23{L&YP2|p2I zo6qsj7`MJ>L&98cA|?ILgKD1>5%Q~o#`?zb0}79Jmkti593GJ9ObIq7}bodk#Wm z%xy2|(2p^Wo!YUf+Klwc(M(w4kH)wN>yUuo0sFCg-mwPJ&}n5nH8gc&%Z~c{$<64l z@I{qJZ}W-WjX%k~{Eu5da9;=b-0K%hBTqCbG+;FVgRh4(s7SS36ZksfdtGc5;-z6C zd$?Z&40QPeULm;27QkQ3h7H1Jop#H$ zm+V{{15QOqjSp8dA^7CK2k_d^k7ki8F;8bC6 zrI75$4gT9G_l=58^NqX+rVfu(ie~aAg)~01={P@+x)Z z+mf^~t63THZ@l?$XX_-AgCDulIZW<_d_P21$^5W|a6lM}S%g~!Igd-(BV7Eol1e8$ z1=3|OB9%ffO>)5Dvty)*^U=9apJ+T-m^K_SxhvF=-^+fxle50I{aLAm z`I&)`2A`}5=jZUI96wgU?1 zAX$eMzBcHp>2Eh$S*&Q{s@FF*(!HyG99t5b0Xu!)jBP$snApTelC|N8d2fe|Wa$qQ z*_~W4#4;-y=$?L;ba%88L(L?>!$kD{({H?DxMkI+xdExnAH@xlWj$k zag_0Je_FjB(c$x=(cO%+Fbf!!jRh{!`juwi}|9So@oz-_~QvPOAvm z@pM{672Or%OY)m0*y_(d^_&CAyZ94@>>z{3O}{B3SjyG82(HEqek_I6lkdFU?cO9v zl=v*-?>D`Xp5q$u-Mb&h*~rX|WPn12oYt;|OE53t!c9UYV%#N#FyKo!w5#r+{`*Ar zJ3gnW^f&9X_am+ddm4Vw>s=JxVg|{e-fS`VMud8kjsvuRXCJOQZ{pH2A1@**4~8CB z)xGVA`kYVJzJ9iUo7#0*FknYvLrtV>by|1VHi%1CF@%_VLD;4#dQCxAMUo*x);Wu)p&>R^MpD*oa zNc=69_Zc->q}Fa(nCM%f5fue=P=Tu~6J#-_4ie>nx>s3=ucR{Z7^guWi~R387Cy&Dq(S=3A$`wz<7)wav1rix*-qbcWRXB z)ibdz6i!qq5JpDXplEzR&720s^f#HDWBal=1uVvAu;IW&4l+MK^hE&V+B+-?5zXug z1YK}80@yoL{xnz@T^zoKMotC4(HrNp<@*^pg%^2Z%VB9LJk{R0$Df;BHYU~wYTSn2 zxp+bBZ#w$M!T-OcX7jd?jr4a}cc ztq;e$O$^jMd+}Pz1xhVx6*5l9y?QX^j`Zr8aOHMgIvJJ}MD*mcc_G+~i4WR@uJFg8 z5Bhi?jnu96-1DEEuDlua&rIlN+pckxbUR${yefO#nU!`6DuDV5T)G|mv8C<=G#%`I zom|th@Hgnmr0b5yRacf45GpWc0)I(d8|cJzxJJR_j0V6GH@h5A>yb>RO|D1EN>WPT z*ZQ-Cw;s6QGx6ByGRz^4 zB-JWFP;ku-%1XEimWg;BqmH|lS+^2d4?J6U80-=A*))hmk5_dP~DpXIvh_hGzXMCs=xIU8YjgviR*e*jysN7^>< zJN^ffrgN8D+_1Dwh?R`4Mz82uMHj=%lq}mIos`=@-~r786>sy78kW$cA6-ZI`3FV? z=MQv4WzT`lP%5Pg`)81Y{D|BtGFA--^qosnMC-2+&j8l8b(_y+EUOpqnlW5Bt>ETy z{h#nU|B4BzY^v2wXP}DO>Q`Vhfaznh=qLY6!Y~uOcrGG30e3$k6E?0$};CB++Ki^kCx!sBL&{$ zHmn;E2;udDtiPq&q-*I}9-WGLq$=?HV>44*asdOc!$PMGHu+z=XGZNePNLdp)UVy1 zK5PgMTE8m3dCtquZ9PrB%F$b#Y3l5ec@}$Gcj#pkb2$k0!iL+wz?{!2>|xd894<1W zFuhG4U~c-i!^z699)8^wG`tgIWfqJmU3W14-^TNS`<^r7jVoCZCFtEi>~^2EP)b-^ z2DRdq`?=e}YL*r}#N}vN@Cmk<7}kVbpoz+S;O{jGY8%za3k$9c@pt5TQXzU%=u^kT#)gReXqVOJ^X?iQAsL(34S>-lc>vi4o5sH@d!N zzlHX^!1tz|PI6;>O-+s-JeyJlyvdi&ZVsEvCIto!(A)H7pPJ{hB93_G&#oXhwz56^ z3cIC~PbX_5d>11(J7T$ls!C*}_`IWfyB#~`&Q-X#i{jqzG|@|)8zCUcAJ)o*KW0yGnnAw0VLvJZ7YbLVoZ@ zW@Z#6plD06RtYlakz2o3oPY-trDP;Z=oCiHGHcm6}r6O?tDO*qM*_M zIrA$R3{dg+CmNvB5JV;?(BXuBOdDS zz?1b#Iae?_KlW2l+INvSk@B+SjuRdEgXN^jn}7t8_gVM{TjTXzKNL7|rjZw8aoeSR zdfV@CrW_@76H8{PiAcVZZ4Wd2wst=2kTkP}yVG2X+|0ZeSk!?D#}7U^zjNHIbEc3< z3^ul)?LN2tm#H`W;Qui~#gS8miGp?KjEY7x6CZH(kVQtC%ww3{*}Homq%lvU__cx> z@7q8J2;37!m&f<7XJzqb-@j#HxLsQx`$yOoD&5aF)?lME+ELEb^dw9h>-Cf!t<71- z6)7HzfiB{Zi-UTLvFixluG^Ur$DE!Qa}kzG^c~PH0t~dIm=3g844GuX(4;8Kl=kEp zW-=2Qp3Qx#m<_}wt2oGpO`guEwndcy9!IZ^1l)Os;x#DzC4w4r@wIg@vkw+ro_(DN*A29cPFn4e_ zyc5!GmTKP;yu83_P79=5{48J|k{LT_n$y`JJ1-=_Xt*1qM(4G-^5%xfbh(uvd4?Tf z0ThG!$UfB6xQUK8J>7Z7p54eHMpbxAu0H~EI2q+*YwY~B+I{nI$?elOw3|UwEqTmL zG4pj6Kk>*vWX%x7Os~itg-}biHVbI@C*bkaJ%0F%Ji;z;dY@PreRjbbnKl_gEwS)ndCR zKTX!+n&Y`v@qAU9VU_&3tos-cpV2XFUHdD`JMnp5Q)RJSot-R+YtUkstF~EwxNeUQ z2TfTR@k4$oIp9kjT2v5nq_AbQzUq)Df0dA4?xest`E=)0BR>Z^u)FGoY(Pk-{kY&4 z8JT-GxcMt@2GB!phPE@0QNLKeGWow4Zw8$tw^rqzD7MwGVc;K5i-y`i#ohm70jxsn zvyO}3;uNc^yyae#)U_Ap3?8%rPnWWy0S>P~TW5Q*383X-nlHmm(+=^`6n3x~)`s zaq!Et%J3?hD1K=P^yL!&q7HJ?u!Z#1Uh2g775hA?vnc}}l?rxMPGAyt z(J!iR>|O$3nU`m3O!2W|-))57ZREI`-Z6wI-048-{PBz&!a|3?8kSImJ9Si1AbptG z0N&1xJ`HXOw-y_0&|k>7j1 z5}j{&hi@9lP@V4n-X1s7fS~zgmCiEl*StI`>se3t@2f9dQG+oo;ZR5SnP>dYFa}BK z@n_%Y#?Ge(N~%lT=s_4vg3D|%Q`EBnmhbxUb0mstns|8OYV_LHf1cgVhvDgCIv4^P^fBu)BN9u=td7m}TI%@4_-bJ5((SbfQ~0O{KL)ljBie&`I_@s@>D^n!vYAh>A?CgsMfj&{Kig5@SNE6r#!;+PQBFPGxf-qD24_zU(&9Uxt%)HuR!Dlz7b?stp zl53ki&u|V6As5Gt?u6`eO>4OX&2x!8=ZWpBOr@r*kiDf$R@FzEmPZh!v*~L&okMi3 z%8tdB9#eY?>(wkB2);M&4fSDC(NFQhm5HXXFjLxLm^aEa(*r^uw;euMu~*NW%HVXX=2k;mHYt9Ov)G@SlbYZIS>T2Nzc<3gfu|GPOx%|T-4 z;zS3e9AaQIrBQK0+>fEQ_wg4#*}|>Sz3H`Jmree5e$xqZeqxh zEVw~MK?{NkSu5+V>U%-+XK$+pU4ftzEvTagxCc0$wQqh2>KG-j&_?BDOS~$DI&fMsa zJ0%C4rY0-BHubh}go+Yl9yq%6pVT5#S99~iF`W6;uejC;K8MOXp`_xXbgcgR5wyx@ zH+Vp*@hMi2Vh@@9sk}sKyyB5w>f@--URBk2jwlb894nu(%2EdIS332>G zgTfuPLl!v&4P{!K9kovF8(aTF((TX>hqHq#4-xb)3lvcp5X!6gF4%g7Ax5bR#(PYM z8seI&yT_$LX#+_{pMe`a%%%2#1Mi2Fb88F8L4_`1FaJ}$!63Dl_q6tdlbN($_3eLp zw@6Ld2QDkb54G|?jAhQ2{xGAb^Tn*y=M@=RNtz_xUg?wSH&O5QId+iid&E_@{DOc` zKE?q2s0Q)9o(VAM3uKt76w3W%(DfCUn9$LY!NL(}QxMyuH@87PEGnSNp279%%N0HE z4T+(dPVnw0p=@VU{{XZ1?l*g4vp(`w8bFUpL&*Y9?_W=dMu;MZ(T$VdBA^XIR)&~> zkgzZf@i3SRZ8vE`TudcvyuKX-W%(7qe#e!6Ki{ELK{?5aN?ZZFIv~2L`WvfDDjO-cy(9p3>x; zNDx;8SP4LN;d6hZDH0+Qrh!EF*`=s6^M6c=C_HDLC<^*77GArl;Y{s| zT*s^H=b8Ondg>QXP&v6q%& zw~YT9a&f*{jl@Wypm#U7Q#L+rvpQ=tDpI4v{;=yvJ`rS_5-hI*QzLrR znT0Zi17rm&9o7I1_1}y=J2Y;bj9crv$QGd}b{P}ICFd2T1ULVUUl~cc%ZxGtoltD6 zh2taL$70GMq}u6u13WUWkwo_w!3V1cBpzqNC8!bDA#GMOOI)o}>3kcIIAg6nZ(#tKo*yW=-kG#FqVRL5&qc`rc?`mWVeBv%9PT-D_Y(PG3+T zKPjAq@rtfZN{&g{cp9SCezZ`y4uswSQPQ&I4p7XoG0!6L0*~pV+^8`L-&kR{U{#1E zyrD;LN8$r&y&pE_pMUmS)fYtrI# zM#;wtU347|lKU$MPj0gAx%uYX(`sYOVa|s{RT~7LrKaNsWUo{YzwTV@ zIye8PR*7{`*m+y|N_eeq6!kKk)#Q)(DSSrs67AV4#e@!4dRN*F-jNf!4@V*k{JqnQ z3u?>4C9kIjL~|W?6K8(xCOc;8sD!}rD%1ygKKWwOD3Y4)ridhU=b zFfT;{uk#R8@C&84(BpJ+s8LtlbcC6Dz63k*H4$Cz8#|{LsW_HO5yh`KjLJi zR#n3{<0VvnOWU+f4}a@Tv=mQ8DN?VN-2}2CO96e8>_4idS$X+Q%GiQY)x^#V5orY5N+O)``c-G!4mZ~HTT`}{!58SYWdH+ zOJL}=o1wH1=CW67-t%b6(P_)^NX__hXlg!l|6%_d zz%u{xt%<$+(&%N}1+tPStpq{+JblJK!u{(IP%&WBJ-S6-F(a`GJ>5fy`=dvrMA)Lm zW=XYe-`bpx;{W?Ye)J^f#P^U2JWn*@8)@1S8TEnDpMVW{ocqv?LwW#1%McOw7a zP@A*Mg_3=rKFXGtKD-1XQ5N!EQDh5m=Q{G_>xVs0MTqBlZ$NG?fPMFxl-n|FFvOm% z!6LvoTnZ;s0EzUTYV+aPO3;{X>iRz#NYFm->RjA9>S|@9%%!VbeeRQcwDUgC+)f7; zhkt0Um(Vd%Ql1KK5~gSRx}u3Yw8g@J2I^T?}v(G~TqW;7>WHltO8_8q#k>*ddQh^`-u~7lf3JsodLUKBxjz znS?&ijsGS_>|LgjcbPORd^uW;FA)P~aCbR#9wAdS)~ zDJ3P{NH;w5``_z%Icu?C4cB$Pan9bKok%1vs5MMjww1)F5r|Z%6T0c3Sgn);K6EL+ z*Q!DS0JWBygdZ2BYnI>mx9s-8y3HsNFSOzDZhx`33Z#B?;Ei||DCd&q+Js>EqYPun zqOgsN{uo9lMhP)zo1jEFN6PIs7jsK~Fl=K+1T*E1QxbNYhA9)q=L=fCKx6WjI35_} z(j$K-Ss3&SX(h^jf8kkuiZ;GkqafS!!ui_o??(n?k4$w5IMhy&JZuZ^FKEsIHT#vHzrf)oT{TAug(UmL^f3fk|Z0zArYrw4iQ1V{^w;4J3 zQr61$mEOP?6v~F-D8tJjC;FX?3x7u-dOqG*m8lgf;qtip@-TxR>Wl}b$9LY%I<{!x zUHS(6^f(^-9D=KrRVJoo+vnXL9;{E_e&*8q9vw9M}^KP1JAoc(+MF?Vd|iUXVFlw_o2{G^bO#9BQsb7X!Jp=8C)x;@f*0|fUE z;G82l$X;uPzu299M8>s&40lyTELQW$uP2$4KDo?Z+1Z$Qj2c zz{GUqA&Fq0RKWCMNp!?b)|TkqeIz`JA#anxb1I)WnbFdo{PjAiKf3mu>9R*s@Yjxm_V-L<>bHBxifn}KVsm`^AE^;C~?@+?X#p9 z!OX0qKyB|{+e6ZTu~tzamPRWP>{8S{-Ihc?G50pDFyKpOP*bm@2aaanK3n8EK z1nA?5X7UFzdE>&p;4d{3(T&vP>uT}6n_k5UMLH-%jXM}|1NCCa-A`Z+*D0%3&#MvFJoEIJ-uJLv$U{JaU3-9+J_$UZ0+`L zqH`u2yqE>pMsz=tChX!UHT-&sRZ>J(p8&&AO-M4@IU z2mh;U2!Iw4rbo5p^0@ix{Bz}hy6Ty_G`n#LoGl$(+Oj`QvM)QYv?5n0h#2c|c0R8@9v*?Nnq ztmcDdoBNhyqTY6EI#R7fQTd9KZH?QP>h>@2s{h=SZ;+3)X`9ww{Qw`~vORKcH;%?v z`3mJH`er}_z)JYt6e@Nk6=L7&5rs;*QJAl)>7?BQ?06VIE?}N_dM5ZWZXma+{#UDY z&?ZWP?SxY9a<0*_nvt`~9j-}y9CJ}HA-l|}MipE7#baeCe}9<^o`)b$km^Yt3zVV; zJW8P05@{>o$9fl1g>?FFAl(Ji0R#1RT^6nVKJXU{jsh|51y)SxM+@gjEz6tGP5H!g zjp02q;wXI%-)PLZL`&^eW*PD>w^=xryN{2BX_lDwV&VF!hT0J^+Gi%9d6D+!edk{S zmoo3=$K$um053>DjqE?ae8c1PY@wF-A{h0IVkokYEYHdeI0Yu}#QC|dFXt?( zyGO;xc3~iSt1Bt$M7zNAEQ^;LSwz7+WNPe4Y^z#RXx~v4tHhcWy}i$57`yfg;n1GIRd8 zz6d+Q>Q}co&Q=^j4M&Q8vV>Xxwg#MD7h}u^j>oUpKUI2!9lpj0{YWgwyD3stW!s*v z$9PCk4VJa!k-et#J$&7D{(!15JJ%_|7}Srn)^^%a<=~}J;qlf3^1WGR5Yut^7?vC; zBLSQ6G)elnn9o3?AYmnL+o?>wi8GHw*DI+I3>m2nptfn|#%=yO2oqPEKu&X_>75?7 z1Bpcgh;W>uWXpS-|J+X=QQLiPwesV4?EsyrmBKyGaB_{X_6i6WZT@4|wLVQQvAWEP zcmemCP(=FW-`l1W&Aff9w*g&=_r8w)7AoJ<0WQzo6|!DYg_;Z*40UUG3y4GqE5hiR-f8&-8~F z#$SX?d}yD5zT~?_vg(TLu26}Z1A%d5=2He*5_`q1|B0rwQ+Ac~YKvBYJtak;!OvT~xChHQ~p_ZiFHNR<3Dlj&4^_H3w{Kj8R{`A+- zL#Bo`kFcZAer4}#)t&t##@XZY9rji(?3Xw?EnwoHG}|*Kd$QWk465%yS}1-WTt$=n za64XIv72y>L;pr5LVh3jS9qEz&}(ii@(|QB5%~{_k9QE+**dW&fmgvxEv3P8x=0-u zQ%@axiyozQ6JZn=I%(bYpC*|=5^*#9Dg4XiR|CrXtxuT7Q0#vi5#MRu%;GYb5+&Vq zlnFImQ{ena=fY!*=NfLVl~#glqgPMcMF$zPQ1mA$tRH??^?4mL4ASLx^H1q%!f}PS%7`3fSTMSSgleW2X66wi|PDY#A#n`9)u(T4xFmmHyP1y zgzfp*zgjzwt-^M>@-k#PktfX`HRuhAxl|fzUBoZ%`*;I%?W1?6rDGYVJNi`ulH%P_ zu_8`^oH>nsNQXc$l4|WYH8s6-|C^ofR-as1OruZ~)jl{(^nb~Wz24>z7+!?ZH+$&H zrTF~KV;6awQ#31lb|FYe=Ryivbq4tIcI-f9M+3RVxp1bis`PdIu*W66r_0}mNAx9| z_HrueJUw5nppV9!9X=0GS`}V!#E@COCO3&`fF#vjn15lqQm$lk5Sk~ZHgaM^i&0Br z31JI~V!$?GxFQ$Mq(sc^9ynf5JdX!TUuXONs_(In6+-w{ANc0f+uGzxpZo1p(Z2Fb zR^3sy6ddS}>U5JLqQ7J*riCyvgh3|Zn|n}svD(YmNClWe^n7->W+e}uh9pEefd+)9 z`2~DBZw@C~F|ng=iZM&v;h8I+&kM)LQO*G*zD?H@P%R^waf#!#>Qy)iC0a>~l-a6~ z2qMT6w^6VzQoI;bz|%Gm0nrqt(-#|asrj>2xT7=*Y}C7MV7_ke9L|Czv78PN3=w?0 ziiD%ksa+7*V^|GFWDec-fB%ltv15ek=;B>mp->mOOtQt4s`zqjY|M29Mbvqb0o9I3 z^52gj#U;*U)Y-L9tNxsif7-q4DU;4W8Zg~Pla8l(^gcxL5=E*w7=jB@H0ixYB2vzb z%&N?8jN(&>*<15`=S9~dOeQ}ZgQD2ae`K!9mBYr~^dbb)AXovn4LR88P8SVHjlaBf zDbB~e%kCL8Xl&y@R?8wY$!brnxj#xdZ_=rR51O!L%) z0UvXHvML579^Vtdcq@8eGX9L^gAJaa+q5-bvRasY1cqG6(ZLZ|m5V1J z_Kj~ZqiOYMI;V}ha#B=iFNl6exr`6-JF(ioB2;fbs^>4SNTH6a)BobDC$H+=Ku`{* z<{~nr3sP$>k9AApvG*G?qX+N9WvLn9OU;s8NjLwtmFPiRVn20Q&qsQ+cjOd4y{m~0 zBX=V|iA#W!(&TcX5**!~Q*sL!T{~3~wP#ErIq-Tf}`KbtYM(KxkNF z_>9UIkR;ya>!Eg6?s1&{#LKTDISr9JX#P7i#{~v9To7@fasMl%UWRvTNrC2k69`G!$UTlW666H(n^A3g6%x% znzUW@Z^xpNrEoEU&jB|=LOPPq%}uZ!Ej?*1b;+K|hSPS< zCLH^|BNgg@W7T)rK0hIvtKSe=cL5xnFNlUnqx&j5nrU{KTvx)5IX!58?{FW)UH%k1 z%f8P0i>vX+3$xFv?<{*`#rna7>90C$+XQjP*wZ;^Hp!a%)2w>jCY}S8|9wDn*TQp# zdanH;YNf}Wde;K_E;an_$k}#R*%e$uoQ5TdQxd#M8L{tWHV{r8Z*a zxsx0>`Tp2TyQFky0Z~%RCw9I(XyFqEZ1~j?7kT{F{``aueLJdo#o37`W@h!GM87%RITJad*T+ent=>9s!yMMy^4_r+r?STPnpUYB|6?hs7_FxIaG7WSl=|^B zq`NT=^$i-`;(U2Q)9{G|LfnmF$t z?t(q1-=0)!d-&*kz$hK-eB8OMemw8b6KmW2@Mc&Mks@DVDnLr1{*Ag;?7XS4rE$)W zhi>Q!><#2k-)sFzwGVi-&8c#|8^eqk11n~?7_<8)SHW3*$JTE2)+dt-Owe+gTu|+z1gd;#|kgJ9)LU5IDte_-}OURne5n~ z3SU0}OFXwY$SjEgg03!c$V{ z_TL@;KCB)4SllgGU(gxT!S}^~EgHXcmh4FjB>Kw7kY8zUhj=xY+Q-W2UFRG^U6WBK|p9HL&YE zx|qcP^5T~QLoo0~^6RUBD(y>rf`e*WDOUffwu3z~l?bSw^9x;~+I;WWOI4`Z+nrLR zFYaB&6qR+Wv}qL5h20x#Mc#;13I{z1dGqPXpH@?z|cqSEufK+SmPb zL7|7oKFTRjq6uvRoX;b4`HHjzXxrEhe=;3-W)xYLADC!MK8(Js`I~s&>~!?3x<{6( zVdN|z$-y-@;}vn?U8~;eZ4=8>Mk0Jz{SVqJg5G2IqDcm0U+E=cpW8yvbiVz#LwL=_ zsimw$aQPFJ5zZeSfzma_mwACs-Pj`=kqxIK<4R-MV@4-k{*MnczLHrnd1F8;%*! zo`IuS9=3O93rO7Xcj!g$K8o1-st++!a>wGR01U@&*Wy`H-}XI8SGU3Z?Up3^j*neR zT2>HQiPfFPmvKbG3$o5hs>wB970T$0h@J?j~$eD&`HwgWM~8 zdID!3&Zm;>pB__6nBSteMQVrujn)Z-jq4iQ^3nHvb)Lwkerf`V>_an&v(WPq$zu^r z_^Gw$nuqEo>AQJ8h=b;@r4-67cU@0ctF0L~=RpLF=PKFVd3xr4l8uBP=AFdDt_|o7 zzwM2;MQl#Ze`|_WX3Ej(YY-HPA;9Eg}qY!)QXxiC$c$D-!oz*p`I_{ta5-WUu{o6a^F9OEYcZswe6%GSWU=Kp8G=c_DakDF0*}k89%g z%_Rr>Z~pUxtAUB<4)8gt1-#AYu}YSCObkwJ8jp{T;gD!+Fm>Y^Pxa+P-c_D<-5Fn# z1L02zY(Wg?)QxUcRo9J0aE<_MU;;5p8a}6GW|dx&X<(INvbKznW-A=6JmfPeWg1Eg#>4Lk)~8FV z4-9lM$~}>GacuAT<&>il+tdwK&1y|ie6iT&_#>qT^o}Nkix*j|G>kuug+)KP+B>|( zp;6;vl_~oq=}s_Le$W{aIuS*J0J%8bNMK_2Fe9Ja4o_g5!3o#k|@CDEsP0E|%?u9{TC{TV$ z@*UwMFqSDCFYus)nE_(x1JLPBCGki8Cp7`cQ6DVLXme6M^hKW&}>XGUQ#HynsX3G}t zX5HwfQbyCNF`MFZ<32sduF-l`mgga#DZHH!5WZk~2k8%~c{~Smv*kVoNGK!gk&p5! z7kbuQ4As-Wfg7h7gqHb%K7##OCAuoQYB|B06sOsP3Gmp-Y8yh(xTt;eppPuZ?eDL~ zc;ZM(*FE$J(CMMNZYHul0SE*Daw5VBWQyqBvPNi&+S^z&nZ@Ss+Zi0Fz^3&gl6SjB@(j8? z2-FZElNqenjA8gm&#G8huV)(EN^?9jAuH1Nhos)Y48GVv+H_kd08I5jWgB%r6q{5O zad6Upo)B~+3F0N@@L#6IqsL*~C`evt-Xs;+dmfiOD^&d8GG)xjZ4;+ziLZWP1igjN-EBc*3^9PqW?pp7gp-z*D%KZJfjsz-Q~y8O)Rw!mMRh2X!% zn@F{ZP)x7LKoK0@ugOZ9}&Yo`axB zTybSatc;7JKl3#>|Gp)wGH1r2Iv4Xek^jaIT7|nMi{J{BH6;VE+^W`tiuMrL;$c!O z$;^x0mu1>XI`3galt=TmZ>OC2k;zbFlKEEn{NZ7wYh)f>C4uKwhQz`2$wOXpaf7RP z(ad(jE#|@}YN-8~#SvO`(A*xCB!FTD!GrNIT%D(Rkzyjv#af-W<^S zB>b3G(Nf*~-Yw-aNIGebirOpzahGV-{sVrJmBzr_1`%obKB%saO?l`H3Zk&^OPco) z_)eAn*@Gad*aa#i8!}{uj8+r^6{ZY5OeC`Fmw>^DmvI_Y|E*@LiyC!*<@0r%S3LiG zlOHw^&Tuzp=baKNW(ABJY|2NMcGVWJ&`7wao3>rGKnT7~t|r0zU~MICKY}G?$w7`4 zzc#PAO+|(-A;}C0RLwx}5cCrW^Fg`IUIscfE+OxmqEP|WOPthlbJPD^GFuo3kJijG zk8wh-1%O_pS^Q59GUH5-?kEf{>(#QtDi+5N&3soMhgVE^$^P2a=9iyreO9&}YX0oJ|rGZt;?BBbo+T(!jxavjZ+#{}`5bX->fXuu9Mq4{tqoriCRz?bD$ zC+*xADRp+DM@*`cM-^r*YW(a%k8_tlS<6S@4)S3J+#{EjtTJsq$0j%F=5XFjhU0ch zKB7*4PUw_OUXxLojw(br>)UhyP z7={Fnq_A_sMkSE3V6*~+YTzCZ{>ep>q25<8k8i?wm z{L_iK?#kQ2%?JWs+>Dtk{)9OC;`Jric(g$Y0H6mo_xh{Io<;LBuBX{`0}1=wfNN_| zsipBSZQ|RfC%^9x)loI8=A~Gq-!`VrH7Ja1K-AjEaV+#(;@Q*fobU{Rtx@}fC{mk| z6)U$0p%%iV*qM@!YExzmN&%HC=2Rz3&63UCpSE8p?YHdYB3h=nNH2(}^%>D+G5v?Y z2TF4donr6EYdsFOgZy}sC^!e%9o&Xx_htO=az4yfMw-PUm7x|`bYA&@aSC(nXql-G z-Byzywj*I$GLH@UmBM{)F8_Bjnwwd&%pM|6%FH4lEvHK0ck1i}vrC%G8F(Q3v&aB~ z>Ok(ldVZ!7n#Bpl$E^odq^UyjR-qqOJ9E5LH*Vw?oTBE;VDY{Wrz-V}o4Ph>JW9vN z$)7w86pmdhzM&Dk85jIRgkU`!9eu0*uT}j`T9+Tol`nulz*c{|mHI=od8Yzn%Ec5* zvDdidc|%IzZb2k2`^-mV8cwkjghpH|su*c3bt!Bu>9iTk#M<1W6SeHdxV6afHRukf z-69axNcDlw$T|HdXXVi|go*q;p~3JpYR8fb*2fc6KAb*S~kQj(u0KPyKSEDc_<_+TCmD80-L^QIb|6=p?*C z4QWq|W7~bGAyJvRt3Y~i?9rc3@Cn^G!8w@AyOMnGnN$t=m0I)&4L7>SUhjTZ1XXEr zBT=nUA<>&g2X;b}29M(xd()94_($W)UFP9m4txMvtFhncwFn_xhL>?xXr8WO-*g5V z>_yvz57(~SWt-V8a%@nl#42h6`HQG9*Jky>iDWF2*Tw|!f0eOVKjpDdU zaoQCdVQB1O$DYEd&F^YZ#re!z`y~;goyPT=(b?+Z-{RxLxs19O#bCeGwMJTiZse8a z{tSDPX1PzV)j+e`mRbhZOcPb%-eLXt=O*&@gSgY5aSCei>?1?VB5YRs<1Fdy^R zqe4-BHp;2B-&%#hYqGn+(6GUT^8!XsrlbGd)2;AjKbpfv=5l4 z16X8c{!SSkd&?~q6g_GlqVQ6GMyl1QjThf1-wH3a*`?eK}zn> z00GR4;Hz6$pO~B-&;r5`R^qbSxh_sq@qJ)e9B$kH0xfp2y{s&DCei0J?9@p4GA1-u z0>F%38p+|iou;EcR3rC-7^o5wkx3VwMSo}S0zK5dH}6k5wUjjEreD-ZNb(SJT~`EJ z%*L(C{P6ifo>U{5T}^15E_ee@TIIuI$PYML^kBr{pPPvAiu?7E>tF;AcufQw?I5dK z=6e=#q#6?0&~8cpsKYxjBmFX(4}GD`J<7bRnhX8zXeD% zfI^;C^dhAg=_&#wWw=8Rl2(ctiOpikh*Xni5qOjNTn0%Pr`tXTV;o5r2ayc+w@!x~ zjT@9lO8$fV`TJ*HuRu671AD#WU&mNIBIb-@(cZxbvm_Iw%R_4J7hnxei{Af!V#U(Z z^t*G6UDX7-^k~ePs?X1HnjcIxppN=&4x=Ksb(b8%+CI62k;#N zhc*Yn85ejO-}!HgA^Kxq7`1#PJEQxn$5J78_S;i$^QxSk&N?-1IeP!V%L7mE8vT9^ zrA)G}NEiD8Xu8MVk(O_xWc0J9ohH(skNi8r^Ox^Efm5x!7wTP4JCrc>`z*O+S(vMC zfBLjaCULTe>G9*|Ydm&3u$b>N75PEY75B2=P1hH7ri>9OfXw!4;wfx>;Hbb3`M4rF zv{?F3OZTv;N0$}fsj21a5vTYsM0O;p`&z7WE!^!OteNco_bmi6(EqC`_foXqrdKk- zCU*Cae7wF{Y-OTe6?gv8h?9nT-u^)s^;YR(MDy()zTl;m@qK3bQ}TuO4udK6Z*V@C z7t_`LNc$~s`LVilpep#T{EjLOZ0iuHda#<>67#)}?jQ0m{S%B4ESDSc_f;_n@v3&f zZO80fn{JtQG~phx_AC=0V5bPTAR$iaHv2Q@QhP zh~AF@$a2pG;;R?I+Y(rBWagmi2kGDN4;k!jTSd;OS+Jovg%&MvMp|@iyC%u)79`g7 z?{xNRL)N7_{rWk4@9)~qhs3-A*Tu1p!dkrz-dA^K6L+si_OdHHt*iWeoi)`R!lsZH z%K(<-Ar>aY9@(X(mRGW=ONY|B=6cJ1WcaN(K4zYple@z9C%swX%Iq4Iu=Pnzm`g)E z4rB2MQs~F?LwTy&;*Xf?`inM=&uSzRD(B%lt(ISlaOnEs?s7kbOGsh*2p13Gge1;9Zd^^StCleu+)>5EVhy{NMv1mF3{a5ZX6hqLB zf}{pqH06ms+E?ZX%6JSaV}ZS|qXq=Wq{#*gn(G5X@rC9m>i&MF!d(x|nNy#%CeGcb ze~)qkFyCJ!Eri1s+=qDNe|*%NA>K%2m<}-Obh^Ax0A?ga9;sF6rA8%<`zi?7)GLf@#uA?51EQDX-fy@N&H&RgI$;`{V>VN$$?02Ee-m&N+h8znRI-mbiYRN_?iLm-$2X--Yc2F{Fr@{dW?x7d_|VQ*RazlbrIEE~Oc{SARLiSe9n37xH=Mk#L5v=1FP$Zd$_>|am) za<({ZNr~d^rqQ=Ipsc)#mOWBSFYNuX?abjTPJCao&+1aAPqGo%d)<`9GITbBx`xP~ zArf1oAo0tQoe41i*dKJt3KzR%65sRzf8|)1^yxk=ClCJ?9ceRFBS=$9+Zib?x0fVB znw?#npKHL+KdrhlNL{r6eYmrKxY#}@>>0m-f z@Z2j#ToUd6xwpxHr0<5acGG8(G!0iE7rHY^LD-+;xEpJ;HR++W;*8dZ;JN4_T1`t! zLPo)A6jxD|N&dbGD_0&-)$yy_gO5d=2I&mcuK^Z0=-xn7GZIis0C7amjt>Tlqs@XY zmW#v3Ni#DR^bYbr?yNhb4OR0!2b;TA&d>H$X)#)C>6&Gb@!Yv<0WFJ<$Pl8GT3dg> zzN(;UZA5uq0Ha)`?nYFO!DF20rGPev)Nd=Fle6-10D-R3YO}E_Y}iEJ&rqrQZ>Tq}h6yW^Zu z-O$aZKDt?vjqjRW$*JN0*8&6sk?;Gc7{*K1BCM7I)n%1gG8sORiWyIeS|6=5*;Q^SR2SL!|1DPxAP3@O5i9 zI+(IdQjop5^RG}L$)}qQMjWt=@PI+Li?VP(MD4IJ_>g0x(TQt5 zM1BxYQSr_6`{12|TGxl=^C_9d@`IFG(46R=f<66!VVz$OfhdF)s=&x5v!y4aioy`Q zi6~vB3f0e}mlTA%AvYFYPz5-&9v=bay4=(_-9bAzICu6&ATpEdptm| zEI?!#upoK;@zktY^O?e5!`tn2K8n;Ksd0n;w_6m9a+WZlgnJagY^GXU@-z%8DJLPH zbG|J_4k-D={1wj`N3(aGdA@WK<8hJp5YvvqEY&vg$N|j9t#|$|@s4`C#|7B9zx;foIBboa1Ht>;5H5PIY z5`(T-jsodLCcV$;C>XnMK&SFC{Wb~yrmLMDUwE+DfyVPULoNZs?4{W3it?&gS!Pav z)Eike3x5w&Sy`=A37gS$Vy7!2<(A*T&?e_ZV#d!g8dKw1ITFK}-sfYYA;L!NdY=To z|M}i^+~oX+F)SyIsBTww>9r$LX$#U5y{!O=ep>b@EmJaW5R*vu3HPp}7;F|WhjPBD zc^4qNrX3Z<>HlRM?vNT2o;*JM(}Ww|egv7><($*`Aj#*)Au#mV?e}n5orh=t-cP5z zJ|bOaid*2M9bYc49FfN4gg5uil(S{Ro?avlpfej%(e97KHYb0vo~+tWf2Q23g-v}; zU3|2W_zboOJuWTBp&op0RJwg2bhY^wcz-l^T=BIkB`y8@*DIAl89n8yf;@<(HxQp0 z(f51FGNLR&epcpg7d@#P=CXTZj?AqUo&+kJ)sI zCUhfGvJSN%+3H-5qZcz#(Lius7IQ&kK}@&}4;{r@A#;F5p+Z4~QPOQ;#-J|D9h;RR zRpTy;b4$0YLN|%gbARS_u^${zacOj=mDci@*LB_bMy8&nBW4WU68!5t}8qLS2D z{Dnog;Jh>>vX2cE(SL_iInmt2&B20Y1E7%#9;b!6)Xf_@aknr?6QxC`V~p%zM4ntE zY!{D2I$OPrsY-cVnZ%wDrc zHaR$`Gw-@cl(@Y-bmO;v+r>R4_&qs7%uxu?kuQ+dXG|1ScJ)AC4cGrijTq|IGGLn z#tVToFkz4nG3u#^;2l=zm@*!P+LbAwQ`;ueNrge5&eE`kB4Rdisg;V~I<-3-U}qQ% z6(@^BURL}=cA`gEN~bs$BU`hY^X(Z-VwUGpkl7k~Qi@lPx4Qr4pp8Xq^KF81`mhtJ3x2qb1&v>xH&-kBP2=Nk;E3 z6$BJl8Ai(98A^PP{g#33P+(!vK}dc{jiNfJZimI^j?oH~Cl48HV2B6tab{dFBjDh( z*6Cj#rHlYWq*KO&l)b2zQd7eRRc*@sGoR2lB(U)~-1}YkXUZ8Hap%-5p&alSjS3-J zH1v$0WGGW%P%YS?tsbmC*Q++f$uZZ%DJ-c5q*?UXkhK9cRyr3Fl zKab6PrNy#w{uLG-)?zzOC$K7!25>wS@Hi4wfqUGkIp~hQd3xAM+@g~&Tq@E0I#^{i z{rc>E)4QLNNo!|QK@uI7Jt1t?70&;?0X4i}gl57BghjYiu)@&56XIteHKI(&Ux4bh zTUhvBL6#)+!frI3U*2iHMu*mlsjsB_avzQo98y+mi4>dX#iX#L5IQGo0@epuAhrsI zz}!WcB6pd{J0}yTDyOH3nxXPT-#t0#xHiuvKF3K?;f0flwQte2(v4D9i37tY||B$ZUFD&GYW3ldqNrTJ?doLK>g70kkR_bn- zDM`vhOeKCZJdUCap)IXCxVJfkh+W|NuS;%8FScf2FA4q%)jLWxs`S!>FjM1F_Zu3& z-P#`WHJ}RW#Z8VxU`>UN@Z5Kljlwx<_heaIX>_agm=V=oPZjeWf4M?K(XPTFWXQuQ zI#iaq0Kky#^pWHrvp7V@Ky#(lgA?Zj?KE765mY!-w-}NXK}m$UF)-Gn6tFH8^yWXR#8YuQC=Bv!UXBWm!>{=IAwIiU z9+Nv0g5N)cxOXw0V+9W}LmGa)1QYKWB71GcM-Vd*iel z8V$-`;W&yktKEiQSvd}6TH*tZ53zs>0SeZYzZCWdyVc1b`yI1k4DNA)2N>nFyvj4$ zT_!SKPB7Z@M5y1@;cEe`)>(O%{o!@|(2JY{q&Rn!QvDdVsO-DPdQEWq$WvDY~Cb6 zs;TIHK&F$dl&VAe%x{!O972O0tfS%49Qp(#PkLpD1~d_Z}GMVWe`?4z2T0IF`Z zuL2X$TH!r<$+t59@-FKUayLTo3#{PVb9xwZ=#wIm(k{!O^KDw@u(5_zp)Y!w_Hjcj znLLV(p9>gzd%hFv^EOm+<6|(Z$jTR|Fr-o8`#lm_5hh#FgMtxSw}-wm0^kRKh9r01 ztn>EGEL{-4(mBKiD(nYdEf`LH*pHM{FmQiBjwnBXbQ7gSjQi2fVu$HVDQU9BuFf*LGROfg&zw z8&Bpe0-2pn8|;$2nxF6Hx?J=8&RBukhOl}gFQ8>Rhz0mW5sPd&OC0+OCzrt?e znK8+~Dd9|UBqv_v)Yx$+W8a{+Q|i2_6pW0d?*xY^izJNfomhlLd+BlLrcB?;K;rj` znqqG^w!#{NL+6p{h0MKhj|k|8sp4407#v;3&tP87%E0$tQ_`vA0y|}+;t`r)a6$mz z(^4Dc8VQ7o2m_4!7RQ^#_E1mh5R?}ut76kwjnR;fpCzf#C3&s`t1^T6F0`GK!kDbL zo{9r6;>EY=Y^7^EpaHtZFezkh4%`)M0&MnY?vp$$DrQjM=gMXPEbn?^fsbKfcN-Qa z^NQvgpvpxT#D7!Mp3Y>A1dZ)&qc(Oh!pS@!Th)W)Zy=4Vj&RYUqMG8CLu|wyiG0bF zboZt#$HFcsj`G3LOu<=9#46J;`~Z$Gr-OZq79HYOP8z-VAV>GWMO(42%oyVy>oZ>i zkIBEgJo;tFI)x7|b!y+YKe|TUW8IfG@N+Wok=g+TTThqz!!1@qt5=gg`lb`gA+lxZ`fSOj|!oqv>$yLS4@=VJH$%I+e0u{nTlSS6&yRknrj z{g0b>ZMc(Nr~TC7Iz{BA9T2b7lqsI}1e~vx6k2>A%IF4qO#N)nf zTQ<@msw26WO7NR#?8kS%fUju2n*@eQbl0*X#DipvXQIOZ)jr##j3ou%?3e~#ul~J> zCyADT^^Z_j*v^6nko$txN40|X=CD-X*xKGs#FO2}fMcr!U76PrI@k3qNeqQh7 z&)jL@pqSj9YyV#**?YB)oL5M;OV}^*ooNbrR(`F!hgyRFO@UIO0^4I_%CYWiNF+NC zhtf>XDHpZVkFr^Kid;yt{hYi7OHwk><~ zSDQvjkvvju8eTnqgZz2VzY_(DJ&6O6#h9w4yr(*Pvd;!bl=Mynty=f%awE4|c^-aj z)X~Yaf75=t?i*MC^ZM{16~nb7q2Madv3&JYkWS$srQ^MDnx|x}mPw#txr~;c0JqSc zGIn9jb87JuCIPOe+q&h(fVA+ag1Ml>s|usBqtQ>p6C!2Bi{rPWZ*ZgzK1o;Q69iOw z+(}w?XE4esy(#HBFd>oNM^+zk-LCDA)15?q7Iea7OXiT4&FvDusxSC=AM=zplOlD9SeMS_A<_LXd7)KthnEJB3}kQ7MH5q`ON22^Cm&36WAl(nS!EB~@}s z>F!>-8~%s)_5HqYerFuVnH`2_@B6v0>zwPHb8ki{y^X(-L)8@D^jRgBXU8)Pd!J03 zYbEc;UO(6ARV&8W^j5)Y@BJN5r(p36-$PQvR`y%Dq>iHEipL0{29oJiiR8=X@np$K z%WO-hxT79zoaKP#JbGri$Dh7qIcTea6Qymle{e#b*E zCb8j5UvAuh$ZPZs(V7vdxzb|M*YyT;ChDN}eAN7C7-IDi(PKp><}=6nY^Q@|7OnF6 z`Q;K@O(7cQ%;R_ZRYr*Ambm6&d2wx4!Fg+zM1qj&!`3qkX(!ux%P)^4y>|}RBzBgS z0w-IyoUX(ws2>-;JGm>!yNY~+2L{0J#jn(w-Wf|$Z&A}2b{ei1XJ^lkQ;ZDScRjFS zvw5s{H9gZmo~ftAUIj8!-I8j4bB^v3;Jgc)xO3(5{HXGJe&m74 zfnyZxID*}{bsjjqG|&Q|c8zB{C~>ysdz$c6P6>R1hB zaKBq)eY!y7vx&W9;!Bmh`#0!dj_)AW`akgGSm;yZbe=3#GT_LmaUKM*PVH z_1d68PI%dQVB5#c(GodFrQ9|N!tr8*R!vG90M}ptAc8hnfA42p5*``ph@I|(x||>r zp*ey%bTk1+MpGcx=U}FpDD7(Je#;WMz(`fKAVo@NM-kT)%J-Q*Rrk$-ujZLe$$M+d z6eapyS&Hu=SK{7=;gP?xB}^{u{*mil4-q*MHSl4(-+q5)+hKPk6g)dWj^TOOB$eS`f-7W7%>~l_Z*TR=NI+U%Fe+l9il7uW=T(Mi`z{JKV$%QkkAWld5aT z)|T!tY)sZ9pUp;YfxbzU?g}R{3sP{0Nl#rX`(Pswrc92~iom;@gYv|z}Uz%yZ)sg2s>PN^>%qni$1Epa=VLHYqvjXWw>Hvn8lQW{yv%v zC`Gv|Jw}7vfCd99=xS>%GXIX1cn3qIO+rZG@!jkEt&r`+?kUj07+Cx|?LvG6pS`0b zC@m*!-oFhr>LhIYZAc)!#E_RQ6~a5;8Uwi|t*^J~ZLkEmV5wV~6BDIyrxB17T!D@b zYqsh)fE$z_o&>Ia6>GLZ7`Ur(ijaw9jN-vtYy<@a>R^a9sMQa^D!NlYG%*RG#Vl)1 z{3KzNgk-ESN>vhgMIJO94ACPB@K)Jhw>O+DWg^q~|~y z(v!A7?YfxoD0&>Dc?s*rA(I%GkOkmBXqf$Bry&>}d_lx^%Mb&Cd5%|pb(gVsY@ZXq za=7?u?9o4T?56MWk9Oz!NnAGXp$sa*yB26|(>61L{jFhp`Lo_ERfoh-z^rP*2M^ix=*pCq{)S3_$pEG5XND57kTj(z9N>p>Z(TEZlLv3F^e6U3G7tvyyF6l_JEP@FX7FC1c(0<$Ss?_4skj57E!>Sc-y&QbDvE zv!YI84~CoL{yr7WVK|JOAdT}gZns@tI`;DNNPuGmxN%zB2O#4ko8H%MRGPfe$Z-Ab zdjw=mx*A)gOOtF?&3hYXfhAUG_J%vOyf=VETpeQ#J~ zR4p6i|IR+(&nJb=i=%1EELu{ta2Vo`0uXgo4qMMT{$^wRhlkj7 z;CHyvt(?svlRW4xr*S3<3^KSw(zu@q;MdEJUlB3=S7A zp>#f5CN$#*C|^}6-cD!Yk`rZ`F(pt#q|$?QwPav%r#V!?NwUD_PJBTl>b2VblL~C;HyZmt-!xtd!-ksS z-L@R!FaMk;_+jxFGkp*0eSt4F-Jp~HZ!&H*E&G|7f zc}`x@6=q6B$2RfL16w1YxdTm_&*F&IqK>N({?k}6dQ5}rzVLl1C>Ez2+QDKDGG9DR z_0CwAVEBIP#ot%r2WElLxKJ%yK~KKMdjoV%BFLuir~bon^ta{**QA=6(7j1O@57aO z$_Q5dwEMkVQvVXTOt2w1D3_1Jf3yzW=r8GoUFnuR^UVdNC-3QH{k6kNd;TK4W|yBnF`pN++0d^x!YdEp0j%`#_MLi1d(eGteX6Az8&k8 zBoT2PaQVOx7H^b|gLY(o7YNVQ?C&bfPEgqf~SbINDqUM3R2G zUy+OiY|%}-KzfLmS+%Di*zWJ5r*a@wZ=G+nNqU)fy|P_&tJi+;MkCfc*It-89+1XO zz%|^@U*VFtdSMwj6fig>k3OcJoh%PWb z3$p75xlEpxnNHXExUhZ)Vg?cz=JG4!pF2-qR>wpC7M4k6&NYH7B^uVaM%6fXWJz_O zndfRV%4(R+nA(DdBQ0x*X;E#^QG}m2C0v-vXX4TIb@$cA=A+oDz`eN57%}g*W#+3Y zGs49xH!F7VZQ2FNbsCAOtjF(OX?#i6aKD)O6*d9PoIrcT2TGi*NmAamo6jm8SN#vy zSAjvy91zYhy!o17(`VSs=d0ApCkyDwmnG4E*JLCJ0fo%Bm0C>}N7~l-5iO%nwE0}c zCjH;7{Xruc)YUjykzeC_pj|<8(Ogjr-?Y-lP)d;`bB4riqcI-=(v&A9=k<7{lO`O~ ziMXbVs}I&J;Fb9>@&mC2N(`(gLuNq=Mt;_*%H;Q?+wWwt3zeVW#^CyQJ9^`$gg+P} zxop@;N}Zf1T0)P;b>8E9QvNfBF{HLgw?@l1Lya@eQNoCjVK&h9g913}AxN26etp2k z9f11!2+e7mGWW%8|2YjdP1E{wXlYodjnF7iWnOj4a$Gt5bcd{X^vLiYxCM43bk@OIW_;=8{7RD(9GF>z?OI1tw4wFiO9!_=mkvf=0d-=M6nFhh@XMM@yHU@=}y49|6Q0=+r+j_Y=O=R%hz zfsS?0#{;<3a@uz@KuDZBg+X%FoNd;qI&!)F^jpm(?lWqan+>O!0Gc6>>vG@#$XwH` z-u?c!bkF7?p&%q2_)98x8U^7@)L_yrs#N6!PLhhT_i>82L6;}CdoZwZcpf!BJhY_*?C zs>c6RNQ8!wi!2XMxQ^6_auTnx?9Njy277Umr|Mp5Tf&^u=DL@v{!v__!_6K+d23N) z7M2cA>jQ5UsOwAFUqEyQw{T4}|I-4Ls@65@em8M;{`-ywv8FJrsxb!dujI3=19Wfn z-)d&x2Rcc`XX;S_&4(k_`VwC&>ox2ZEGOkK{r6jKvLV@Tf=2_(|8Ggt@rYCIlBxdi zQ6e$CM=s+|L2PSDmmzpH8R>Abv!=%=hROZ6Iy5>bX^_+9`+wJs?_%F!nh)1&m}dxM z1ic8In-TYZ=b!doBA9H))QJ2)AL=aHjqkGJPT z=cj9$-%+C}c{AMimU}!XxXj7koMVP)A&w>HG85NTuF#MdS9$}8RMNc-4R4C~d@FZ( zd^J&Ktsd&%cv^7whI;6B3aI?vM!+t{x_8Gm!%uRhUy`+*D)L%+1{^Fee8x36!80%a zxJS{<1`jAbdtFEq4cs36j-ydCk;jk&M#d6OO6v-7stP;-OPH6KXRP(-{UEE}0lor! z8-xa1d^p)u(2*w)v?6R=pl4mM_c@ZuQ$Np~3swQBP7$d1U0!1p`Ji@y#8i!s0BdY> zT;ylK*ZALJL=H?;JYy7qAz0>t&p}cGOgubF%xY91Oo;mIIN4|NmySSLvm-l6-y@X2 z9I^6vlV;P=HCY$n109Z%G#gw8l-sVnMtsy+z)7b4!)cs~H5QOb@Egeuv!eqK2A#U%3`f=J2PbA_!(%;(| z-P>4oQI4-3F3d(oiX!0{wL~5?U><-zVIiDsPt=Bvd~y^;)&(4qU@cg4NOx5k^M4GZ zg0xVPKeJj|#?#7J;II5y(#aqObJpz%qpMY;>i+>pZkNp=tH*Rvu-#}bs!bTh?OtW@ z?UbhR)cO26G=6xiQYtjcYNd-2pFUH<<4eu?ZpRxI8#d3hxc*LHMm-6j8O}oI_6%V= zM8M4Jvqf>y_z??BT-qa1V*-XYPN!Jr|Fgskuk?#F^}r{+s?2XC&k*YT-qhy4pKDgK zh&YTu2nkI5YU{5Zinol*6z&o>oix`M@4X#9V!m`mrwYyoM^i-a#bjbQ%~auR z8UEM;a;+7h6y5^ugX7fz+^URa7I*y=u$=xw*`1E-9fb4t<9(oajDiVMrU?Jn;NxIm zF-h~vl%@s)%@3b^`w19<WxC0aO+O3^g?1h!c3sd)rG`1=JcOJ8F*Acl#swr4#0b1?A}2qYkCVe| z&5S>W6NR<|2A%z=yEbcg5uI6C-Q?ykFHXHeN53<>16L}$a4_f$qs$mXu3Ors^l*c| zO;TB33qlTZHIw`Q5efY^?jTy%-=7xq2ndn|Li7~Rn!9lOYlG-CVxnEGERX zuCV|HGby!1GxYSh%;1wU@vTwX4muF!nrVHs3F-8MU z7&M@JLWf-L@gDue6;j5IetR*3avHC!22j|$`vX*O{+4(11dXgE)SyioT&a&6Wr|j8 zgPDS%oe=PNF;Efe*&ixDB+*ev2FFiKtPOol^o)enNvwavA}E*RKe@NreVLf}*cyOA zJl4w?b5dkU7OxcB?G zZP<{I8`=_!uz1riNDTneLqRyLXxaDFqXq*raP{dFP7(&^Z{GtiPbv_<@aZ9_$XE5} zyPUdqfHAaH=4j%(rIr8Mwe2SC%Sg3i|dHKkrNbBrkrnTZ-%?o6`h;y_sA)%{hF zC^A*FF5z4H1Ph+)L{;g%6lHRZ7g;T!f2O`|V{Yyb5Ki-+*YRhpd35_}{y$tox+)w; z6+uWqh`0{e**1W4a}`x(S$2(5&~le znECJEaUx)d(@^}wf?OEn1d-a?+$hi|NHZ+TAZeRWP@Ic8A!KpON0$P^)2!1a|Jv`Y zenm!K-z%QytPu)w0NC^4q6gDKpCBr`6Nou`3v&n121+fla1-cdtGP0s%&5fBahp$@ z)qE8D@pofPC2PDDJM!JhPywTTci2j!mDvbihS?)WQG!q0c;f8JJc;>-;8&t*`} z)!g0zOrNc0K?jE9bPteXVoelz833djiDA~x&$3r^?U6Y$J^G_0^rrT3b5dRLUat|B zE1@?=Ov?)xp2qt6oGJAEWmNA5L~B?I(IPPY|JXdSOF});{psFg1vpwBd1>x%;cB&L zx#O9-ksUH@*Tr=?I6VWB+>vB*KttyZlmEjYQWM@Gx! zdZ*0;{bQxU+rKZ_S$k@Y|DK?(0_0rpb583Zy%aSYEmy*eK(%)6gsosz?%|$;um50$ z7a?`=2ldfm(+3>wEgjcw>RGbb(Mx0O_A8CC=X7_^4mn#A@bZK}r`U5U$)Ak;4Mho4 zg#TcKL#b2@wo4^1f$Ynv+@#8qI#EC48Jcvze%+Y=U>U4^)La>B%sPaj2wQ zW#=>{S!R?oB+&a!TdsX(h{k+Up=~f{S<*(@fY-pd_1W0mo{p6D#pSU)`NaVel@6SO zp;NAn2GJVZ06~KWxbShp^B%wpFv+`oa{JaltiTAMg^CnouG4?9@OyKhK)>`Dj>W@$ z3L+wzn)Y=)Q%3IH9`CPkFutv*^=&8foyYrzQ6;KvI&Gfo3WCD#FE|-5$AY7HR9n{_z__75UCqfFsrU_wB>Y(BHJ&Ag@Tm;^kgb=R#`Q_Ztz z(6XuT>>KjS$l8e<$=WrPRMr}%sO!sdmzV{#d%ZsBY*SfUxQIlDfPT_INMdnCg6CkT zDX#wSh#%uNGIowe)zFmVy5~;u+pDsl7_U9+e!lsw{sv`1LMSZO}bl zPmiQjLwA_m@@=L4MZ)XkOF+)3p4JaE@IF8Rk1wXTD9dvqT+UN{L>fZrz9{8y7chTe zn---eZ{IW97}?=#Z;?1*e^oAb>2hbCni@}RFp{}`OZH?zo9*%7-U%!neu|V7U#^;u zrRYo1LKIs;S$t*HkOsBsHgG6(l1lBW7s!?X6W!CK6@!GHg{qek<=8{ae2v6gD zo!-HGT`R5t{a7VB!WcZ9{(Zzq$2DF+c`WnelukZq4dSMp-&;xzNeDJTnLcjk>XB$z zW6&YF7(R_pJMn081I!k#X?ryEP64ZZ)(huH(;?bR#%CY8`k#zn0k?x!9d3+cMtXyn z^w&7H>$+(L*gCBWo3+FXuN#z9=W0R!-rI2^ca|QQGIvrg3Xvp)g{NJW$^p3q`KGGr zfu~kKeZGqEAq_Gs!eocucQUOIEVKIU<1Pwm149TOQt3yHz`4v5|3H>@!jn`^+N4Z! z^_kc|tXag>1MujvxG^@0%8KpxZxupaHV5MHmGXWqYUn+@LaSD*$?UjpN=jx>6!FIx zYOgA_%#m*{HBKJ^0&GJ-SEZg(0~{X+2AR zLr-n10hu{8u+l^Si^lEtD$K>E55Iq;&g#3E`0nr^g!V?yCQi)Dh5jPBIAyh+VKgOLq zZW_5!#QO!u*vu<8Rdj<&%z5Got3rLs&(ca4x}ZzxUySB-XMxf|#Du z>AkwjwFvU`2)K&4u4WP7FPo{g$>%Ie%qOE>9d6V*Iq$CUPm|w)B%?FD zf%W1lqg=QGCRCo+!3+CtE$?ajR5@%%(==F+0I})~NGG9x8tf1<(Q7&$MF~hhKVUw{ zR*-p>^;29U#r

      ;=DF9zud+Cuamyu@rurBIg{qs*3FisTl=cO&KJaR<8REo)Vwm z(;4x-kl(kt@I0nWTEZk=Ya^75zMV9>P7EJO;hA8&(NHoiF z1I*fT$Sdabma7%Rbw#cPy=_GAT3!@CDMi#CKe|dFF1SuSu$E3~02sE8s?Yv5>rdY8 z9{}8k`X~e%@7lDPF%Kzwj9Q70J`@iqt24P21%CtcDD znBgAeNL?Pgu^mVQ0L3!oq=|wkyp45L@@T?i;W}E$6__<495a&5yi;oS`_!9oZb?=2 zW~<&7oE-t)BhOSZ7jip>R6hIW>lg-uFF=Mux=-xF)|WuTT%}lU+oq^{IIqPOyBl8+ zQgWbw0w3qZODTINYvI5mJFO0!FHUWJE)WB1)As@(c)Pf2!s*Gp9&V_QG4aj*5| zz7x-V^jb~t^k_@qX}Au1@uY|Zg@Qa%W&ybDi;oA0+6;o|+p%Nq#-cY~KnErOOM$=ZBrn?qXNhF^ zJGYRz=r?SW28kh(;1q+3WGe2RN+%QRv_V)GnLR_f|i3jvg?0FaZcDuYdA3Rz4HFshZgj-6vD*6j>lK1{c6mf?3R(6$m03 zyE<`SXQ5s+Mzl)+J^{KIfnmiDFR2>})IxR_FwR{cmnVRunkQD&BItlLzRJDU|G)Ru|thB}XxN0Vs~ZZ<_PtKU%v#di{rn;2~5 zBkZyZeG71Jc8Uv%iO(+}QaC(+O7PKi3@b~%4Ua!5(#tJ`+>6%&m!zqu1Iz$W6%Gq>ZCFkq9C@hp;3@ORU)<&6(uz4PreWpB zp+x*-tECM~fUbPnDqYa(957Gx!0K7I$zcC23><_1D}x}Vb}eIdv-BiR73RKE#<7{x zuQe$lb~M}7YEvA3XC#f)GyksPU>-3+y-l*pwB+?__Ey4q*p7c$ac({SSnI2}}e= zBB2CHbwp>Qp<9p@$^>LNyjM*X{W=NE4wdI_%^G5IBxhb;sFkrGB?b0lWci<#JzztU zS+$TyTSI=bAmcD@hVx7z=R0gNb;}twxlB2|kZm|8R$SrE#f>qvzlR6o=a3IRs9Y^j z_1w;HEAPgzF?y4+fb!O<55u_gbGR?itg$iPUA zQv{~DBS{6O2eG|xySq~QlsD^UP9y}SDB^qoIrZs%Os(=+zpntzs^Hjn9s1((IBS5akWs!lV(xQCUxBhI4@(MsxJ=ccwOJ77xnGo~UU$zLQ zk10ez+jHY;Z?L?W4>VZHKS7g(l9o21$op~Ic)Y(SsE&WIV1RyLX7Ho&ImJjT^sz>! zC2Pi{?k}PE3+>Xvw&5-Jar9c!tZdud+MhG53T^0Y*(YB1IujZK5GkiviB!fQc#qK$ z4n*?NYPW$7WAoElk;+W+WgTd7kI#LV8!qF@-Lm!pL^!Q}1bVbwoxtvWPb_dht!G3q zIg;twvrSSB37xe(w$Q&JWevdI_Fzv*6FPb!#yg@O53pXc(j&Hy!K2?;5;Tl@*ir`6 z2;)NcZi>RFOGN z3h{V(lF~`Q^r{V`coV3wGV;l=j_BztS2x+i1o&HkyU=gD-PZ*KhT!My`(*K}+GA|u zo>8BvgWl!83QAQa{0;EN(R8MRCHdljF_fz^s61ZsTW0uucP6V(cz407PgqZtr&s28 z7ds|2#U{x{g?G;YyC%!R?bc7L{dq*6BYeRvz8&lZ^CQ;=&{&@H*@dhZ@!Lib_s!ig z&3X+jf;pt(xyR<)`}e>B7!IT|I68cYkt&ZOca3OaMOj~tFU^xMuRX8&XftL zB;!Hl6$67eYD{0XSI;{c7Q83pIMMR$tzSrA>_cyQS&~LSJNaN0%qtpCzb`t0*ZVT-i4aGgF?Mbchd4wFDd@D4n}6HJAjP+)}Lhv34955%#X zF*CryPA zvMf@>MpgEQbl!OM?$ZX@DYf~N4j^2`7+aY?;i&W8{D z^70Z)k^{o`BOgM(llyZ-l4&d6IzbrAvU-xu1Kg5R zejaj)?k^x#;oO75D9&Y{w>|fn#yuhcxxb!ifAyo>Zg^sS&{H*FR_T7ke|u7-g-`Z#Wc%vVrl_XLY70fd=`bs>7byGISNh= zosJ-hhWn2dE{mt~Z-fz^uC5Eel;9bvnvcRiQb8OH=yxnon8*%P@7(1~P&i{vtEWrS zKE03suml7cdV??0N;dYwlGY^lbz2EkDJ=%q2t-v4>G8L<$SIeaNkdUu9QAa`d+4N7 zk(X62J{Xq)M*j(BBfb^%mIUfxd9G`thtlbVd3ms0NDVVG0Wj@$CRV0zE7yJtcMxDu za>C8w8=Zn(i3n@^*80P!J~`=U6?*9eFL$Rab4=yy&X05$I0+(I)+q`|F7Ar^GkNuD zF+_^J^0;y1&IhQnf`Mxl^PGq6U#>U+-yhda;?FXkd55~P zrSN4=_asUdkA5IGZo_Z;@+DUI(&k+kU1eg^w$d%E?S0)oOvTUSyV#}7yPi{@o}5(g zv|x;ZQEA7Y!{)}0mk&~WCDbfwG(d6rXjWo4G!t&mI7ToXYE$ems(Fm-i&AUWjr zJCxcV$@wPUxK>U!I4JnWvB5k=iAApavyj5-3%|F+nNAxkfnN&cCh7JXbyi*6^6ljg zo`}31Sh;iysU7@6C4_IOX_=~it~s5Z<{_??ramM(wOQ{kS1%f6MaO*R$$0~=>?qX$ zpueNlJZ7TT2HRIh(^u-|eSH7Y(}zhg^6iWKSM-B~$Bcze5F2F>1p>2s5@c3@RgLo^ ze!xdbmvcPDBGa~{CzW3u_~z~0`Dbj0no+FCjyp!2+qvQvs_O`P{d|L8Z}`Shjg&v^AEJP!2SkJdOA#R(ds6T~C^ z-EI~=DL??w+C&+A(s*@d4vK%f9kR@ncJe80I0xE);c=J#Jo)!#`qdO#jOJ1ao;fXl zC?syum5s&6y9cOQ%Su17jO5Yb2awKuxMa$TFZ%QR`AXO1HwE*X2TJ$X*?>$wG5eX1 zRHEd<_8+eL+sDV@l}k0hRc@i6FO(FrL(MjnF125(*GFdRIO8g9wt2*a9XzXhM(Ok9 z2AcU?@NPXdUIV2lKfI!Atj)k2*+T45n0%0EToSuBQCdeY=3P!NVflexWVed&T+Vs@ z!Ei-BGR=5Bg9mzbxbHu*ab$JbvxY8}d*Sn=h((>Td5QOOqCJjL-7C0oZ}+=2L4SI3 z<_pHe@^hJrFG4Z87k8)EmVM2?)Uh|<%_louVZ_cOKfS8Ue-ZXPPNIDfWzs6bryOK9 zb0;*2Pl~SU&Mlmj;wh}KkMCYD${)#!dX^oGvTwXW>`$<=SSY+g8+b_gN9K6Stlk(J zNE&}EC+Ef|cTmdHj9R;=v@>1g-*9Ga6vJ3VUcqag6q1qDFLa)LH3+)44!Bf*B#5X<@^%$2{^ z^ops1!t{2U%0<@NNtYZ`#x&Ohu^p*JQMEt;Bkzc<=JxlQ%bA&Xf{?@a_cePng@=XL zDWs-a8O=xJe%|n**%%fTj0Gn}Z#B0R_++KYmTm=E9pJUz@#h*VTzr#1l^<6`);Z}C z`*Mq0lXTfU_yy&n5dj_d3j&3n<{A^%u&>XMRA#_mqS+wB^< z-sP9))kJy~)4aUTTCHS~X9_&mEcvQE0QLaTCbfBL( z|Eb)r-liLRyjVLkYA*L-y4HF3Y0B36y^~+EdU6v2Fm2561^aoO{oHr=n}(qQ)$VmO zr?s03QlYj-x-aBj>gVP^yu317tX(MGjJA5rn&kn=gT6c{@t6yk^Q}WgU-};ms1F1f zER%WFgj<0EjE0+hSL^j_yW698d8lgY^~*?{lqR(>l2~u8%cNtAl9DH4f~32n(Cz|X z16AYC-K8kg4R4fmet-S3?bk|_DPu;=hUuFz#!!#(8uxRf8mGD1?Fsjaus!ZPBPj{< z%LgbI`lODl1nM+;^I=h46)A}l2J7vBE-Uf_j&U8Wwfsrc$kDf;Xi<<3O6xe}mYw?9 zH`Fty>|o{T3fYS~@9~u@_tOx@hb2yB^)EGIZ?n$#$&PZ>)fz=>#G|yFL=Apdn zPDy|FF20a_aENi~^H&K3Ji;_&=gj9!pDef2d)jY>QCuBSm%293oT}ZFv3-?bEEw{t zNT;EJmpL%0ggKB@mUoHtu56=KV9CgHo#Pq?<`3d7&*%KRiN}T>ttibxj4NE<7xlr) zi|%~HpC&rd2s{erdRlX7ZW!V+7nE%EOX5xTZ-0 zsi1Br@X*<2BJXk>aR}+@gN?o(ODF9>D(sPN^p?MQ7V{hST5ry7+jF|OyK;+SCBfWQ z%Dx&c3LQIF+NMRBrqjN@Pi&A2JNCcOks|u<59{N+B5xfSIedJXsW@&TF0H${t^AaM zKI3IFlXiLO4q-_Ud!sj`L4Gd4>Y-{YyKZGt{|K+tgA%o@Se{=(+2m^`Ln22_ub$Tt zWD*nH$_!fwSd5sx&_U0Bnmc;j_<9OGTd^D98R+^%C98A$T%osOLTvUTvG|93))Xu# z4B@1fU?$0)6Z8v8nxSaDRQ|mGRxBI>n3n zUmkfOb0-TyqL9F$;ptP3dSHH&d|X_z%+*~qE#Mn*kUY(Uw``Chq)7;o=FlS&1oI2^@vIk%9(e7=7{JcfZ;N-R6f-#4bmwAi{CUS13!9;P%CCM+X z<|JkEEQ8(Cyv}(B*3usomH5cE`bS>GUmo3V{dJX*M+nr^MET67le(~;DU?R~CQfyA znOF6#%t_PH>}rDPuq%hX)GHZrqndZ;77-pd6C?^%J!1m#mvxQoPVV;fT3OpubI8_2 zdNC&E3;4#9#(8NbDW%%$JO5Y^L|2+*$vmFTOPl7m9(P~w&FwVz$rB}?WP w4OTpHaHoVmP5(z8Z^!A~p^#=3_K7Rf$2SSsGx?IDZUBFvkF}IhiqAv;ALB^UIRF3v literal 0 HcmV?d00001 diff --git a/doxygen/images/blinky_win.png b/doxygen/images/blinky_win.png new file mode 100644 index 0000000000000000000000000000000000000000..1771e88630822a41e003b1370a778b786128ece1 GIT binary patch literal 15865 zcmcJ$d0dm%x;C7)yY=)`v=v1Jgl$zE04X9w5R%(iN7UF|lT96TplYap^ zl6`5!-?+S)&_aD5c)}SucKBp%yqfqP2z2e2VSga;n*;8^w}C8kxI2KKqcN@@16eQs zQx-*PieJ(Yj8rv|ovxA@xrXgP(a5YXP0&2k92|-)Flm@ZkpmQHHFu^fZ`avaRAPW> zg=k8HWA3tMqEgjyOC}@PG~viJvY6QE__6hsfugIMXBGl^PQuX2^<-?CQN&?r-*nAB z^U2}M76vNuZ$jDRaoM<;3Qc_d5rx`>)Eq30SAGg-S>t#45aNOjZ`Oq@z-h*213 zceOQ%pirEm&k!f?D3b|;qYgDQJtcc>oI#-1ss^%QepzJFilRnNUfiDGB6Y1aGl3)> zBbuRx0TNsr&^>~%D}^j6UB`Cg%u}~enaRQzSoNDdGwXp>wLGIx+?X4a4PEvGmkJ4? z)(<&C)5<+X-pZZ}T>}HMKGOYWh;G0T$92C*E`_WtQ7doa1hcdOA9B0d#7|0`X<=5{ zEIjC)h>`KW%ozWHp;Cwyar5R2Zy4Hz*%6YRh(bLO_Z?W|81kV=}gt)tYPJN5v`PQaAF~T(LD~;ff4@fmAJxy;&e(QS{*M+^dqdLQ|_YD2q@{k=3* zEd`~bp;JrhX$RbUpy4&l`;nKoCwzpoM?QNDzKFD4gZkXtln_3Is3b!0uGkH#(b-)n zJkIo`DE;tdVH;gnf;*GJEOtnWiptO)!m%<$Uwoas5HSGs*xRsZL|i`9?92?{<+cy1 zdm*J>sGkVB+4KfX2EHEEB0J4Kjl*TAG7=g#G76f^RMVC+soK^(m5?D@o_y)^A{E$^ zr2}9d0Zp*27t^@o(n@Ec$#|I>o?blD!3aE2$)gy0)}J8L6;sRA1CmrjpOR|l-Y&_J zNK?t*!R8eTUub)y4_}7esJ&?F8JNur46Gy?FRE`%dvX>89~!kU)62s}F5nHINM^hG z_SIipa*QRg%@c4eCV1`L2?Ah~CnXAi`*cv)rD_Bxi4Z)B|L%P~TN9lcL6P zh6p3>xU8c~yTl!65UCbxg`VDz9BU1+FZCsVxYVDMy;#y~hvc@vIk8I*w+Rk|lA`gkN$^^&t#ohC7=BkbH?$go!#y;tup zKs-u?>CuO}bc&PnpMZW`6#9&QsF1^vI%-GZ7a6WqS+!(*@Cb{59G{+@_0|n?)l3t; zliFwPiYwQRw#&#TM8;OF?het*z@1H35R?1%k*w4yiA`5Uoa}JX>V72{3v}Yrsg~)x zjCeKa$t1+n+O>euZJHYx*dkwTrzkFG7p72^e(lF34D)WO}j^apE2@{8Yph9vO_CuBEh<4MQx|TQF%Bc62 zo)x9L&OqyQip_ASc5vxsGFV%|&Yq2y{Kg${J@iy9qU*kYq3dQ?7En(RwDb5psp;Tu z`Rg=bknP-CTOzYIvIULS}es7Za?7n@pXV#bhk zE$HdD!-NyJP43`TV?QfgMF61NNP8cX+iJ?wxDCMn59^8n?C|tLqCH^Hzpx@52hy_H z|0>H=ISu52=QwtR4#I&xk#PwDd0RK_f2#W?GoDvA0e$igZ}>Fco*y|`|F-J&mTwc0 zyGK@g_Uc!Z4H-(nn;tXnpMMKXfP%}`-5cIQmb6d7KT*tfnvh8VVzGA95lA`!dl3J< zw#N-F+P+m_A)WVtG6Dmc+cK7#{I|kgIa<)G5bs2L<>%T-R+gU&-MI$Q0YVu*Czzr3 z8%O()QiZD^Ilw!Y(svjkEK@X08C-m#ro$#}oKwa@mp<7?I!-^>9CeaH_HFF^1l!2A zaf9)gsXkC>ut0Q3SQhV>7{&KA`B9iRXQo^K4Wv7z|KQ#>l%==x8;fAMvOi`hHpc^t z$u=v6s-y|Q-c2OS;LqT^NpF2iVxp7K6FO2fT#=CouJe|fvmj46SA*vy8kM6x4N_iI z#foucV-^GVOka?TCx$3pCa+yV#9OthTOE z-->M6mP3vE%CEZmtjl9zF6)}=JUW6P7@M&Njv?Lg5hVa$s}X-Aumu-I-7mU+X#tFF^NWwj36dl0`T*2CSzla3 zPs?>lW%Tx=!-NrweEmq;kl-LRn5EQZ@U$^@@McaOE-4wWE2flps_kOtR;n^`ll?}t zSkmZ_eYvWY)<=eK2aUJg47A5YJ*U+6PwHML^FFzRG+yZQsFw#z)bdfReJ(MXC*khC zDaYa3yR@;$icP%6$tVZrXg0wyoFr(#i#RK3Hg>v_(X@wklTsJvE%D7IF|M!QhB2|0 zB3M>6DD!h+9=^$4lNSd{a1$oSTjBu3R?sB}TO1eZoXhZ^Mla7SEbL;yWy3*Gk!{RQ z1{{eEB+XrP@Ghv~KBf;sE%wm-9LnSdeT(DG(Hm@k3x}bY_RuU&7~feX$M$aCLn93r zD7zjLWmL|SER_04ebFYnydXN?$CpG4BIL26f!2C#tCM_{!|OoJNqp$j+25e=y%5)M zdqyv^dy}sS@Yt55tGp+c?g-E&n`)GO17RW_8O0CDo9-E{?V{P))mp2aK{kRpQkRQ< zm&N2*guE(3qdZs;6~oTYUs~~~Z&_ZxmBC(tcpGlK?#h~`)gE?WtiixV{kd3u1O{pF z#wCs1=5d1r?mZq?Y?aPA2v+6u%llk-+uZXWTz4-0J_P$D0&hy_ei0bLU)fQiHYaaG zyi9-1J+wppso(SwW}0)SJZ%s)=Qq9fN-d(c9bs2wEN}0dtOCK zo+HjYR?|TGrrJ7&Lb_a~=-_MX?(yBmC#}>%Dy#-+)_g_pXY;II=HS;pBc;X+v?&#@ z1@jkd-Se(ap242QjyL-`%)lKVup5MUT(R=QT(w-n;)BAB-8o5GAZU$ zLC_Q3hM`GDlr%WAIKqn^-Qk1K=eJM=+WhDW3u2umn6lCzf!3wXi>1J>4 z@gO0`4xB$T+x43+4x8I55Ruwx?ECc!*QsHk{O%-vw@m7dWrS_qEZRp&qxNfFii5`O zDzz)_d9>pW%=}4J%ju0^nmjHs5_uGdC3THHx(oM}3*|fc&8Jr@J<(~lv+9)^mpXE% zDls7Z)c7EqRF_QKqLd@;5qTl_JuD2TFiaFwe7GQVXZL7!F0xl1FfFk5%cpT;2Le`$*u@~VvF7uDJHvaGpuaV(YHuy9wLr$e{t0H#azQCo4$1?e@s*V#| zQ3sl?;s<@Ek2TJW$`|hT(I_y^H`w-#G#o_JFN)M{9+UhgvG2n|7!bNNno>3+qYj5R=UML1i-X-j;CG>8Q z{OV~7DQ+~UZqQ`iJ^MIBZ}GY%hcNz(+%Rv$R!F6joZ@ZDGX2G#6|e65Z7Ww@8>0rs zc>Lf)xf^oi2&=rx^Rs&PQdKXPOfZE-$kX%;;r3jx{9sI|h#fk>mWc zb#?YVcWKHZPsS0C9D-vq9uB6o?8$NQ79%Fpf_qRmI&)+((c?t7@Y)&*XHf2~w~1TS zyUAB3BeJ9SH{$;i$S@dq@D6zoG-@v_>eFw`n$u96m>G>3=qEdZUT%DOkf7_K_Q27K zqt_Alb=nXavP=ZJwzK?Q%CB^;2MFXC-^83zk&Ukhh~6VQZEkdxLPF){>(Nt|&v@;s z@i1G#W^cC8&M53=H&0?L1W^%$J&R+wEl&>gNtRjFtcb~?Aa4g+OK4Vc2zFfq(%w+H z6{DYu$x=F{yqtQi@ou+AM;1~Ry%(v!@jI9mliGF7DrG5#LE}@?=NbLBn-MxTQ>A$Gcar@l$Au_?6^v|LEMEy-mfPG4kj>WVPOSgLSo5Y5a9- zt?Ual59}@~5^!LcfT6lM8)@Ze40bP>usH75A3^+%JN5o#UQ7~fs@WahVVRXYkSXYN z313HJU6sp&$PZs=QF7x_3Qv8j?%_))u8lCd@!G@PvT*I;xHw-uu{TFLzo| z6oPl|8QI=foWMmPDVl~BcI=VlhZ-Di9i9<3Go$FE;Zd`CC%n$iaI z#r#C^iw%%}&Rck`iOoX9upuLj!kU`d2$}N`uA}iI=|BWvw2m4Y>MIa*270d5cw4Je z#(HG%sSv+6((ai(lt6KP{f)$^yDk?cX}(E4V{Q20CEk6v)IBpCT5j?lEY~})-yFBk zhsRu#@oSY$7fl3jv*!omT&<`^!Q?1a7MU-?uPgR5_^AaEQagl9O7gpkoOytG^=}uY zr~M_}c(yL4OA%H-7Z6!M!1miytL1AXcPQrqU|edtAG&bz30!KJ z<~$DUb@`sxY|n+2v~LVGL{Md;lU6wIc4oBWQp|jEwdrI5kGd;ULDR0kJ6$Rr-k-b< z%50vp;vZ1y*^0W<)rI-3OuoaB&L~IeDT*+JTC6o z3FjU=ji#b3>p8EAlf16F`sV+4{luvJ&UV|;7p0-73e&e|EC(dkm>=tLSQ zg#7|I13wqRaOjEcwI3ENU2sh>1)Y*-j9naL9!Q!^3*a3TRaS~V^-gbgkHw*F;d_YW z?OA?-7F34iqW& zB5dF?<(7I20-Uzo2W1DPyCV8N1huRycrW0)f|`5L?RA5zPT$pWJeQ=<2KTAkp1WK z=y5y7I?&&GUWtl3wad3oAs=2FV*wL4yn)p9!HdeT_g>@t{BIO1GnDRn;9=SpDV4OqQ$zle#_5s z5#+djEi;eFqEUV;$R*s02~+%#^05GGNJ)%n#@iZ7erqXUsGGV8or0UKUWxV#Q;%2L zR$5Sn0918T=(M(-wEQ{7*R(%DJ=seu=+4DenD@@P3vggG^2Z^zx|Iw{;2!=%H@xq- z0D<#$2?pSMHYr5^y4JArB2Yl63J_RmQsC8TE*9d7P1IX4^)?r?7SL^p_HN%^9bzO! zkFOk|O**ZDG%#XXt+a)}9W%3lu5^UX>R%`CStJJk1I;C4BKKyJM$=r~Yuz707~J#7 z{%+^;G}+1qz+eECHV+x}x1&e2`l8{$XiQT@&F-X&V(xIuX!aj4kuLTF@MQ0{o@xNT z9p$*stW+#Xa{#;-5q$!#`YWukd-Oo%;`LVKU6E*PCxZx8L*gySdwZDQpMs;CE!?iW zoFm`$cPfx;qE~_9k!1Noe|7Fv@yKWjC z=3^h8Gc1zi@#aw8!M}L_auIcG?&0Mf5$J`Lrb+nMoO^;QaSof`N7O#Hxy6q>#Gv=L zHl;`{vr%AAHa&r2H{gUjK`b*_MY`vCetGrREBzNE3>k`Sw^ZYO4&e$#JU*8GMk*IP zc|bD$lW!UF}Y5KTh<0}w*wjnHUx_dOk zf2-&j@7zou+??oK%i3*!Sc=&!V1WIos97CSs=wMd=`rt3lxxmSVqM_;P$UCzKU%#s zDm9cKXFHqHs`4$87wYqplBQRHlM<6joIkqVH|SLLs&1J-y(jkA?8XC^^PlYxZs(9_}-%J1OJTq z3i%i#@ls#YjLfA5)uk}~T->XfJaeZO&;9dL@$Dx)kpbk@B#~(Y>%IE~v|pm-zg9{O!6`RA`8E#qg4Dn~zOGVN8v0t3%6ZqVZH%u>3)1G8{?{xeB$<4kiCUmqSR2Daf# zJp-}^3U@>+(j^hh<|{@ED8U{^#y7G1c9Nd)f7-)BkyG^c{F_Uy z0X2f<8s6Hj*;vhXsAv%VnZ`qTu9Cs z$$LoyFwZD4al}^lhm+|#({>>nK2YSfGgzT>3C}GO30OqeI>^l)fO)NCt~|qSdTO!U zX}k3K_1Jj;QG&0Pxitw76hQhY63)V_lq>f}0OSd35{nXHsE#nckop7txVC?L?ycB_ zk$VhK@UY@E>rx={I(NsV zLeB#ZBMc?n)_OB+FA(5-N`cKI7Rw46(NAu{%VZVOH z|2Gim(nbKw6YGzQ^9}>8YkKR8y+$i>BRBd1K<48DT?f$C1pvt`w(k;%k5)Hr`LA5{ zH9)~tB5Cv(>+?D%NNpFJ<-(X)#YSppvs&r2@SH=X3HYJ`Nx@dlxMK>k;of1%DN}z-2sYDE zGOpMy8c&zhtCd?>K@uLEv_~U(e(Kk_%RAfBv{SB8y&+gLSa0ht0ai~}3-SYJhdujcdvRU)rr())|iytnsjel2HElt#;nA-#;@fM#%wKz zwoGq6W8BVw^iH31P1xnb60kV9_QuIzO0h_w{%dXdY4y%0EF7I*xzUxDmd#50|59J& zv>BCrn6rwB>TD_U;6Kr5-vJE(7brGzrRW>axz$S0{BrK6U5bIj? zabvYA#azsGezFNw$0&c$67ImHs^4g$Peo#ZuF!oYK19D{!o4~1m_Og1q7TX(69@g5 zq}FPs$BPo;#vZ$idbqHhU;;kkedT6A+;(-zeJ(kH-1Mt_zR4yBp!^ z+2q0j--V+bPx1L1(AxSnBWZlfb{q|dD*UW{~);@w5+JMT}i_9p(@;?5Z#%R zM`Lik4%0+madSTgyAyy~9_Q1~WXz5(N0M7(r6H@3>m7B_B@+1^%)pOKj`n^Ffbwmx zKMuhh4zjzu{bdP))4a*_x#!IPM28h6&7w1w^@3OR#e*N$n^)w849p2g@incA_1?yZ zh^-P~-*q^V8M2e249wwic>**R16FISGw>0Lw+YRiN}`82a(K*z?x>muAD(2ZU0fD9C61wdJ`e@4#jkTs zHI}4dlbw#bY>5!Hx2Wjh88|-?3MOerTky`w(zAK%%_Uiydd5Ws0JV72UCm6BCJT($ zaQw;}e?%0PUO_u>0533UfCx3FnJ(O88m0x))K*l&_7v%A#up)404pW^9V>+`P+OH% zWYh9`!F6etZH#O^0TnBT$-T1>&J^ZG^#Wt<87m1|J2@2Xl;1q5j&=$5mhD`}lPRXM&)q&YtbNB=&fdFpq9dZ_nahj2Cu;aAI z7hEj%lu_V7e4=imGc3D#*s~(4`e5p8-K~@wRJVpK#_!of@l*RdHXq~Am)*i#nYERf zo8NNgB?s+$?l%oXDgjJnzOrlNr{jjNV!}x?9Zl9l`L%%wPICiRqSZ}`ENQsX8;ray zf}3OJrN(#**Na)cXpL9JT~W_v)sN`72n7s=Fgn&Iud>T{IQcr+xu8|kfu@LHo`fti zG!KB0uo%f5?m5Ks%;<_nV6+hZ`iOz?rf!sye~&?AuKT<119;S9k7Cw+mDSr_q6chC zh~|u1-fvYCh``b0Ta>)+l3Jyiu&#vveld* zNnPVU1h1R&qlA#;!y}mWL!Z`}HxK4fjw%Xf_OZ^O&c5zX+rv5|+RLz)(qI27aIa0s((cb{Mmdb%LBHm0Z3L$4R!L4*wqE3A2( zph*pil02W1Fn!ij7%e`tzr1CRlJ58CQ=pLh=)@i9kFA0CpdNnr9+x{W7ieID%9JFS zSn?v`*=aNtJnCnhx0(fJ(TLS?%6RAWD0!;dJs*+5kH0asT(7@PM$NVUsK1wC zBl)?_H$R6Q9B8aUyy0vjy3B;!=3~1h9NNr}*mdTdz`NX8r>*eOaf!pIC$khz$c>@1 zMKG)XwEvexGsanG<0bfqKmV}O$+@b+I!#*t4Pe$#R(^I8zT$(&qy;9|?3+VIZj+Lo z6}w=F7-shr+9vxu`t{5#fA~}m#NOT6Bq{!q6X=_R?s=h4Azz*Lx8>eEtX5?&5pBHrBkDhl0klGX2uu`lqZV#xxa`+L z0KO0c0QQW$K4A?f=`UYhWU!}mRyM-Dya?{q513j?D=W2M~43bM9 z(&qX~GIeV}*QDqXe=Ya|{WCV$IC}K2)-tm$GE2NNEXYdVKK%uSu|Wc+$6)-qGR}FA zXgqu~v~O*ddMXqK#Bb}}8(%`HUAM$QJ5jQTS(=+1xIsrECU3}d%b+Fiq9FQRmH5RFtiy;^y~KxqbqAtG1RpEe zhLEcR{ABtV$GfS{{DTak)b+g6xE+ok2A65hUUo{frw;a$et0M$&Xl1N8N$sUqI!!c z6daDqiV$Q}Nzt7c<*^oM?N}L)_bjeIY27CHW;-=N?ZkKk8i|Q32#H#qZ(F^OLAOw( z+#<$|uc$1uHuCt+bpguZq-aMrEOBcv^~}BY<>AhZM@8^F_8_}Bh&f!QEdEtOz60)g z`NWzQTW5Qi{Uq=z;Ngfh$;pWTaI{w;hG2tGYrz1ZrLf!kr()~XoJ--k??~UG{Y`>Z zNVr@fmfEv(;HMq%3-e*CCLmaF4v5wOee+hOm|U~A(2kV1Vr>VyWw9QZP7ha#hC*>8 zSO{7GD(nE0y8doXjs}4xxANl+en*n?xZZ=qHu&+ABU(SKD4XY^)?(1j{DY^j;`RDE zr#_JtwDa%zlXX6SaK$5>KPZS=7QRkv2y#{3aFm0&8*_^UgkJE@$DKCh82*iJnDTZdKIn0k}F`}&P zHS!4gp*-ti-I4g&T`ylMvX;hp+t5`^ifj8-1cgvT5j3k6Xld?cTq9%N$k(j|tgekmU z&e8dZ^$X6-eFQGIiyig4?10gQ-^@Y$A{8J9QY53>pBd_Mmk~)P+*RLW&`?!|ld5f> zBN0KgS|p~t5sV-D&7^!p_;R7EOdx33C)y;!XmTU+V6-Ak@?3?Fq{j*1FCXIcn-(p6=d`p;gN#p%k9L5Qqr18^VM!gNm;& z<@4R$Y&FI*T48kmYNt5>2;nepv%zWA>$&&A8PhHHo_66Q*Avg~Jsc|tOs^QXi$Zpg zw=aq7Q}}G4-+-5YdCs~@_}D2>b@Z%QGLxhC3}}Vkcwumzwgq%*hJB>2D%2zV^%sh` zMIH6HBFRPVrVxzVO7&V*4bqY9Y%aN=40VJ#gFuflE9ZkykBa%EL<^z@YbO>bW9Ox; zj@y@uLg2R)Bw-y|jwU5K)dkvHgKr*8tr0Z#$p%|SeIvvy4lt(V9zdEDlT$qt-KK}_U8P<;%& zTnw-Py8UUct(-uVs->d*Jg0;PP!2Wc-n^CDefmFY^Zy&!{(sH_hMnw{zVz6pE1yQ( zdJ}K7fsds_`je4$ePs%=78_C{*^#4SlGZojd4WRIXS_Frq~p68}irC{iiT~hQXf;CT@RwZ=9jb(%U zz?~QA-)x=Wb5a*1sZSn~$yHL>R_0*EHxvbPP>Z=B+)2DE{ovJ)nM_xYsUu$+E;@(( zuA!4mD)^Vgzy zg>GL1M#Pxr>yaUtLif^*!f|8T%ul6uP(ossqM7}HWlM45h{Bx9f3%+;!I8ilJNSB< zI4dRwpW~DRKb&ApTu3(9t9tysA=YHB6Fz5yAXXWXo1JrJq&n>$W{Ubt7S4t## zL(f@HRa#QL1|j|y7CP=97idEpDm#h6{?Z?jhzy25YJxCE^`4NsQRp)Ap8tOWJl1Dt zb;_!`amHG=6t7EMVAj1|W-{LAm7-7u5J(TKXQBjZP1Sx@8xRRFFf~w>JOz*!N-QMJ z@fAQ%ux)E(t1x@7!3&{6f9uJgRSp}Dt z>tlpM&^aD%OVhNO5*FqjX51pO^lstCL@Y9CphUz$D2fk4*xqFDLmReQxnM6Xq!ovF z4P;^{09Z8wKrV`>#l1TY5Ep?6P$re5x6iffCaOLB(0|BmJd>uMPeNt{g+#QjI#B6mT^eKt$PP&C(VidVs0A@YtUt$Ajml03B^Xk{sYCra2%Bavt^Q}#pMZ10 z-@!ucy?W+@QsWFC+_TMa`6A;UEnR-grl&01gR!bOdzR9G31Q7IxJ~nuan}qmoa-$3 z+l*7sM|1ZcDyUf~iPXt|YfCmQS_{?;GkfCtO+A4ots;87FbJF7pC+>P3$y`v%bpfM zEX7pS6Ev)r%=5&XNmBq!vjdE70${H|KW86@qYK@U7iAMC**WKVEBqUEn}Fl->6M4z zJi0Zjd{|F2i*W$>)oZgKq3n@)P18r~-AsJx2Y}14bBKGsX-`9-u1ViX{YN5;dtN#~ zr+^bFnvs)$p4bu9Z}%$S{T}d&7gc1o*;c@9x`qTodHCQ9MBK!A`LKP4*Ol#-;Cwtb zVc+k)0zSt*seHdX~=+Upz6NxMhB0LEY*@a__*lZLFfF9^L}J<1L0+vqM&=d>}{YuS(ij7_AVvXHyOWDHYZo#f<@@1=d}B zJ&X!Wz^j7O;JlHFUdY1Ok~#Aqi5tNHnWAnI{!E*RKMe5rKX)7_Tniq(^aOZCCEf~r z#S3Vx2~a|61MUMzJ&zSbdM$sE^Ue54t-QST(Ysy&2hUi`-R|KP%W^rOr1F2edSd;x zCDuUY=HCq@W~KBv{DGyqeB&P@k^!W3;U!U3pk(jNzfrd9XbihJFWs!dmBr3>XqHvocw zF27xs(6_~lme(9CH>(`Qfbnyc$rSm!O25??FO$9k7%2NJj{8gTeQQR`{qxU&(8JFJ z0E;8XePa`WZM7nF2U@E^^b5v;-xlOM#r^0rnZI@etHrte-8UDMtqyvD9GKEO2HWWD z>SL<3*GEqn8sq?qCB2=ao}y*9)P#WwmC!79{Fo{mg|vhv1C{&%LSdx+RAeR>KK4b^ zY8;{{=?$+X}_)!)f1?X_($S6pb488%Xr2wA-`SHOaEA; zW~JJM@fWKbVVE5YoFYE}k;ecFBJu&}F!;OV!?T>inLF=#1*~ACIAm{(I3}O1Q(3yc zT|EUZvj{-$4;pU@banRADh{k>x>yb{1Tv`0=;UIuUQ@Azu%z5Gy+u)YeiX|N+1G) zc_bcBy)Fa$fd{+RFJ2jCm{a8ENDnmNNSG%?Jwx8Y@%O>(89@ENg(&7Y(w@^Wsi8UgdM z2FR)Thrl(2a(o$z7ajBusj|eFACzkW-ItqFXUXftQ`**ggn*tdePnnqm;Ph**R;)P ze;^?YaC;yn_n`1`!2b-hZ56bX*AkZy-lr1qN)!bO$PPTzkFMx3E-5%;1aRu4 zj`;T(W*XR}k^kL|f~%mXR{@pQeEPQLHs37SLk=YM`2VB31c3SEm3g-lmcyzhfY3Y4 zd5X4qc^fuY*g-dRs-;_DbCR)`nof0fjw~VgEV7()hqi@QsO5ZKel>yR${^bnPM;im zQPdS(o{^{qkaLfg1t}wHfNb-zdI+HOHYmeVdi zd_QK*>Rzj>x_4Las{7tog{vq@W1+uA2LJ$AvNBR?007V)06-{1MTVcTucFt0|Did` z=(+#^*ggM#2#L(tqyWG>fUJ~+hR4!TD@uyy?CeX{?QNUv+U?6u)Xy)G1fRT4Ieb$B za&FgzFk5feyiYYh{hX4L$kWA@I{NiX2WoOEtDpdSxz@cs8vY{)9O0m$Ik^-*Y`o2^ zx?Qq4bvb#+JYBMRk$K$VYrj9nt0yhKN=(BG9k@>P8m=`L8e~QD%@=oOXN*l?42koW z%fWwA_*0$iOQ^8p9<#yy9_b$QDOzUhap3vPot3&MENNYFc&~h26R#QMStq7DJlBM= z_q_b3dC_u9#~ns-Pu}=^)5Dgt{zJKWPV`!zb-oSd;d2E}qK((9b_bmD@R?cayS47N zT+=Nt5i!PwwHq+j73Pr4Uh(|?Z7|!9aVhuo3$ML%w%4t17S>mzrN{QI=U434srxbZ zET8Yj;<8*cFI@Du>+Y1|D%5Nm^CjgQ8^6du*_y07OrG8|@y?I$IJ=y|lF%PoeJ%$C z2ta$!J9ROqN6lrK-cZ=!Q>`m3cz5*Wf5d&FvvJ6EfbT*#oShyN>8mCM3`B-du zt66Ypap$fdb59;e=)V!k#Mh4}jx;D&JhI=C6{B*y0z2YH4NZCl&Zm=%m+EU`Xru6b^{XSBEUQrCJpgq}EHYIDXS$Uc$ zG*p%-C`D_OfAbJtlL%t2)3UOG#V#|2ja5G#AGP?n*{2P(p_gsC(h8$bWrEJ$1Z5)_LpDBC}&eOWLU#&Y} zZxyikfykNolI`A#_^IpqHCIivhtIm3rhc9@t!uZ9FQnjeDplAVICs_`Zj35h8Ms$e zu&*2M)6@a0xk9qayfmDufYP@gKg&NEwz`Xr)i1k6C zsZrkrHli(hp)mA&yaaUIIM>y-TQVaTb9gIvQjTB|@*Sl=oP@yAv_FU6-Bd!wKHTaD`fet_0r7=)XH@Jo3}t z$4w^^PA&-^KXkomX>gmgtdCzVc6_P9v7MZI#<{bHF}e8f`{i(KVCE*AKE%|;qkC&vNSo1WFr>VrXJVbO@1|QwyXY1 zR9a%!^40F;Q~Iu}vjwzbS76-7yMV5F*R|luQu+laV|1jv(;xdq{X~p?>?zu3TsuEP zU%M{%u}aG3Ua^tlA`LzDBJDzCYsqYnHJe2#uIpJn-pXqFu z%0|&}KkDGue0AJ}F0#GDbxm9J8CbNOSE*5AAYVME0npA3%`-Dw`2By4!COr(?Y)=R zw3$nY^aAHuJcX(WmNz{XczkRm+$mGg###B7hqe(Mnb*Xbw98m|4(8*x4rZ_a*H;{~Y!QXYTHH*1 zQ>DKAz4;*afBPvjQ&X3%&{T}$4&=A{Pq_YbQ6tfH(OF6HTp?Y3f(_k#!q>w9c+7X| z<=5qCKEz%9+>g^=ZKt~YZwG^-N!zEZ3? z9~Sxl2T-2ik?FA{ZRmr_#@rAPp0!6ElG_L(N-S}bq&5MA&Zt?OE>gt)hb9zG%T^e{j4sc z#*XbkQ9Hb!wd!&zWv-}wQ(Zk@(x-(+qwHtdQYM4Q3)>aLLc@cmY*uHFEJtPi zt5(ZnrBT)9+}kgs1Fb3aw}Hw2B`@E$&RU7yl4=I|61h0gmKY@_{b1uuET(Q}SQ+`h zFnQuK>E@RUDq6)QP~3B0{@q^JLk!LSF4$nsq@AQj!2I*9)p^5%4n@h47KxvhStB+$ zmfM5zF96H@?^acXMz5TjA^Dg*)4D)0Bul4{%GFTKtEr52CRf>EpYLmI-fS^#`2K!l z342dnUeC;@RMzF%_#A3!nWqB9aRdidgX?%v27{uw#dftXe+By4wb$wQ>3t2@*w}2+ z!p0cWW(5EQc1FjcSY{JYlc^jVZ6Jp3jr3XIJKD78h6O)XQ2zIQmmIFWb+-(m!Hw75 zn(d*Uy!PY2DeDTS3x8lzi0U7n*n)R@ebrR^fw!`MKh*@d)t^jAghmomfl2w=3f;m^ zKQ*5M&vts{o%eb(R=t^ic=KOGZhMZp9DX@reJm~p)W?Chf4={JBOzC1u$X5mYD&5I zq*s1zSU|}Sz+&q^;sCSXj~~yZY~vL`PN6YZEnm*sB3qAi`KbMOwy2~Ok~0r^u6l?D zR~-hxwx30C1`J5~WKI!)G=>t$V+>hAGbFyo5_Lv#9r;UQ<^YrU)){>ZYT1}q}syr6Crm2`g1@q;s?sg5JBo-sW z+112|QOB)5rJoE&zW0rhZ^hOCUu|Jzg`J|v(FP=(Pws7;TVn=I&LO3(m)I~n^IpSo zKLS?~ucJa?*h)2W0cJ<=XXLi6Y&jSt$|wYqgs9BWaR6exO{I|7JW`dCW(A^nZp<|8%n7(TjQCmqA<_Rbowru6lgh{5NjtBKR!%TGVF6Gg6DE)-!(2G*C`{UzAIW5Gx zL|w2ynrmaZ}FYl z>8ZK;`pxWxD(I+aC(P39B?qWh?o8kkS9W^s1wmO~E}ZsxIIiCseo?c#zR=ttamKvd~mIP(NjrZieu2O=~$;>U{m<) z(0Uz8=KHrWp;(2gxE@2gM|9c!B-WwrUe225t1)l&^Tbnmmb`Z9SI9Gbz5J?F+BC(UAL1B+d!akp0T9kjE2uqZ0MT zPeWZ3PB^s4x3P7zQM!jNeb$9pn}NIy=ZfUf1iienR2Flq4sNIWJl+&5rnlH8=Fr!g zh)=~mE7UU}&O*MCypY>|q}zuJP3G;*7_kJ4GSK3}FACGhSwA0X`iEdnkhTQV?HSOU zf}^=vwAQI)98m4afm|6wElsN_xH#2ve3naw2D$VRKY zXe*G&Z~OSZxY$fWlMiZf*FUw~>@xbIMiD-RMpKwO9DCoK(r?l!#)W#Z!fub3>Dynr z`KnBY>0C;enHdh(n(J9~nshR~Pe|^U*Pq{W?~GK{msRhM^BK<;sM9l6C>i<8YFI6_ zG#XBS0$Y=S%T20ME&;Jt^ZC`8(<9=j?rAM3_3%tFf_xRbt$9+mE;3wFum`K3sDP zxgV`5cJ8XdN^v1E$G68S(5ujzgNe=*sio-_I}lK9_HZsy4~vxejRcH8%TewDEzJeX zF0X8l(`iZL{^5|_{3*0KzqPLV$ITn;vtY*f(R~Ur&$tj8H9|N0#kLHM5_Rb*oB6mX zYkylIyE%pGRD^e|+$HC4h@gh7we~|DNx^-pgzcntU(1_n`HJ+aLvLJW888SyhI(a! z7bDf<1J6MyN5=xk-C7wla?NfHw> z)8ELWKYy}XjlZuI*|6{Y`$^DV$cmDWvqSY`KawfB(C=5-UDpEU(-k$7Q59j7-cr$G zzAFcoM!u{l-cv*n1yjTt|6Mlyca*+Y0U?-pfuL%MJc=dp#+n$x;*!;gFmJTa5lxd= zLXI($lt&eLcKN4*w|gexVq_}6$W9ddxaR?F^~Wo0B*hqlJQL^2BnjIO_|2;9ypr@s zgHObi0P_>0zV_8+J(O#8(E18v zCcR4oq8-LM2_sdHV(|e>6uz*x8>C|3s@2m$iUv=o@$Va+ollLHr-t5~=QG^Oi%-{A z)ymS(HVqE!ca%D#k0qq?Z}=31FN-#&!R#QjU^l#wx!XkKz$6#YN9dKk ze~eI`RejLlU9J8!HM=i(cZOhU;W))LQv|!rdSQT1CxHSG0PjM1*>W98^Z5_N0Bxl< zmiCt?K6E$3WcyYx-4sF-=F==s<+l6P`Mzh@!^P?JDpt^GV*BH^^2HkLbchd~jgZCA z*7gm!RHs$0>F~Ou^``jIu%dfE=xJZf3`*vI(9m)}mv%Gfx3eNZh#2}2?OiIje`X78 zP3R*31a{VqV>UUJzw?bxb@!$t2k6G;fA(9sor;w}N2JC-%cm?_2(TT+rzE=`0K}p} zbn9bE*|Iw>Qm;rg;NQhTXTTA;fFi`rL>^R`T+-d&#p7&8u!|-0;oJU+)mF`JvRD4yX0?DfoHMe0cnY|Dnewta2lL6l<^b3Kk!^idg%FPd0qFZ6$SId#yB!+SY>eu zAg1#1Z}_gA-@@Mc=Jnn>>y`Vr8>-DcbMlYy@XaHydER%5Oi6U^y-}vXSb9no_PSFA zMqm+SQ)od(p2Z%Y-37;t_#EZF?oqznp?FtvI844b73pJmxB1rgApvnQvI$&vjALVT zfoZJ3t@KZY9K>@hi6;#Pltu5XuHM*x~Z0t+hIpCv_~_df2g zv^EFOq`SuHb7TQ5?NS7Xy89z}`yHl}So>@@&W;zrS+0X4AL_zA*&d6^*Bc~6RgEXS z#r-kBrPI(KhSjnX6P8ms@|M6z6m0SuPpxK(1@mZYYA~KQ!+;6(3XaM*)A?U^Ak$X> zY$5k!j(7E+zz-RMfkC0zKUmSF+SQ;^1MkAc?q1nm9W6_fANz5+{q?|TrEV#B+2|~I z@j$XKJqH$g{^{M#PtFY6e5MEYg)xbzeK7wXz?D7{z1lRy3HDOX@|!*iR)6?j2R?(E zSm4-3o+y{N`2X#Rn37&zDfShznlGvz`6)Dyr+0Ry^BTOGDi zZC6t3J-alU^c4~1VWK;%=EUBDS)9S^NCUKq>oS^xwpnI$(&F99sl_2t0|O&z0Vep7 z-iA?%*`#|Hvx#`=6fTLNmogFwb?nVxOJc_Ze-EM=hj0cN?6B%*^ByxxXYzjm zrIZ(168 zMTuB+S&qRYJXVukhL{|LUQAz!`K$tciZ-y`347de0GZrZz`tweD{o>0OU6ZEI;TG} z3y3h&k+Q-&NHh7B5wrj`5^G11z#mA?IM z-bIKubCw$bA-Dbqq1vowX2`nb@o6sLY@;*iCa_}`?dy7-X_`U?r$H8i{||5Q<0Q(; z=9Pd;gs9e;@*O>dLVTV|z(x-pc=JF!R&Ow2|+1zJkU^pUyjsY=1Xz3A`Xn6smfR>-)>juv60I zzJ}Ena~HF*w2&O5Y_it+vkH4QT~ImO(MQ^+f7VZ@R-PKUY*FR`2_L&B6aVh^Yz~=# zeW`$2?(87D&ab?u$<}P84OMX4vEq(AJ*L^}?~Q#~uyvMdKc;j>{a!!*UP2k3u1vfSalAXg z8Qx|?SofEt-(J!1+Aqpk6m34xgR{|myHlSYFUMK7Y{mlbcZh+ACW*%A#+Q!7P8VqI zJtmiDg%vieTc!xV9cto}saav6vCBpo&u%?|= zLq&qnM2=rA1YfvR-4Te3z%q4<^Oe+|-Ed{;?rySwdt3YcM#jD4p9|D#c?<|?HaY3* zp&=c_LVy{9eDDGnO0)}rIe3z@%{b1Q&$@8)$gc798Kz(){ui`l8C<->tgq9#AZ2Ert%Qk0#43E7R-x@b)FJe|Z-XiK+Rm+NFJtIW$*^)L7S^s|`V+qd!& zi$SBgT_fM<33{&y-(L)~V=}C&6~>y6JRTagS3d`VVHya6RJqXY(>7S$>N-F>U00kR zj7h->|EMQUNHOrCH&cFi0M4XJ0$-!zFGxUZ%3^LzAgWNbUFCUCk$P!`M|h{NWTE5Y zyA{F$oLD}yEyofZC=&BMTrLiAAQdizd51q6N8{Or{qec3)y51Kl^iG%HGRIB7X#gW zV5jxq>~_z5%|=~J#15^1LRYj`P)6L%F)!j&wkoPrJ4r7ET>2XBOXL0{hm4sG8;&Kgt*^f#|BJ_8W^M^y7G&D!R%L zqvLX=OBe#5xI*nx?M#uVbw_9;3x5LC$Vb{EO&Rt5(LnQQ8})SxX@L@jiDqy*!e`@7 zRBzp?_i;S2^{~^{+j7C}D6_V}KKK$*NVY;(zF;)nYK&Xy3JT9vu_HhE`qMw}IO#IX z{X(j`%|Rsv9BL|pX^!4lAUMkC=Vw72v8mt`#lkyrfH>Y~yPcKAi{pBKjylXVv0u^r;>ec7$icjuwty*_7RV(! zP)jdBmldf#z1jUml(7I}Lk5x0I8gx4coO0&-Cs>B%f=YCVrH`$RIZSjEJ$^rbYNwp zZPxi*%N6B-|J>od|7K^xf>6LwFgklrcZ4?wbbRFzD4Vx3w%SAr_+nIsd>!TK(k0A! zwdON!VG1Ue=a&<5JFdZ1Ptjd?2S7s;OA-4-&LJNepeI3sx(}Ot-G_yH{w?qh?tqZI z3$Dx&fv9&37gm~%D)HO2@K}mcJ-x!{yL(z*f3e7J`MS@=B^@A2l?c%6LlVa*K;XKv*0*QWi%>Vy1dEw7^oiGNjipdnQEk+Jvn zq9GYwA?5U$F(Gku4LQXKmmLSvnv%`fOf5jTI|{8zwB{(piErN>k=~AcAdk5s70=+1 z-KN);NxfvdeuUJ@kb%jkPIAhy+4NzUE5_|mPZk;xW{L5nzfg`YTE2L|B zT-eUe7<(^*-Y|ilV1mzXb?PdhcdhL913QjRabPkZT!8)92Pq7PGWL`MBmg#F^fcu= z5W8i`XAfuUc1N}B-k9`8I-Gdx826zXldGW03roPTA?PrSJz$Hoy<99quULC)o<@ZQ z`-X>vi&Pd+Sja=QBO;Id_B3u&(9NWYJU%Pq3{#;fiHR@aRfA{W{~6@AnsH+m@h(^G zMC_ha5I!>gosy1`4O^gv%&&mW9!g3y+7$PT`S$0a2)~C%L+t@1>BcGHSZTaJsnOMuJ-$4X{z-w*?1*r##~h+!1u5#*_!J4e0603j zmL1xy{y0Kpy84V2Q+AP5`mBr^EfN=<`_dPuJ_Ypr_F_|F!j>s}z*30GwXR0&l^d8L z;XcyeQF&c_v#=TSmUx?Q>;sE-03I!-KDPrp03{ZA1()gWM#y2g3LOf8#zGY1WC4WF zkE@j1HA{EgcFe{IVcyqGwHIYKI4)Qwhk)qy;**86%hzkRo3_(N95T>fBg(lIhF<%@ zAv#k={3jf096=S#9rQ)L_DEc|BfyU-VV?%r4%3cn>UZ8tM^kX#5Q-}>tW~4ir-bo& zK73%ljq!if%A8kzAh5s(;Kak`Kn{Ap2#*F@Bn)Xd*Z`=ft+41(b?Ur$0Vl|{L)$Y` zTpW*Bx$GU0jLsQ~l zTd;x3A>>ceq9V7N-v9o;EP#^o4^le;NZt)rz3~Gj+oc01_8%5?2H`7 zO<~-mlN)truuwwa6^YwHvLwA1%nH!uwixFXnifqNPIx=JeS5Igo!PYYYUUFcNgquU zg2mXYNHa8~JetYWc8{D8eSx%V)T)$U>?S2_32!VC?zQAKjQV`k&i)29O$I#g6>mG? zaE=wmpYz#iy>hi=(lKL++mAkk;>@#7@U~tI4LhIx`N-QxOghuaX_$_ShrEYUYJ$_z-wPx-eOs zNaQfGRit!cpWsW7)*7H?PL^+4a)Yc5LwyzkDu;xHAMkF{qAZa%v3wC?u7Za3tWx=} zgW}OS+(uY z1h!i@9$m$F^6%8 zD#Nui($25lvy!lu`uxTeQI7^VufB*~BeED%FhoE(y7(BmMRmAx8b=B+fYQq1E(jGWAwRr_!nBv znT(ajlk5|M{;5y1gTYaRT?92h*t5V-k|K=381ZW(&q63>%!t$BVtv+%Mm8jB`b;EH zB%O6-$>S>7hTBWP+c5?j^Bf4K0TzOQaSs@Y3`Mur+!*6|Mk^lO_Pv3YpCq9gK~X5H z4&zw0Bz3z2A7Kp@#H5q3frw;b{Qid3jcU0E_>@1)-N)(}yNMV!7LnYN6#R~-85B8> z5PN4#PG7&CaY$(Bw%cH{nw67rIwy!hSPDNn?3!IjT8Pd z!r-!z{*hvimUcqm0%j|uzo?Z3;umsdNuT6!6LVqs0*C;%x4%_Z6U-#tJ@ zsO_R5ty7)vC(fyanwnMv2g*yKPhZ9{ZgXJAgr>;){7|yx(5={V*?p_sg^7cD=l3^C zXsos;(am*SG10*k9CE=o$70a&htX?wpP9bdaYkl=4`GbG`4^wtRVW*|x}J`fFPoVuY@R zemuh~=OCp0lhspYSUT!l?0zI4b1D0ax%(vx9(NA=L1*8=pU#>&pD(CSW4+*z3p{`R z7k1HpznR3+&YDCe#;&psY@eSs>v*cfOM;D6WQ#t5{`EV z|26O*>SrtQC5Z*CNcLj+*X(vN;0i2KqXMehLFQash-K z096-ODz#%Hgnd1=KR~|_=dY=)f9DoWrqlljmqwPzV^K6LowNSgb1}K?}SKfj6cxP_{)b`%-Vs9LZM$nnid>VgCz*p)>nkb0S{x0Ql4N z_AZjh<_-cWrtC25vcSy^DC4=heLVCkF(v{>l-dEQ3lexq4ciMWb zL-f4ERL{+PsgV(!*UB05^#uy>_A>&$1aHsIIoo`_pHZh0RnsCu`gEPfn>cs8EW5cg zdc1=C;Jtsb&E<4pW;I)$F=I8OVr{b+jEzmqrPH~Lms*gGoDnxQZN7A*Ti5Ob&?&?) zu;%+}yv`gdZmBo=wm^E+>-uWx!*ssa@lu~{B|E3)xbnATlibgPTUP4FOE(5h16}zM z1hzcM2jBx49uYBXKGruNRib&Jjc<7eezw~3U^ssTKA2M^WH(?E@w!dY!#V)1)>N9# zmlt5zb+ozcj3=LXDOJ@~geJ-F(SSQ1Cg~&@7?U^mAWBC;uQ!Fq>SKq0@|dsmpmEuZ z*_vVtgi@ecX_`N7$$Hs-`OwSquu$uTb!=1k1n?l|_Di3!n;CduD^Zc1HyoxZvXhZf z3?F-Q<+AeMWMg>YMqYo&T9Sv8_$YxM?eARcN+Rr&68P&=)z`rKly#_1nza11(4xX5pDa4wI5rt2wQl7Lc4GZp&BKtVub! zpFfKiBW5#B7g%{Gr}%!3BDL%ot4&r0e08uJhs#W}>n0xLOonQC3!LVHpMg+p^eZ?@ zWbrP}uj6xWUo_THWtSu|f_zXIPQ9pI6>YCPwn$sei=U<<^T9RhNGaB5ivOhL9G}xvteIETe_-!)RED*65SustDWa6t% z>Hp6R>SIJq_5Y?>a0X;L!2-DK0re-XUO&6n3rtap^0Q6jpCOR>n?R1g1 zwrQp@j7}jl4^k7F!R`5=VOp}}dPF0Szjw7a4Qjd`N`Py6`Ixm-R?nmNqWh zcAzLhFm0=rVoAGsv)ddIgafj8wOD=RUV=@IspGb{)C>7AuQdO_$X)GVWTQTvRQ7&- zc5PIzwu(c+mO}=HO4@uefdEx#gy;asH&S?W4jqvU5|(Q;<&O{Xt8tz%h>>1(@oEjd z4?yGXie515*pP_(WlATSERXrWtnDGN?hFV|(!8+7S@H7-oX)@naCPmV+L`&Oxgg0w zMftBs3HUo9U=_+ zOe2F(ytyHTy3Yq?=;aL;HZ@XAzvp{~eF7>12(osx`v7uZVO^J5*-6lq*eOcl54b<1T8p&&ykbQCd30km1y zTEBIqDw3{ve!|4(}B+W9any7^_QKE=?$vUt86tsNG!AqUX~pUq>X^{)5yqLfKZ5xIQntmc7(Dl z&+_YEGN}Mb$q%xhCBNV-X?$D;93sij=^npILsJhaUkI#1Xo6>xN?av?s?gKueF9MD zz0VtQ8yAFHmIIp-x6z~J{)Zrz*gZtY>R_5Btp(Mqymh=(?%!Ul28}D_j0RMQh5|{d z_0dc9?UfG4`25`d_I;(gQx0d@dmggbSKymXp^a271p5(PmV7|94}-$gy5&pLcu0hS z`^2zVMb?-3^bs~##ed$zy*q+E8gKt`abT3NBa8|i0{HDa6lullk74n>@hgWc;1x#x z(JF}7Zqe4IKu){dHgY-R@U#k7bb+huPOA)5@~-qZzIK0xjmezx1b`WXkp07F%dG`Y zE~_Pc(>BKk1hiJYzWaNZ1M7+!JWH3uW3B?}DqMDlJU=Vv>2> zOL=xMRZuq&Cq`1Gd57)`fP*T4TpHvYUk=SDWSpe()KtRnsOreT+MQ@H;b)oVxmED* zke5ylyfrkBKpxZQ<(3c(0#{AGSd?5od5L4hTJnzXjaI=j<$Be95XKH%a)hMd;5bga zf;iihCjxv~er?YblvO)TS;>)9*j-{c)tgSD{^#M}eG zx8c}MjDwyBs34irrHHC-r^9m5=w77jC+;rA+@@EyrH2tM`dgySeuE_;Cvc*BY=0fP z1s3WG_i$FTZy0x(ws3D77AEy(Nq@Ta@iK~rjr>PXz@6zqxRTgKdh4-q^Kq03%|pKI z2bG-=xC-2w@`g}J6KCKH8|h`YBPzhOG$W}PHrO@bBzc5sTu9yNS=y*2VjOqCXZKzN zcEgi|ncaEMubScQT5rmRByyOJ@C$$!EZ;TK8O);=JNb{3poG9@tyWe$(fOG|?R8h= zf%7y^eE>V2L&qyks9Pa0H>lO~aE`Yf(>OdDLc7$tB5)97K&{Wo*!nXAm^NGJ=`vd# zR;jQMeD4&@L09y=r>Lc{v}AbODXA-&q{ovF4#S=k6Is!7s&-yT}# zq>f;{;>WA|s+7D$VE{-jwOns|F|MNPI^s$zG=5pkv!OPAdnGckfUe_`A(=`~#mh(CTI%4koy`~{F& zjx=EF?Hg;`GsyOEIy923$C#d{egE|IM1(H8JA3@)%EY#(oH}(?Fsd><=X(;{Wozwg zmy4+=A`a*&cAfw!hjwz0ihX$ek@))k3HN_?M>vOs$`O|A#K%8Qbdvg?nKNl(r`Nh< z;6`(bp-XoPv_pBubT_62(wzc6N+k6U1kMh2-Y1TdYzyxyaI_B#s3kFcx_v_^0Df>a zjqOuNF&* z{)#K})*9Q%(TtpvCM`YYmkGH1_+;YEFP(LGhuMB#jyn}|3ZNmTT&SXB1xZQ#bQ$Ra zyBIWNU?bQJ{#`3qEO*FQwGzutfAygpn+t#OTlj~F? z*e&QDZH(V1^DnwNW6AnFM7MYNNoG8&Ue}Rp^p$qw-w`6sOPq%h1xRD{_ZH%n z2jcs)5;B_IuDT(T2 z&&TOpAbcT<*T>LuC*6g^^h=gtwq8KvG;0$>LlTw;Gbzgzx!VJoV^`%(_8fs9JUB4TNkWRfeDcZ+FAabav}YoA)(Dv zcc3{LW@+)sC%I%^fG?aQkIV`AvFdJ|l`z{R9Ybk3Y_X!(a3&y6p$P$5wz?U!=OqAR-% zKcOdy#-i&k-_3S!&=WQunE>b?uYm`1R4UrY{~X?dtmJOkkY20!se}j__QZX3T_S9@jG^b@-hX4lSw|@ReYWEt>$A5=~An2XeG;o=+EdRFw7d z9NFFqhdl>AFcdRx*T~0^iOIO>Bnh;&gNTI5z)weF5uV4(a(UK-h?c_6^&PPk^|jyK zkB`oe`| zy3%dM)?up}53VS8{Z9Qo#P1ZzxGp;(^_ABSi9c>2Jl48?OYVv8hoh5icNOyjAoOW= zUP}w^%NLV>j-7M9d7{R~4$;PqGc7`kyg>i3Sa}5-VFSr# zL3XZeNz%nL?6kPLu`{j-+Q2sg*w`09vN78T{^Ru=LWJ3XpdrI`*%iKPe%jW05g1tB z21MB+Zh>FhbWP5$@{f1Yp_L?bI&hjX@im4i6;rpqY#?Bi!2U*z+m>(SF{*FD*}&Q@ zj(;dn%hL_$VoIK#g)_pG$mKoc`{=DLFGOQ3NmE9H<1V3$D5d?YswaFO(_*!Iy}&KY z*z-Tq{Uhv_F~zs<%EWI6j?-?(waD0EvaOGzIR$2X8O=BS> zr=sma5_UpmIs<4i%lF;hVnz?7OzNi)W4Xo`zCN1QZoA)M_Eb3b+xzqJ-+q?Ja3tg4 z)U)(pze}_U!&dt;d^Sxk;|O*0&7`P{qv~-Tu{Y>T#RlG{rj#O&g)NU4@)o}9D7XHY&GXVOkVTf_FPo&y+7n_ta()`yOV}exb5q_i; z0!CdqxWH!_Z#^sB@0G_G%g+*chSS-3#fUzV8tWdLU;&>kPS1-X`fV(vN%;PY%Z<^0 z%gS<@zOtYC1_R^&eCA>ESN0GN;wT)k2XP9qi-sdV$CyzU(;}3VjP4jQxRo)+X?)Wa z!A|U=QQ>6jDV?E`LY#gV1>zl?q>uib+K>+5lk7025``VTNxQ9qb*}2|{@KIBs3>}) z_?Hkb383OQFqkAur<(4m^ShaM#m*!iLV}? zU#|1ot(irR!Z~5yx=P!`p^Ml#Sau+tj+{;sJo`CpSEfAdX8F?{YVysUEH@sCrcul2 zLcNK~j2MQuJ4`-qZ{!3WbhMjfW5D;2|5(}ibWEC}8i&&Ad|{p{;66oM6Z>Blpe_J) z$9j^Ub||UZGZH`vA+n9BTHccAgWp<(}c=TsHL>`vT_Oi1i`D-;1Yz5u$l}wX-qq7JzsSW-Cpy?IszQ* z2aSuqNC~LLkB2M$j#*E1nx*_afvC`xd`u8ywXjrZWc4 z6>D%PM>fg?6SkfA6}?MfkCO_yMD->WwMgJ3pebv-JZX-+XHNR0H4s6-M|9j1PGr7R znp%gvZh};mq+8`m(&)adwdg!f=u%~piJJ5O5%rc)ZFXJPXdt*0cPqu+T?@tCp*R$G zcee`C;_mM5F2UU)xVuB~FTJ1hj`J57B)PKp+H$XG3vmq2}7z=Qcay%8+~M2E(%=CL81VHwqA=Gl~- z$p$a|^@-H|Al5g<;%nUqs01jX+vLEN4NCoa zDCJ3!^SwG6A_CwH$D;nQ3AZEDGB(YmQ4&DZN(mky{gLIOm z#Hdns64f>(i+3lUFVuvZB=%vP$>4J892hnuu0qEtiLt2vB#{H;K-fE3W^x8IuNoZI z_>KZ@#~MfLWkq))k;L+(H_ClCYyU%iINi-S73XnrkU81j^@J0|17>xi3HsJUy_MaT zPtThP+0@lzsT`}?Y@(=(eUd%R4JUJS$z+=I#IxzpJh$ZPGvg=5%il5gMx^4{yHBBz zbS|m_q4SR2C~PskG0(%rKMaK)_4W+bL{V}M>;GkT!(6$KhyFMMm)~Qn%p6H{cdMmu zsKq)AW~(Fzme}|}Y+Za${TRzl@8oqvGF%7(p~FFc#_WE2JYi0a_%c;eRlLc^^FKJphqF%n-S%9K_i$91#WabLzO)= zEE+U$kyvqz`gi~BHF0KP^sI3;q$LZa{Wzx6atI%r$ zrO!8bRK~U8@cKbaH&ITeTTb|tVy_4hA&=1U=!%Dlazj?R*xJI$i6XC8y8nDb5aK8N zk8KnZCPEbuAL1t;2@;35v&VLMN0=oR_O5S8yV2gwh~j*r)CqbtF|E`q`RHS04|og; zdA9S%Z6x=-gLsT;zI+1UcEjB~8b-mJtI(_ z#JuERaM0`3@7i}N1?>Fim0^YcdDEyKX)Ci4m2by5l+rSsfnYt=#G))=`;W1gTK;{9 zH82Bz@}%YpOW#4LiM}vK9;d^m&XXOwpKKP7w4sL11ke!^z6q~Nkp<9JtTu7HX7akv zEisFJ$VnRWAm%X+4)cKqSHJstrz`9A;$$r}o_aaPFgXTX?=qNc0oYNNYD|^1w`0q3 zD@4e4K&`INXe6ux0*(@G#*;(ovXaVTzf;l>i_IrK$r-XH0xBqx_+9q>fK8D3Bj+aQ zMRxxq^xIJpea{Sou=>AX0fWkqo0@_YvFZH^>-Yb@_!}9|A5epi=!F`x87t+9!0O0Q zB>7|k$pz7LO=69vZ@_F=R?;(UZh*fGd=%1fqYg3l z9B)Vu&*WkoF%Zj6%l*=uNhrLETT7 zwGoP`-1GQ+3szr}7bU;bB7Oy6%v;abhMgaoE`7o*twsULTiBnStO(ogB8;LOi*eAQ zIZ9)q-4^+UGG1>R4SmPJ6}FUfDHf9X1{9ZD)p?G;9!TQsOP&YDIY99m_5CNPu0eyWM){6I}^fFouz4AF(W()#zE zchdsCc`7@h4s$QTOAkd+T&TYFb)rLm2OHEUj~o9y{7pG965qgI-l_U06qomkl~qxR z_zHU9ClUUT0gxVRQAjv!uvI&hROk=ofZdnxyNyIw* z!B>tYDc^o2FN4WuAN7ofsXHX_x8Dj@IbQXkx|;u~pw3Bb&7n!zk+IrT#KyK| zO446IGUh^&n05@+C|5AK^1FJ2QjwCa(2pMf${#`zC(hfJ7VztO`o`!d+6qMuyXkfJ zjt4rrV$UW42bwe%&zA=}ub)QYk`+r1js zwSBlPh<5n@s`^1Q6!>^F2Amc1uj@`%O0PRhmk=w}<8D0_qjEWRwa^0XIa9x(l=}}tAKe^1PBz|%tQP7}MYp8$e_Q0);<`x28)S$52IUr60dMzTZ?|Wj&|dmm zN%23_7N6b^d2U*jj$~M3N1xOFz1WLQsO-}o00IeOP2tGfi2>bFdw^V*E@;OCNS$HO z)zh}RUBBo45A`uz7I?+>7f}v5{Id8G8|N7@2l;PFwb8m)A5}su{(oAUdDa;a2H_T( zoC+sXRyWU_2Og#q_`B$vB6Vf7n||UHxP~F!AN`+tV4KQ@&h5{e>Jbu7fnLG2v;MU8 z0a^k|QE9Y-GJ0F%*q$T5K6Q2Z@uc;PTe*Ewsgi9=&4jzbViF#|xkcWn(3Wu3^Izxs z9aT})rHPhdTYQCmjPfe%G|KE=*oBRsD@R!<=e5xGg6h&P2Km}-bn4aF*v#rf|Lw$o z9HAU{aF^>2QyE8Tn($U>GLwi&z?rydhFw_@?&h(}n5ZTHBH# z=d2I8k8jm@C~T=6OF@)Tl9)ju}JYON-u;sHW@`utFmNq|_GWmhLMP(*jl2px_uVwc51 z3aOTN6j(*_iIAuQDH20?JwhG_=GO?6##X|ARPx;C4;DS6s6KrSg*np#Ehb;>oVsks(=|3Ko8a2;54=T>ehz?+ z{n}_}v-4mwSgPyW4B-r8my4PdFvqO~N(AVH#z77gBxOreOa|aueSv>-#fpabd3lZMWN0TRw=RoUYez&rm1Q)( z_S!`^LSt6CkdTiy@7_C$`GuQ=(FTcMxKYP=ja!eR9-4k0E$>scC%>wNGMIIa&hH1J zkaNFv=#wP7}1;o57~NQ4i&|#En*e z)5}4sy99fNoL&%^Z;0HiuSS`sER!y4!ou-<|7ZE;KxVK~f6VF>oYyv|ITdS=7tXg- zGG9810E_Aehw`1BmDjbJ>bncO%dxVm2+Arelg~)x(Trk{G5mav+Jn7nng1*8P)`oC zPG>Oxj@>uVsgA152@$L3@A|W)>Dzw^JrJGFkSgf`XjxJ+nkX;O#CNU)^y56|!wWX7 zYzY!fcnkp(YAPoi`rZ0nJeM8aiXo=-Q$OvFe{B1AJ6 z?yRYpV42~2Kj&jy4?X%5@y9ZB`Aq{y%h%SibPnCrCVRUssF=CcPC1$sewWr)cNW4W zL+WZCKbhCSo6Zopm4`&6D2~Ia+N;oSTZukfX;4c&^c&!sfFcp{&QE+U z7QA1|V|U*DUfc)b8&Bnmd%oD98jKbqFVm`urMDJ`Poyu4(yY`o-V?s;ex1pcKyHI8 z;tY6OEl|u@aei3y7>4AFP{X60C;7iV!7bwc?p(R>c{rapjW9cyAn~^2Z~^cclxZ?8 zw|m7M-zF3DRvUs2>i`z$`f^FkR4(;hWL~?*^A8w0b>GsdJs*(w618+Y-{0EU zP5K=l&m015o?}P^=+n6E;Q*y32s)><28WU{b$Hhk;i=`}_sP~XXOA>|xw;+LBJ5aE;ZJ7cQTrm92J{P2BT z*P+8|kwnB_KAO}|4`Qs5kePjsV^hoha^(U5-tp^R>PWuZ9HMpR0k0w1VUnOIBAOzl ztj4Qfwk!2LASG=USI5Pv2}i@wQ5U;1wW8>B!N=Mo>5UnlEvN1!7Tv~j`7B|Db>AD* zlAQNdJr7|4Wwf12kBjx|34x2`%B7$y_v>95tAck9o^{W>ql1+R4_BlZavpQA_77N{ zbM4b+fh?mk?x(Kq*J}5(uO}>(G2p>RDlRUKi=DfBl%-a;vbp(#4j=#QzTM%tauPHV zU+Jfl_oOyFzx+VRY5v9)NR$(Mkg@~k2nkY23Jz9D^vy1QBgdIlN|ykL>%)HGbr7HL z89JS%!OSg=%@1&7!j^8ZTwTDA2J_zmLVLctUqJL;=mBG2J!;s^^2Q9(h4a(ut*sym zr0yWl%4YjQv93~Ssp$s}9-DQ&BcbdrPURwIJ|Uq&{!LLH+jV(}E1Z@Khjp8B_I?;? z<)2Z1g3CQSgSVz+o+I+dKXDQp<5FoWe^>*NB)+I?Rbjw_8zJ}0`bGN6cN^oUeU`75 z{MZco)JTB7oXWt21rq*Z)YQyA$_1;rsV9U$buJ2uT${5M)j9*AlEvm4P7U}rXOq~5 zCYjO18Oa{UHBi(TTpu>=2eqQAFazY`s=~!R?6FWN+A%C|#WXIpGmXI~VfF_GgPFPI zz$@EQzbNK<0roe-)Xwn+RJ}fA*p<0T7mJdO`jR`ukBEh1QR3Yg2i@4SiU!b}$P>nF zU*Q{1ECaaEK&;%7Sr9Q7q2~w_5s&(6xDpeB2vJh{JB! z>j{A$TkbQKpR>8Y*eKepXy8i#lzZLmOKjw_7?e)Mv6l3YBT-%Ve7%RBsni#kH?C5j@9aGSw|T_y2fm_wqbyNq zv|TRWw2Rbpo7d2MFV$cu2o{!dVy1zBfz44i0v&Dmn^vTwHCjAB0`0^By*t>%9lj>RmREP^KkGo9V(Tz0)b zb1c`Grn#PjW&B@uvWBYs?-*dQcrt*5&7?vWlbKeg)MJgIP`|Nk5kG>fjXO|?dAmh} zfJ(-a5$+KuEgFM@n}67+3L1su+|R-G_qiyxu6OfY)iuK2x0bUBE>cJD^rpZ3a{{WL zQF*|$U4I8yb{D%k7jE6|+PwWAM-7jz3|BgKqg8}ozihPDrjxYr93Q!S5SZ~`y3^Sb zU3>&Ex&uy`v{?<^y7*Tnjg85?v+;u00qP*ey&IY5<$zfQo-E)OjMJf-lghSpVrtg1 z&Ybt@lg8ESRpcl{EYN7B{=@PeF@rj->bbthTEW9P_K6SZ&hO!jll2z~z`D)-tabye z76A#Zz!S%VzWvt&T(dxdBd=5~5?F^)T=t7+S4Q)tF4kj96@`sV|L{}uPV6hwH}|&4 zS86IqMiSWB63fpI)tE*ljFhNd^bWyUEvpqO#Muk^5Pm<+0kFxCwWga6n#(7B7LQ2n z6LC7mcJZZ=&$LDPI0(h1R-}~Vghi8F$v52x#Q@ld)TztQ<97i-bQ8q}1N6vd2*b^91Zo1SnDqvnw%R-_M@X9@dU~qK! zr|AQWQ%aR0D)lMkRaqC&J}zj#7bE6;!4qyPRkH)AJx@JJpMb)5Xq42a(o9}?J+^!a zgoK^TA(3E(ER7@uUB z$K3u+T7U7IPB7MO%%#kZ2}d#k;_Jr0xfxg*2J=5e_H2E1uN0?h=sKc#N<}wHmcai8 zLbiiZ??t)SDEgy34aqA^U4z;K|I!<54*#*g*X;{SQJ;{6aHyjNvHoWQJ#v(XgO8V> z6$#6j7YzeKUS1BgQt~>C`_`Ub57>1E39=ESj#F(a*|O{HRyAFCXJ<+YeZqiI!0)s0 zrmzhCEyOmttk&!8EoVDRwC6!79An0PDSa~F);j~BHt&mW)4J&x>E1T4QX02J z&>Rc{{BIs3(EzvWfbtJFRpT{odyES{KKLAovC>>05 z54ZW@>#w@VJ~mXb{RzI*$^|dUv;mVTYSgu1WI~g)SHjfx83`SF8pg2D;YO6-(R{>r2;DXzw<^Rd=NNA za`@{MjhOOHL>_S9p(%w;!`|Y}1$0uIPwC}@4K+*nbKTyp@E!_xM8+|}y!qSPvDV4a zIIx&ZNIDWA@VO)5HpVTUzgOS;meq(;;(;xqc#Nu?O=5{S5biRfPF8wj$jOvKRD^MBZCQ=Zo(=RfuB-+I&W;b}1r%cuLH8QjR}%r~r~s>g2Z%sV^57oI`p}{q zoNe5P(oa=bpxeT#Zssx_ULKeh_PG>g+MkTuI$m8-F?I#16=5|@Agr?3a^0^1?2~d5&to@N|t_9G}Vegs3YI`evBx3n{8SoLI*&brQn9s=F;knjX zI}XJ;$&H4)At7-bJ@Sqk%J&$V9`lnZQsen6a;nGlMl6B?2ycVPURNq zazWsz27m_g`R&V}jMA^XL9KiMX%y(0w~y5+%eW08An)eP)mve?Tsql8@xH%qyfb;M zw@iptJIVJ5LzbO3uc1;+&~z-bfrvh%@5V9}5WA-o1}MP_X5B+Cm! z4e~w&YQ3>K-mf0NUUviA%E3ih{v+udL=KVFQh|tKFfGhF&%}U7u*)PN1;76bFS6Ib zdJ?diFYs=NBBFefL>d}g7gOW9sP8dC32&o@(T_y#MHFQVUD;Z0l1qh{$p%sk-qr? zJcshP*Au#%i_={A@+y*Th>sS?D~hy3BxHm@AQ$>J4Tc==KTk^^YWbXcrjM1qLvMYVdx@6xi5_v5-3MBD-?Dpgz z9Z^WaqA{3qSFC5N@qKhYT50%2a?lxU7D}?(CDI$+){5$HjT1G zb3=ol%8jPc9Tbq6ToMCmGfpY}B6eptF^@LX($A64OJ4{2VO$nak`Kwux!j1MG=!kw zd(vz9ZVrfy0*9e)d*-0P+b#%TBV41O(yA)l$sylvdg?PXk@5j(@w$9;(}6@T6UjT= zlAmz`XT=C{nz#O=Jp{{7_PO# z5{Qdr?Dz0&VM?Y;g98FXeigs#k;y$lRY0qrIPE7t3Cr>{3OJt?@dt><*2q}rwSP5pd4l`b)5~E`oPG~-~w2UV7R4Vq8Yfr8O+=|RsXx4qbZs1;nwI7Suun1=JpY8jmIT%QuWD#aT}JZxx6>W0NVmig7Psw0H|*2yXlDw) z7LLpH{Q!Rd_D!8vMEf+wivnb2jf8l&n-S!iNU=AJj3eC{u`>%Y++G?4-A{X zYptYa3l+vwUZ-O|MH0zNrLdc!#?KT&roy@%%;gvhKpIj|44>8^5>ej^wb5iaeQ6UN|Y)YiNvVa~y!5Q`FA8$-5PF(e>V0lRO7&2}qw} zS=4_ZN-3Bm=*D6se7-+jCaHEF*bR6)c;_%jafkQmd2&Qy?cx0t8S^x40r@re1l0O1 zjw!kkLUkV6{z+ZxqkDUD;2w#fXLgX4D1IbMPOd#^wkg;oh)68Jlnf*k3Grp}1X8-F zi9GI_5&@T>;2t5vk(z1?kVq?lo8Y;y_4P?MS z#cXhy&hIw!ly)^)2gxsoO#bzbx+{jl@OgL!Q9!VRHL|qg6cdCWE+biY7Fc?l@6>6G z#zGMjkC@pFX&-D1Ta<_WLl44&bQ8XtqS6KpI8H!f?{z>GZ6tju@N;{KPA=XY9?_S4 zBcL3QNNhLxd6C8NV{KG?_AlWmWTXn#+Y6t7me4Nl#EsO`&ul(fG7=v;}WC9qbFV^}A0M|n`HDzSEMWHN@Qd6wD$L~0D{^T)| zONns`iM*oF9t${TXNa!>czPd3_Sn^9oB_tScrKHG&_lUT7y$dF!o%)#!4)`h4RQnv z*ktHqfPJJ?FXdXh&_vkqFLwL+QliVr)3sGsMU}x|FZ1f`v50ht`F>m>U(xg$`z0>f zVmFx$BQPV`1r)^>bIZ3?29O=J<`71l-4z_9Y&a%%^I5sG#tV9%)3 zPrbxgoe1=XkKIf(A9&;2T?*7W2KRc*`WYijDPgX_OTb^7bu*JN?>R%_q!Xy+O?YaB`Z<^{yPqwwDlswfnkLOvS2?ASXTw zV{h^wR#&xYH?JBQHcdL~Ju33ELO zzer>g88Kk($3(u7ZIT9}j`nJsw6ob;Vg;^`^8pe1scCxdZ*go{Oe>8cS(u6l9k9MV zOEX1tT7UK&>K$q_Ov&3kF3ewLy@Y)3>yzLjo231CR+Eh*(UFFE&EFxNy$#UVVxryQ z6}~z!Dz|Ey>>hs;Zi>S8x6@LAoQ2Qy)ehPF(oRp)g72*Ssaz<~JzO9Tr4K251~{dd=EgC`*U!FRB=%Wq%j)cw5UBgjuA>yGdF zykkMnC7N&laPQ2a!pYz=SRZ-tRPJ6KWok`X{6xq}h4$Da zuPXECbTUZc-`e$3iuQqP^v#%gg}XJL~dwulbC->9yUY zyN)71YWvF;dS=sJEjP5kz-xKk2!mKoHe-g{IiJhqs#nq8h(d04;6q7KhUN%GLF~c) z_{~T(@t59C*>r5%k&DkaK8Tw8CY{(Y37C88!&!bHQIgBn5ZRhM zTZA*L{e#RR#?duZ>~CJ;R8bV~D2!e)q+NDeY)%kOCj+mWS3G>uwpaDpzns{hR4@3`#O6)k5$wYH+k&^iH^&X#^B^A@a7BB%Z6{0{4{P(iX9O6 zT#d^tqrCPlZsOODj?k9yUv|#h=P6U%Az3V@R2idaoee%f_aThTf9Uz7(PyP6-@z^-R(hn^08)*o%+J_by;sPndai%J`51)-XM~ z;M=&Ym-uU1?U*j?LMJ|ZyBh4^qIaSsKzZ{QF{&uJX6k+u{- zOv(vR1Xnd=d~NqIu9^{9ZqqIV<%WSGJ3eHewXRSlKAjJh#tuu>btwfr%_fHVR2q8O z-2cJ|jD2}}yji8&jj6apV&f8F{jtb8VnIYt_n?qN)GJaDpQ#wE%gwbf-cD`T9U0CLZyc($v_rU1Bk?OKjdJ++7Y{ME|>U2w$<7G z>$3cAK~??VXby#*pIx$>>8E+xYN835qcm@EOM?cLOI4jLhHiHRvwCb3Qm3nAa+oH* zk&R!x3aRu%kt`+EQ6AZ=CEephh8v>IH@zC+pBGU){%wMe?FsZf*Xqddcm6(G1kW>P z<20rGOiDa|gQ1euX7Y%iGub_^2Jlb?Cqdgnur5e7e98;uTw96G+tgkkEf!Bx_3KWU zcbrxak6di*1VKBJw0W)_o(4u|JXyH+5}x_Z=q3+7XEvk9EG!W`GTJHaJiWdrLfWc` zcaINhGxwQfa%}K;7uZngA7APZ1l!idAJGeGBF2ajmsD`~;!{GVKt;?_8p8{wpYS4! zLN2rPK5hMgG5@JbSAP>swHH3cB7bc)n#$DXae&uR>|DUFEnM)HMO?9WCEc3Eeiq`k}Hxd)Qi_=|a?YPz6@x$DvBd+mzSCjoydtoH|BZt-+D;qQaHHv21Vd3|b z=1DPq(ap2H-VVG&*2`_BDz%`K(!bmBYBlNz)m~p?(gjC&2Xwz5 zUTZq&FKbYtWog;c8NsOb|1i2gesn|s9a?yGI)s6VDR~*^kh>I8>dmfAm>sgODDrxn3XDOd`rR#`LeA)atVWilb=pWT*O~h<)Y24vr0Y6?B>^wQNP27c z2j5=2+Wvy}jxf%MlnRyQh{d)QX8`L-Xl6#&Gr-3YKL4UE=!J|OH9N2by63t#6WU8xqkAIf5G?UMUp)?xhy8x z8+hT%x8SS`S{ry0S5Z2w&|An*xp03_pycPr7<<|6qLojR>VozuWev*BbYyg@+X4fI zyV%$6D#@Ovr*@@OlArPJi@#Et1=eE1N|RDj{R=wx-4bX9A;V63iTL6DEmEa&sBBPS z$6m<(hWwo0o`P3}F=@c|D3;_4)zFo1j2o zo_>qiEb#$3y*+N58jRt)T|%hog*ow;*f;j#NdD?;=@>oanvyt{RQi&ArQ!BLAL$K%4o$J?LRJU}ySs6*P&jufY!e^-0f;BRAAXY-tzvF(A}06Xsn@+Sm(b z1l+cV)l^aAN$flzV5WC5l+d1YdoUvCHOj5ay@-RM*<{eTUqQIn?~umhS3h&W=wiL` z_}8qX2e-#v=kL}v(##RtLT}EQTVf*Ie*H2#enM>X>GOEfos=94tE^l*cSVHTO+`{v z7Yaz1o7LUWyQBiaS0H_5-~HwxQ&=APyrbd6y>SYB)tPvbQ%KV=s_kO6*X(4aQJrmv z{(CD8TBeSH-f>r6n8Pplp5^lw+YW?{E$*041$TCX#2npCOlfW}!q3fi&E$QwY1Umc9ZQOfSW;_n zc)yE27F&y7u3#EOm2DddVk7?AF1bq6V+$^@P?d;T42%%PCn|`mJ>=WLN`2jD?^LeB zepkj&{+=dC-<9RHe?%2}GbVUfqC^MFI*G{{)*p4UgG>HZ7{e?mP|2tOg;x5r@*eET z3Y4I;HQXO}fOCQ;%~NnQAEE@X$$q1gm8F?XEAtPHkk#swewcW0rPmO$x@U;$ESZg& z{?TWUn(5>grr8e<1sUJ!`RJfvigePSvTRnyiKTx~a0Hbd=U^{_873gI)}6<* zSUF)m(hcmqA9z1iwpvdr%Q$c^;(vdsfZk18_cYbQ;gt0_sPK{A^LT2y==4d7h5fMZ z;D_B~{FA8Q=i*lc$1?B$YmTi*9_nP>Zv!|~$M7Ao7@Sv`81Vsq{315(Xy4UnSR7s4ggMEcw6h2xIYZScPc`)@91+&QJ`L-5_}XIgtA zAs1JtSWRiUa}9?2hK+-p>i35%{Y=(@xA`n_pS=|0hw|@60w}nBovZF+E6*DhD1T8x zda57q0?2$tOfKLi(FpP~o@t472rfy&&MN%|b!z&BXNjl?z?_l&5kb#D*z z^*&jC^n&aPZCcoG3=HbEchtkfe>N7Xa+8rF=wUF2Rxt1VDe|A}((E#;X$@(_5|JV* zI}hloF1$8&5gR7G;eWL|J$s2F?+7|$zfYk=?%SnjJHcJKd=2O}d+a(_!7m$JHr1`NmSR_z4zpf|eL4M*UqewcLca7S5CWfDEZ#zfjU z(7oN)4)8Psv{u&53HmxVEh80@!q7tsY9hRJ1oO6YOBxy3o?zOaJ*V^S1PdtH`b^YmHuo1}{vCrETIPZjB{FrVSf`(>b6OOP zACMp0@!C~&{*YHV6xea681I>{7$zqQ_*BcfP_-taf;fZaUP z;VKo{dqKw{;nN&<-nlo7JtwZ=*F9&j7qNM@rBemks?&3v1-twED}$KGf5o}(q%v!# zaa2|r{J&a#Jdak@UYBqP+07tC{hiQS8R*sOjf-NZA}{xu<~Zz7nJ(0{jpE5!`pA9>siuy>`w!@7J0gt`~ zT>`UGoj?#Ly&D_l_QgOxQDhr;-c=BkOx*~;o(}kT-YTtU=Z$1g@U4wx> z{tDHph=&nPu_D9-l14I*x%5c7+uDk3FAG}Eyn9EptTchq?x}Mn!yMA^uDDHSsj&dU z?9Lf_vv3A_h557b6GQ4VHaJ z)E%QM8e;Vm@#BU%C(@o9w0mV0*GrYN2Hj!x?%K;@6%Robqr_U_o9PyJ14KNEm$qhm z;&4(fd^|d{oS8f=`J)14jzfvyT_m=kDx z(P4p#hUHQFtH^27MrXr@zpl#C{T8yYcWMvEjm^!qCU(*+gEY;zGC*~Fme85o z;Ob}6qJi+4RX_`^heK@7H@X`uGO!@TpkqH~sGsrEynzpO@DF?8cP2Q=@M(W;t z^E*8EyO=M{?{bIwX>WO3{?g*hEQ{)}1O-pb>+!gkq@iX?HEnoTsx{7_6O(M&b50K> z?0sJK{*>F2=J2+a{q(Ua%-^eN&0Y6Sk>eZ|Pfr;Mc8{sx;cjJS|Fg@@?VWXB_KX&D z#~wAJnZ8CZjb@$A$;)k#h)%~ot#iON%|ltHGdwW_dNi(fS`sXJ_&-BjDPI$iXWxvM z_8^YEEo4J&p{072BU;#<@gwFuv~9c|Yr~)(FC_Q1OH_6n>oI3MM+W@eiqPo#991iFo6}WMxMYMb zVGP!eix-pS8bDOk)h#=O;jwQ!TL@AWvL!i^TI&7rP!fPf>~~jY$o0VT?yP%v?Lxg- z(vd$@0Iw$yQO=Te_M?Rq>AKJ|4y_(;XPU;mv2#WWbZ)b z!>0It7GL9nxjWuhc9`&4FMcwYHiPK5-XbFVznTQJGfC9}_P$j}v@3B7i4 zRXC3pbOZPv3VBEjUg1``F@knDJ(uW97u-Mu7V1QaUC(VXnl|6-Ciq>9c85qOY;wcOq7>o3hyB!yK9dFmh>WGSHNb7XmR z-ZZy7bUt*iVKTI0phzupv)p`{ zuQE`9-r)@Y9?6i;krTz7H5;fqYyWfRxU9+mwGIm|=}{Fx+tqg7D#ul%NizGq)^uF@ zP~I^wRec6r^cKJ(l$IgT62d0#9`O^T6_m)#Q@*x7c1iZPA+T8qrpH+4y4)}5czZh8 zzq(w9#XGU-6KQ)mb86Eo4c%FG*m8N>@Qzw-_!@DsS-kEBQ8t)w6^EZ%fzQC6@X1XE zpLRUq@t;pR)9hPo;wepIkZtU6&~p5q2300#&D+-|KK)e*7J0ksO7rQ(YE03!YnU&E z-wng_H=24g!Y1XXN$s&oJ{PQPSa`*wJBf=FLA+~-{xI2^8Nd0IP^G7G3w-II$%#Q$ z*d^0U>agl)GeT*kNq6i8>ux+H^2b%oB(cgro9X%ROhC-UYc~4v_N+lX_qY96O2xfm z`)G*^?DBBwSE6zWf z5r!`IroImX>e3b`RMU}LL!rBlNnB+ zqniR;*IQi zTB+B|fyg_WO9bf?i161ooPm)n!MyZpyZgrL08rv*@IMJ_S$y3sAqv{9&g?O*{r<*& zKO)ETkd&~h&`G!W5NQxka6^ZiVLRRab*a{wp{(^PbvMVNo{L6L)~5g4Z#@RMr%xyep%Tv z%KU6gSC?|Y+;%GHF-*1gb>k*84*p>Ku1e(F`SvfC^tKDX3xRID$$W)=zJqkNk*ar( z=6bbpEEG9RXBqzo7hgl*iJ({TBvE;yAGmyR>-oam-L>S)oxr`N6B+q}P z)yZMgav_pR|8GdgF>p4~KE>E8Jh=$DgHVSQxtAD9s+rgU{~}Qje`E}zlA zSLojA9A<6kTt-pk&*FoqEeYS_)f7|ks+H)>V8#o|@pa#;RUSRI=nnl4eXsjNf2e{( zUEgkt-u1jhQ(e^9*Pqwb;9rk9bGWN6d=J7gm(+NB4cmtv77ct9!t(T8#(DPr|Mp!Z zZIZwyZFAe@-CXjTzRZgF<=pRiO|DjAD;XEY104q@@7FxCtO0(TLGTj{CP`ZBgc918 zIezc^JXLgPACwe92OS>|Q$4VoLbnNislF8Qbd+qK2*o=*$CHML?a*?!i$IpS+pD4s zJo37S%kl5 z%{$R|T1p}(`S~P%w<-ng+CV+8=hY3(_k*o`?O-86h0HBV2b*?Lh)CosfkHag`X`@0 zIk-&0p!oT8cu+El2RP>*sWXs;*i~nBoM%IiudKb(=d58dR*b66@42kypBAQSf(AA- z_+0NAhCc~%ZS*{jtO8VFd`JlTA#KY9%1eQ#nk)rT7&RXSb_uOL8!05iVZFeXP1F-_ zOLBPs|Fi&ld4ldp1Qh*}F8>e*gn1#;8WDWjUF%VElp2h@IZ_HJ-IV!}_bpX~SKo8% znc)^E6O0k&{jc4SYXUC0?zFgZr-%%ubvfJPkaK-+#Wy#mfx{N=QSGz-LEexMYBDYs z8Cw<@$oCCF9@AI1D#fSk?T+Dq;4lsz-adUw?9wPIPY@HOb$2Og0+~IF*`yzHjvABZ z8}ymq*blQHe5~Inm!P+=pQsVFa1fhmC@T%`x^89_wgE?RWzr| z!Dn?<)`{ZQZxeXI^5l0toH4LccgWpy4haQ!2|L4x7F$F#jORdtPyHK&rl$)7SYV;5TmdWQawdkthT23v*e#`4wiY0~HlL&+`ZrF5$C4Vq4Q zp^(34zAT7ebrIwz_r4Cp_P%@!A!~1r%<7d#yu$8RU#V9_;-or~GkhxYlGuh%FihI$ ziTtRv+`bungOu3L_frjpAvU(7)*mVUMc(Ikb+@KJfJ}0Gw|Uuc$H4E7XaC{Bpdg-Z zL|huLkzOx87^>^EYpM@k#Ir+HtVeM=((v_o0rQD~$5W{5D#~FF|J(O9kByFN%AR3? z45AS+!k{z(2@dk|zSIIVWEMCjBxd65>Zj8xp@$R{pj2F+bPEh5Htz%cBJpNU9d$ge z5Uem!*aTyGsx zV^Y|zh}upR%=DPxI|Xcp2`Nv+Dzd+I;GT+9ryR=Dve?A z_j(INI0W(&tkI9Xy|DylC{TAoMCt$Wbkp4iP53NMmOC3?m74V&*8Ac&iDJi z&+~bnS7`rmd{Y8Fk7#<_D(Nnh^R@prGS4bj^#wQLMF&%)4%@R2^%nv+*qYRa5$N}g zXPGyTiX%VN&-XFsDJ z7=}6~GCr!q23je1*F@QT{a5wnT(5{Lo{fg?_C~={hYq2qleMG@zy_m|!WGE24zk&Ma0=mN)A7eH5a#U&Wz|Z$!i;ZW0*{eu*Xm@bM+%-ZOZX!3>K*XEUmq$4L(6 zUnrt9lNm~~f5Zk4jj?*k!6^{OVI+aYAVRXHsGG53l?HVnJ1&w3&p3HNb+2urbe>0aS0MOb~PEkp&}x#s!kcq*8lmE zEToLHYKjW>n{l!GeVMzgA#W7h;3l@v4tpRWbP8Rd6SgtO+d%?^Fz7^x(+&lJlrQWG zyyqBj=Le5Ku31@N8+nBE=;k27`Ka-ccr5q#N03lD7$Lr%4%aUG#ThyChuSR@UMRNHRljxX`AxkyG!U{7`BQ_ zSdtLs_t&owsOb4D+ioM$y^;-?8&) zI>s=y2y=Uli=yp2_MOIm->Nh9qrS?v5x*Ioj=!gIRv6ige!*&1)7`rKGow$U%KG6X zlilm9O8-AkwB||`_U5l>6)v|xC+-Hl^K#V*o9{B?11Z0KL%gk>*#GK?=t;M3$HN}V zes=25OU4Xg;FrLPFwB3lV5vigD;jd!8e$%fZogOPhNlX3Uu`IZwbk8)w;n&K7hw>= zAwW!U%hn|CS8dX=HnMThsvrNu+Xp5dqTKM;!*_$BJ_p~2eqB+DQF}%=`t;ncP{Ci} zhKy)f>4QyqKy?b_Qz&8taDcb)yrzdw2Sbrmkmvac>)i&80{?)K3H3l~g}k~oW$WA~ z_3{BI-Fe=u)43qr%lBJ#plkZ2~myucps+|SQ_~{Fjhas2yd{l zCvqOh?3?Yg>3tIDYY5|yC!+P)57C=YyTw_3-J5FOHX)%?lP?^_<9p6dIOI9_8rug* zkAS7!pyd=J`>}VMFnwCUGH}6WiXg^V|KlR}o;%I~?#bhYTaVyfVrd-phpuyqo$j*= z;f%G3J`A3ksGp-64&w}NcdkJ#*wCf?pdm59>ek2buw^lPI!4_!tPd-~Qxk;|m;+jT zQP*)T9^8qw`ro8;WR+v>wl})8zF3Z4rr|`^!LueLZWEOCl+r1lkvfPK0)64S7&;?* z7Y1kKTq|pbgK?~#v0?Y^YP~cid?=Ae@y@Q?H0VB;_(ZWQ~GaS-^4SER;e@J9V#D~7y;a8oMKiQGpbx%DQWZhU^Q1x;gUOk$~G+|Mt)053|br*R6!#&rl4uw!G#bfh+7`!v`L zb4D6hA1;UzYU*gi%Qtd5gV2*}&c-L>(>AgnlQR2>Cru6IWeI!C9DkbUgBxq+(#hi) z!_rt;A}IY2ByBe$tIxLSt?(Ks)cx3Sbu2@wv@}R*nEy({v-v`yK_5*cfh~R-mfyqp z`JX43Xc04qQ7icEh!yFnTV+8mqsXoBmec6fe56`D{9b`nf#n~(u7B+lg8{rL2!1cI zjNS1+j(4nRbVf9yWysLSrQ^$JWxGqy{V5;MXb0ZiCSl-l+pz^oC7VARwU?97MOhK9 zz%B68r>fx7`(v}wL{i0oMHnjK6xmfr`7Xd7DY@(((SCoq8e(Ii)yA+L0iNA{u+URB z#~pMTwl=r?Y1%v_G)j-jTTfpB04?F?AH$>E=&L6D*oXNCkGqg7&w(E3GxxQv)qK|z z8}pP@?f-1}swM;P&qJ;)3LOR3-i1LHDHc>`o?B{!)zNeI)i4U^NkZLr_VRV}mA8BE z6P<}iVkD_6B4U0B3X$i81}f#~8m3~DywJ2!J#M?+VaYg9;@vls`XCZAHz{~G+QBOb z4PPUn8ByG#^pyEqPO-aPIf3o|-lP70xy99YWuN$4^NCgE=b<)TwJ7CjfG^NdCz)|u zI$-JxLZS`_lS+*)2AF+_@bdKyO3IOW`py0sAv)dGj5P-QKKHNYnS@^<+wdi<;%p*8 zjJ42(#vX&#udZ6=_TN%POTR1>dXI(P-EWH4J(fINnMzV!lJjWo`@_5wDk#O?JOz^` zgHE*0L+b8)pqotR`jOenfbTC!O)LfuDTJ6GuLNyTyIdR;~1`g4?s->umX33bx z?He-BQ^mxnpRXEtzDV6kui+9uRRXH-lz(;5I13zPt(>sWMr)@kPUzQu0oE=h)ah2O zVv0OB+sd{b!zW;ad6f(#x#-mQ{WjHO=GWYp%pW%+!W`vQx>O}z9?04lf&JAc#F|^= zQlz!tT!sYp?1rho(g2W#Z92QIMm%U)KO4UX#T4d~EC1YVM;U}+9f zHx5bfSH%Q&$HXYlY_FO{R?o4a3T?mYem^!U=zWfW6bzwkG27Yh=R2eoyh14s+uHAX z3~g$O@@xDS0w>r43YVu|66!_L@|2!6MVTzZT~@9GuGm4Nh_iKByhn<{oO3`A`VW+Q zOZxFuT+hJ|jp|{woAc&2^cQgnNq(_7q-1s4a@Wl-xAAdsNmsvN)a>@^**C7&V42yz zdabIQ$e90Diep~a06~L{t?xh2X4W^oDa-}m$`Xl~rUD(&*JxYEGMEXHb(w#6-C6&X zviq8)26eVI6DS{jqGPw{VyH$vi0+Ll!zCpEj`7cT_*`pC;Z!p?8|8`A*w$=tQR?mY z;hr(74}X@9t)hWb>`49p)P^^A?B3*lX}MU}WZZ+L0eUriFmkxse9W$+Wmdgq=>loN znu5VIHt6oJ1-!NWd~Ok+y88yHTB3}}tfB8-S+Fejv1gLBlWbCX^RAhw)GQ zF7>tA6;^En{`fZx!WvvU#cCFYPT)R%7nKmnuf9^6-^a`rkT*&3kktHYrsWt3vbXG~4dIUG+eL4xjeM!&ckhfV9+kI42i> zBllZvgrH_D`rtCXghJdt*of2Ib2T9++5NBdIuV$C@tZOFpZMQ{S)%j7UHC3cFL_2s zk$>GoLvK-qN(07W(BA)Oz%j|S__EB6E%ami&-xE7G>@my)!L!6$wD0ESVHatJ#8}@ z@{Z6LIByj1n0@-L1TUAve=@~+%(u2KJJ$?S?sn32x{ z8RNJ1NZ4+1J3b0{rea!cKXKUO=>TEC)E)d#Z)+>B_7fQp@ys!7cl4a*RHJK;*a_%g(*2-nM$7V?y8kX-6pn+0ElZOBgc~mOnyO zfRnpq=on;1h4Zf75w!U?D(3GhxAAv~WSHOW< zbfhtO(Tc1%n(cdcTvD;xchRVmRf!kGq+D-|eWU}gx0M3LBUZ?o92^SHO}}g@B7{op_PXGcBO0UF3hs^&Ex zOO^7^{BB8{D8L8I?Ku1#y^4>b(Hjd!+flx~W@$6&`H!KL66z827k49$$9Wi(L0rS8 z!M&IdO@mqpy#R;>!}WJjf##{3ItHHtzE%GIg)H|n6}kZVuVlCSD1fU#eq8fE&#c|6*tqC4 zDwv-Al5wqguV}kdkWx6(_zlv`6rU)quTtyD@^n0hw9ANh<;RLXP46tvFQk~Af>#0TLf?k~-Gv;P`&@BzYI8n{5h?q&U0CQPb&fZ+d zr+cmBH>gtnx4(`VPXA7MFv|OqEPPQx94XSs-+sx31R+n`j=h3v;c4%7LXQQksvgQztwg(2t-C(bu4&j1Ni7GS5}u&2zmwfyT!R$- z-pJ;6`iSL&4rjh6jY@Y4sva5`(4Iuuc4KmQU?9m(vRE$_-#jY6C;+2@;GE=D&?ihoAY@J)5CvfC$3o!EArX4@y5&i!hy zcC7^G2Aav0rhhQ@H+%e+S?RSs(V8oZrYmu}#`NdRwiQYi`A)w3s!B=nAac;{++FZJ z_7}+!ZgXLCr7mkeNA1Y!cxQi6GV=7zOlLwBKFN;x{OzY)V7OdxTG=w}Qy^~uJUbq( z#6)1yRs(BN*V{z;)PmB{w5LnN)A3n;AHe}*1N>-`i-w{y#<1w# zuRrWd#kr3usR)GIw^G9kzWJt6cE7{t_JVKs;Xj7U3NkkplJxx58ceAALRexDA|kiH z79sb;_J}J&#S;$rqd`MeXv$2#fK;nTcvzRT4_z{T#~J_QYvfAwZsm2W*q@{OrUA9+<^o;I z^Z(%F875@&4kU1^kBVK5&Is$op5@l08K8T9d$kE+n06A(Xwr6X$!FTNaL{#B56&N) z3o9v%Gt($;P8Zl!j52h;NTkO33i_8{;jZBnv?z&(Y@*pqzy1_(nzBJr_MWf_-ow}Q zp3_8_UYMMJP|8p#DJl7u-vuYppy$jrpro`~Iu9bPO(ElA$(LESzo%Wqvfz1|qNIV% zM3ejPkAW(d@f0lXU7zXDdc53og#dhJmqndwCmGDE>Hq9v*sq)!q}16_B!zYxQ`AkN3`7Xj*h|40VtLY7QSzy8-x^yow>J$RIgwy6?7|l--{;O8~hX(pTbX znf`HIx9H>ZU-?bpirGn3;21)p!u#Ik^_(oZP|g(7abdT2kJcCD<6N);;oNl{Nsped zxA9q9J11&PV}O%ayy$j$HH(#guGEvZr||5; zf&AyBgKdV*_c0+?F@CnS{QPdrG?re+pa?0qBlM^kbguoA2bgh3$){ffcT0c5wY8Zt zuO2z=v0&>~^K*l5CN~7IP-EB+L-$hjWQ6vPx@cKa?Ahj3N zW_du}Dn|gf=H5?*oTTOL2BRX7zZs{oumT@$dmfAai4WV9bw3>-6*NMy5ETPO(U03j zd}CmgQ^f@~R2;pCo<|^jcm5$sf>HN3AJ9D-a4k}+-u7I+OVDT{v{2MJNNU7uJ=@2O$wz`Nhu-&F zcQZ27 zb6M-&O#P4Q_)Ci~fH`{}s2qbe%GO<${_P>~D7Ik%Hw@3Pmv+0H#k;6{=^M3>& zGEM!|_Rfx5|F((i1TZ-=sB--`x@N?elyKX{U`kgH%Px+{tA|mC2oqSvGGD{ z`&m&`pi18GbX2pUk!eNE3iJiqA%B0)ELDuxcyh5eow?9To%t!8s6s!=+Q`!VmCl66 zKrs+3FmypE@Vx6ni25JUUcM8@qAXwe=>-GU-*-BFx!9d* zg`l?c|D1Pl;k7hQWGmY1_H%9iZ6v%v8lEp2UJ^ax;>LG2a0$fFMw$#x}FWn7AT(RHKV!yqQZc>W_;J|$7~| zPR-7~p2;1t@d1(48|!C<(%D&_`|N?2vn*@P&DfB90yrD;Yz1vgDBi}kWJE|eBTp=C zu!>sIzQb?G5F*Cc}+vqa9pha zt_TOTK?Y%rZ2QB5wLRV3WPv+b%0h{cqA10AumN8`{;HBUO+pi>F2%I5v^2gDV6hWU z{+`X%nqq~=b5bU8W|?nOTkA0_GOcL4F*9sbhTZe}_IG`7^W;nLPU7{pa7epTiTkz3 z4{QrhYF-!U@3}$=VnWsn`C7dEIR3h;k5R8xU>F2ep347#@pO);ZfOGLnU z?DxWAeR9Qa;vce|^Q-`m&+AAIlgaVlGIe#@rI1w&cpxvdcYlbt4Xvf$W0wKHPEyNH zH-GrMH}>Ci_5D&*W%1Jsw!`O@C4yoDwXc`w5E~f;%&qBn#-l|V=XDktK#WGBm>ObN zfrrk6AD*UmhQ&~^Z~Wexp8F2SW%ME3OV4vsx|bgvrYg?m>%Q3Skv8^9osG#(kz)2o z3_!Nqrm{uzI#&*ll+W-SvWaPKn3@%Gbm+Z=E_AP zV;c)*gONg46TY`coo?%Cj+aYrtMGcX2o6Vz3;61PDMxO@?1*t2bz9IxiLKQd)XVD1 zq6@%pWO4cWS<8amSUV)-4jIpjn>Q19X-g8|gy(P5%Qx2f^3^(4L>?e)SI(`|4*YHK zCh6J0k9qOp6_3K14|@2CJ_IEhSfW=T=n8i1fjJ%KIlde3?yor zK?KWc*m@KKKb3hU+91TW4|^@F^~h7hxyp(6S4|zVF&GXVVh$io$Au@q?@kxhG``|> z3;zbo`^+=BLR^e59+rPOtg=O64I zq{UDfL{10)#{#HDY@t2LTDZBN9^NO!SGOweDZC0V*SfBY#UHK|?BLnEx|ttcpL8a( zDmMu6q&vTn>1gOsxcX0suYSQ^Se#p^I-QiQ@{Q=?p*$T&U6EfHKKbuPQNl$I(zUaz zt#DU5cGnJuI&)OkI85onXI8e^=z4(Dbn6E6*|X;hM&mSazU+XIkD1#&0%hEXkb|6@ zvJA%7L53>{nK?YdIQ53c(ZOBc3xRDfKU2+(_VqifeQ!JJaLWYKM^N@np3hrb$6K16 zT_xxQBLgIE3^F5V zRah~)zsg39t)EpvwH5SD2q%Y$bPB8^7`H?#S}tgjw}zvi`r$Us|+0sONyN~vZSkGV}Qaj@L~=vPZ%f2h*ODB zw8*At3T>%wl&MMeEw$-?f5BK1mgy#Hp=<(iN`n@-n(!~rm!pS?Uon_H`#L|<&`ezYVg4dTl!P!v zJUwR3`eA!M;UiyfO0UOZ^Qr(q#b#-`eF-89s;Tqt+P$3f7M5SxeMeDaE|pCoCG8Fn zEP9<%z0w*S)zr(@!-Z{q^#`4=`P2TN@f3D0h4Dv)!NsDVw9zI^v3HTrcs8;ud9jE( z`m0mZPHu=koM{7s=3SdV)y{6QzBJ)*KfYK903?4F=4KHMI8LxODd7SD*g|;#UqZEyOys2NM;%L;ymyu#UDx@h?TCh8=h_xjJCmwk~3=_WCQ_`}M z6l?{+Syb4c|3y#ekAnGoB(` z3X6!+_kQX4%Qu||nQD)r1FU_xNn#z`9PzwrEV_U504g%~ya)mWi?H{W>xLq0hT5Pn z)7drC*SCL+2~~HMnv_)l0GCHU#_E)jxWw*jXxK)m;zs_m-3^ah_NXn0ckesARKs6G z?*~mTgWI$3Hu$y;RH?kw#+K*JaIU$>{ra93-_T|j^fSA;3ZU!>4q3rb9T!Bnc&6;* zwon4X#VRO}vlu)^_P)j zyawvIC5?Yt64PC>w%IOpcd^zHlFq|-Td50xgc`|R6brVID{(M;qIqc+lk3jAc|n3` z@MKL`3$Hk;7Oc3^eL^pQs$neL-+t{ps zKhHtoAy9(K0+qZ{>!#4;7fIMC03MZ&(~sRl8k0UH$36tzk{K-hCy^Cl@XeD_ai?4h zAjn=c*~&!8u}J^QOfjrN@*M z(H_ciH-&7QLX&EU4%8o76kX6~1}$5+gjzx|`6Y$jr1f6EZQDkp-3k9SHK>tg@V3~f zeUwf~GraRKE2uGKk`ZhE9)<9q{`rnda+jXO_DKYf=uc6roS4ri){i%Hxn-g-OeXRS zJ8PIFO!o1bz|X{)i%eS4Cpa z_vbt1PFk`?D@Vw3B(}Z^ZzLfZ!EMK}rbk}-=G#7*$Qw;2`SDI`qh^9eUnfg4W>275 z`P6-ERFcMH+QlCuT*eFYfC2c1o3UEWSPU%NAU!=ROqXKPG>TOm3}=T(HNRS9cNk2F zs=<0Y_pdOxd6e`9l$ULXY#)+4(wj39+6Fn+g`68t@oCWPUHS)T#scT4kYB{RE(3JYnZNhT=++-9-OQ#gfpJCPaV-H{*47! zaAA04A?ac>1=|-~(PJxShC zy#-er`NrC-eY$K)wI^<7wwl*L0Yd2sHvP2rQ!s+UyrGLFg?f}MTPVQXJyvz0?P>|V zRzUEp9e~BZ$_l`}sYq<<*=Y5_SfwkrWlrlj)G!BTmEYnT1Vb$HQ--E#6)b@qyv|8U z@g{OeCZTpiB{XS+x~yahoU&f-2%ED$n{3-*8=Cs#H=9Sy?;vVxjyLnNNG@cQmnQ?I zwmx|WoAU*S7bvUGUiO5%j>^X>>^m_4J&rqmg4YC<^q&)a_ZmG8&rk?w=Lpq(r$Tua zF$7>GK1qm5h>>=PIScKtKsq>y{|H`jqD$<$Q(052bLu1 zWWo^E&Bjl|JW@PJv8U;)N(rCV9c8Q-3QQv6-owTeTilfO^eXf<%9nnQ?S|Y0V(Ncf z$^6z<^3DctaxKBgJR)B-5PNwVn_15b%Qc1nrGN3}8;13My=C9JnIxcV8OU|4tPShJ zi5g191=EOS<{@d^R_&u|<;T9RjL!~4MX=P|mcF<=ZY4-t_IjbQ{@GK#ox5!97zH3S zA4popD>|tDZfv^k+HAejU2FD{EkF5^&=RsC!6a-_eUTvf%c_rNY9nip$l@dMQOF}s zy4|}6LXj&#_pWS{xmBrLw6$P&sIl|QIKAON-+QhgK5)b5m-k489;Yvt2~JYiTWL7h z1V{-h{Z|LS)p!a_;+Zy8oZf>i)+4`=JBF!F=jcR@qb(vRWQo<_8Sa2=G5L5I^ZBqc zSdjI{GPfpn$`8dzTjqN0u0v1Kiz@LLI&-zvS@tEws*avwQb!ayw!v?G{j)fw<(P^4l}j1hHaZ1#1pd&YgdIx-F=sG(6}ovS$`eU`qVZfiTeo#i zID?)4!}B>a&rQ*`v!6Qi>)T{%b>X{-6ZEsu+gw$!`{fQ^8`zD`?sjf8-Gjr2!3=#=dV(_6ln{?3&ugTv?7AF}zYarU2a<8Vg`1BRsl@<#kd zHsLlWcqUk|SKE9dULs7rq^~`3s=Eh>m~F|41<>ry%TUG}J*s81v1d;$0;MYLR(;*u z_LP8;kzpj^F3GWyC2__)CFX#qaKXD*sltI3P4Q`}22msZQlgr@2jm;`Ot^S>U*o_O zZ?)T+LU8SjMURrATH{F<9NUCVWilnL{s3JgK?v}iqk3a|^cV8GaXJbQ@1j*_j)irVpEqP)rCXP_!!mzPH zfGV3}O}z~vNg6?~EZ8P&6>cM9^P4LK%^m(5mvKbHc?IqNVX>nzaXClMoPPGzz5UeBKvjJro!5P4XF1?a*3xdu;rHO$j5nwgyk zVp(6h7^m};SE1UcS0SmH=;$LMKN-b@V282L)^>fuQMx5io%wX?6@ADx#lxXu&L_t# zxjSq{H-EE6ccavMQR9JLQJXc`AYm_&hNG;$FgKO{Ua6>%HR7urS^pvo3||@B{9{ER z3j*@VU+2nvGK7FdM8$Yo3iTo5yk(d2s_N3{<7W5ugfm|i1@pS}-Z^?TZq{#tjmb+V z_);tDOI0?D0K!Bu3G$ziTrEbKxSDuk)7W+ldO!4Kl^QH4cp_ttn^ktYZJP)t4p06a zazLhc(SxMoyI_>fu1FE!YyH{ku#o`O6 zypqZ*pzLPu^}6hyOIG726JF*)Lc$3jHiM7%VY^nqp6h4jTloV{+n~>W;rwIOZOX$q zEG1Qmk{1fsahqT+;m!lGW^H?Ee(=ySp$G|7Kcv_N_Eg(<3*APL(D8__YTJqTSB$Au zeG?_pFJVCb0p$&i1-2FnMM$JWKtI(LV;qpNCGHR-D=K z0O)#=l9jsg*W#LZg4=vBbeeu(J(%IQ!_-XvRNziplm_DO3J#;YO+nc$;!=KKY3*x* z=3rYobe2-;hnuDA4u^W-TUIUSCxL{-dLq&izND`;_aG%FTlfLXrERtdT%9GGB{q&1 zY`L*goE0_)?Ym=q*+BcO)6&r>Y3 zK1nc>nCxVtAB{3Gi5xVMm=D|{A)PddAtQFZ=lt@6T9#FBxwIxW&PSmnNB2n%8{y07 z53w|gV`jJ#*)AYyw^@pZ zL`r}eX(slEa`0Dc-`~Q^ke6aTpi+Q7rFG!x^YyW8_hH6Z&GpW?Emqh>viHVzlvy6e!tQG5J!3fG5y2D zjdY#AvbkQq3RUqw7U#?4cHgTZTQQM~a*HZ@PPW6;I#aESqy)F%l9~vk2?+(!X zbwuRDB*%9oEBzB9TT@NfCGI?d$Ub_^!_;(FK_^X+jys^R>T@E#<<2q{&mXA3%$()| zm#+3$qKN0!!0CWHWr8CO-*tPbFlA*_`DIL|`&2I$WMbZIhWC+2iknf`5AAMYRO#mf zTr^prk(OmxHGO~(Pxm>450OKAnI1rd%^%)W%j}A2kw+wy&ODQJvui}Pkdp7u%!XKk zs&31Az3%gX-Z6Z)^{VSINd)KC4zG^izuteypp%#lkFf;+_8FMjLFiG3mX(p!mku+Z zhpIikm?M8a@Q~t8wbA#FpAN0yH2$j3HG~8hs5QGxE@R zKC5~^VkeNiaMqEu%OTVg`v>Gg%OLdjKnX62*Ic3{%+j!i*Ap(|n+&vu<*Moh<({ls^*PAd)aDTpkU`E`fF2#8apv~Llk`H9}i;MYI92D12XWd)7$e0 z)T|B;a`qA^AHf=HM9^3LpWDr8pz2%N7u+gDm$)NU2Sb~g(xO88|4Q9MMRP)T(~se% zA3uRr56I}V9^P1zrQ46%?3f0$`mVMJX7l`*=s()c=5AQ$%qs|0--6 z__+u84>%m@zKAX%v6wOS-LiC#wNMt44Bi!K`?jTC*#GkDz391-6++&1Up~0#INm(c zoRC8MNJg#vd{Z?h{znGm~xPaYZ zgFX52r-fHWJn9U9wV=@SNZCkI*qWYu@6RbtT$Q!BAs4o$Ek*BP6J9ooeKLUe=e8&| zlG428=I1C^!MMLUVZD0)`nOs$=_9`?!J`-@69qH5?ZG#$!9_yGGNm{ru$2J0DNJ4f zSy=G_Dl+~OStDqvTqzXeJORrMWHy@g&SvLChP{B;dd2OM2q}iUyFqwyF8Tt;6Dj~T zWZw9nz_T5ws-cW$S$qM!ILmyldbH~_;gbW&-y0YEDMY{NK(66D{c+nFp>H$;dS8S} z!Gvw~0X&`o^PLF8(WK8>FEPj>#AqcP_!7gy2R>p|Mq;uNU(gV@X13d|6Qr(pzFGCA z7S%?*=8Oq@lJ=s%_uIboX^MYLBlt;652Z)Aq;Tl1XdcVs)ec-^POhQrWRzcBMA8vZ zWaHRfcl20o=o*Q#8BM#S!0%*YQ-M15?OO?YFoO_;p^ zKO(4x69E$2L1wh`lA!Z7^J4I;ULDyd02a2a2qoaWWNo!mn=PK!B)5f6Si-pjF{Py+ z+XW_6Uv9k3Klo2VS+YziLd);@+qo@9+;wjua{?zQ`9ruMM7{*_{b}9lR`+QEQb30F zmu8zp;EDF8?ynhE_>XIwf3s)U5!R6$C>{~nJWAyN-~my0ZxFtW%J?i#e~if6nBefjm;AVL{ zQavI94i(>>B=zvHOf>wcPb&@Yq#5OH9Q z@!>WzF&43aGblRv0r}=RCDCTEBTJH#68-DIo!iw%gaI?vKCFt?tiJ0acY|xEPvc!k zYH}HdNMPG`X3>1GtQ+M=EUO?d8&42Q`~m1p{tM>KnhMmdUy9yS87xf#mgM>yZ+K z8uo40RRV2jiAkQ)+YR%xEiVL)Vyl1~h{1}bTea@@_PxYdPk)wBrmdQ?b)fL@br|fn z8f^KpnWJ>1Xj{d%GCu#c{Jd8oYFMddMh1>Ov>DRK@>UW;y4x_a z17@O3`(+-dW8~iyw>1x_narCMZ!b&w!gx04yuCAA5AX$W~Z-$JyPEZxex;X z?A0~Cq(e$hGE?)#UF1IJ{+UT?jo6oTeB+9?@Ui~7UZ7L>XJ9)3a zv7>^$M#V!a!;ntrrI+UToLDYg?15y^25V?K0Gf$mCuq4|qDlnk#Y=I5dSQ|Q_3RSy zXe{IzvOp9FyX2Z%=-R!f?T69a=3c$^X*|&bP{NXd^>ZYl*1@+)S5xeWa#xY}WpZCX zyca-;*WC{!q;j;OL3AS#pXk}8ak-G2Dw6C48BVr`kI5f1Q}N+S1G0UgpDTaI#f!{u z6*%b7h4s<|qciq?a~oG2D2eCx1ZV4r&Cf3 z#|l8doPKlB%~Z+oGg%+!onV^n0nV9IyQ}lDWyk0WGa`yuYem~POgVdbe-DVzjGB%< z^@(3%b{JXn5Yv%1=KZ$rPTI!hO<@Ic6aY(?1`beJ*NA9cnp0G+u`WW?UW&$(?o@P` znMX!qI4c~8RpdGdDa)oeR=n|MZXHv9he0t#@y}P?#Bj)O84UGHIG|x$dE`>Nq^OAr zSe7?K@Tqex_il;O6dJQdKwITs@2ywg9{EiLWMN=h;j%Ka(N+Kn6vKa0!h9eJy)TRD zl@rU(*fe8V*D)A-b){71L!6f2T7`7JVGDRXhaczXY8dHz24qzHu!J24?nD?0soQWJ z*UU};q;7Kx7)c4m#MA(;DbBE*ieEV!c%e$TjndaE57}bAHqm&(|J0R>bn)4^SN!?7 z{m^JKDgItVgVa<`f;V?f1=qvQx+K`AC%3wtHj90U#NlLK>_Y0SI%uvlaew8$6!Rm` zV1~5YslEAA#Gi5i52Jw5@5C@_Z+BnanZ$QcmqY0=Nx?fA`qR&5WzAk8^WQF8Pg@`( z_XYiwOCGW+GIy7xgu_q%j|JFjrOy%}-Beu~`UzTeuNc6}WVY;)E}A`y|DaR{6K(r7 z)1ZZYod~N4E>&RU)E(jBh6r4`#0xGgt=(lS82fI~^wU1LJ+$5|z zaG#+tKg=4B(4r~zwWiQVxakshi@cBf9^6sYwC?oL*HJ%|(|7U6eCg3;Ij4aH6=34< zF1)^RR4KRdDfS$;an0}5-UYFD$;%ROiJ>(!l*klLRwA-9KPfTql%7p2=zR=qfOc-9 z9k*&{Bj}2MF=sd|vye`#O<0{fppg8`#<>ptS|)WP%XwGZ+#&B=nncSwh<9>tG2L5P z3t*(}TRqbxxJzZ3PfmksPYF(E_M#pVKK=x&Cavu5Uyu^6y)MGut@j}sV>l@K+H(0G zUSer8tDt0B-9vCcC&8SbH0_ikVcPlq_|-?cYf--)yG^0_Bno& z$D-4>u3w6PEba*xBoRJ>F-kw*el{<>ABh6gZB)sh3v0YO%DwzF_r%p3L1<(E)g_HgGb+uQ+p$CQQX&yp2^4&nXouTIbKs{TSFAhlDdu-|bfu8f0` z9>0@*_G$UzjWGmzQu|^?o#cuo@GR^-RcTN4v)OEOU1y>w227l58Zid{~hwuk_a6=;;LfA^KW+GC1!0BnH;z>ib z=lNU!VXOUa)^}RL40G`uE{r$eO(s#-+vO%fR2B~%-e7?MHq zlWf&HM2^Q0-rswVTYMkcdOa5dyU=Wv;lD`p3uq6`VWAJk90$M58ro9O-WDivt{n>D zy%#->G@w0`L$JAhzI0#rS1D+o?7hAm7=phxmm+kIn#C9HyJ)f|{W9Aq-23jo91C@gwHw*7DJ@u9OG0l&>*U_1xD&OiBrW;7N5h;LlerDVsT^;o z62nWT?xnFHBZi=5&~d47c^L|>xm4A-(qrrS-gX)8Mr&yqdfm`vN|=zDd||s(_}lh* zv4S-Sz_M}puZZ_|Xxfw{VRxU+0kT0%EYWpaau9X#(Bh)qBlufH>dbFO|6(HWKFS&{ zGa{6*jv6m@a90+@8+3lg4f=5TUGQqwO;|jUq*==2R$A`p6Qap>*X3(dfLX`$*UOcE zH(M?bm!6^wViR1dx7z;)R6(o0N9?OyE6R{k<*~3sBC*aC4gx=Gy-)^1vakW6Gb}#t z>pUm>mg_#2Z=M{2wJzaSfr%|{4^>L=688O;WX;yn7>f$wTg7;K@qEPc3CYY)SRhXr4`jR!ln{ck-@r12HfJE^nN*4{dNH0L#g3y^s@1>1m-22Og|5m8lkdj+=X_HnRi|=x>^TLoE!>cj^TL+Fvh}tt zMRA)E<=OT7ZW5n!)8x{Qj%Sy_8465#g<^DeUDAr<~e9^wHE9LO>vxErLOa@U0x{+(othk)wp?v~Gfuw>W9F68;7jS_#%t=i^knmw zb&;~mot}z$DU%!ppMtGiz27q5gaq*h3YWd*mR}6@+Q{9a92|c5;ice>Bg}1>TwMQI zV{j=jHvg1m&fauINFKf@+#~yu9%e~&hTDPvBqrVOaoCoDp9muqgZ>IGHfK z6iqS4xON1S1dJ9(efB+tkhfTgd!eMl16$k=j2S^F=Df{$c6mH*{YK|~p}O@pOw$Pc zju)lOt*c0SU;(SwN5u~JO6f#OTn+-m%uy<#-qGH zeIwtr`4g?>dK3?fEd= znUpg+?cVh1THm{qIjzjST~WF;3FgD-=p-+G+71jmQ*95?xM6PmVFxj} zR6Imob)G$Mr);)k4+||BCdf@%YyY=a>FB$b`|ukkXbyuzA2Alg=rJROR<7(x#YsjH zq1J1|6C{*R*b&7m?@Uh-R-uGyw&4p=KzKAIDf1%ss}Xhz{i7@NQ^@Hw@!@^E$r}5( zG;DABVGezZ{IF-2dN9ZBT{~`zXQOa(SXjpLFy?kXU3vMnDwJ5FaC$-Y_e~g>YL~)K z{oeODPE(vDjnFB5$y4bomg(Wv@Bb7dMf$w;O9Qv#rij9*aa%*psBzPbUEV~-&F5hX zajK|hZ-ibm@^s@qVv&(2p4GgQBEFP!8Bc6mRAZrN$NGb{w&PAZLov)`P75&Xt`!jm z`{#UR2$+ek$Xfj!=GkrYP^Qfz9A)%qVKh$hZLd+`Qp3jecV#MV$%R>70l$r^86{x% z4LFnLv^@LJ-}7z{9zHlz8FyT{@O6Et42;ATEm4UyZspI%tn z%TnQMKKS}l>C&XNqJJ$MvwzcsXeX4e{X8iIu{~SxVi@gj@o_16Xp=7M%31FA>0t%a z#XRMqgDXyr@R0o9JSk@}iYM>9%cXtPfUibY=qf=kUT4NlZe=SUa|XnizA)d14)%T; z!*qCO#%RxWXhS=0%XjXG_g8W)ZUwQQS=k20e5jdT6I>56SVsP*Amm(y+;L|j#ecM8xbemt>ud;jZw2sadF3!Th*m*|q=LYKVY#;{!Xjr~ zZn63DHp!X3{`%{x)IYifrfqfOVfZphnT=6aj=aj1U;gqx6%BE|@>|xi6y>!m-1d+v zX2sYm1iz!BSCxUcHB5G6ZhX5+rPF$Y`i4?;S#G&T(|7`YqX3uQX3|f<%()PTDAl7a zax*MSW7695Js#9HMz>e`N=7+RF}bUFyZ>Yd=M|$=OdkDzznqcp4Y)Od+VyZ&iP#poriS@iRCzOpUIXraqVZC^HY?kmKdlBFi%g&StcYelEZKLG_va5)IUBczcuhtL?rFk0 zD&!#Exz>X;DcSeVSaTAvm#0|7ioACz1q1p?_I-tET;lzx{q6U!8nv$pHysrwI;jCS zLPk(QY$a9`vM6x7?6PYKTbgVW#`IcB&qn?BC|<_F6fU^nf>Pk*b$<4hXhCE74 zFp66gKVjLF9{GWKa48f-kQAjrA*N8sFYOw${^|TUCs&S!)+vg_V163bw$13rHJ(+d zh#*ACZ5yRhP!%#znpzqDuJF$5>P(KpFKaPJ%+UC%#mYZ6j=dnPVsyqQBoY8xt7NRY z1OmUwS#E`Lq0f{+`OH2ilzBzYjJe1GmTReifrhgLurwS_Qh%C|>t!fU23*oGzVohj zO?nB^@pg?$)+baDRNx8NFEvy-a3U;%Q@k0*2Y*7<4L5wN@M)Om$UHrl=C*zK`@S3Z zku_h@4}^RYKr~PV>p+F%l515IrYF2 z=F<9rSIan)`u2tAy#DpCE8!H5Dq@9}I9n?55*`Vus_c1hA4kF4Z*rhp#ckZ4+Y7YF zdDaGIT$_qvw9wiD2j?OU&(R1%H+r-B>h~!a!PC~W24?rT$32R+q_<&8v!@KZv;_NX z%y#dB`}T*&XH*Dgx!yepKOThc!hW@kGm$U=p$?bmm%U`i*+`w?* zOm*IrD6st^EiFIps%>`)+B@Fyw)tl^sQ0&fyZ7F&EJ58G@h4svef|7Xk=wg=-+j0G zznTWtL#e}y0zb3}f9m?GKCu)q1^wW*s2I6#o@3nTiU8iP@Y#B_XHjG?yviP^EnvTW zHuku^O*)byaw6K?kN4og#z1e-GrU_5Q#fpoBbWH>eQ-++3B_g@3{|9$lVun#*$)aa z0|U5`BeXVRz-ap};sMsl_|gx}3>}4+p|kK3+$c>H=^yjQ&k$}V2cz(=l8 zyJA$eVqF{Cat`%b1^Drsjr{C*oQeMU|kDLEf zkhJ0;sHhyv@`tFKv%)RBZ04pCXxCKuW5uKt^&ubr_~$DyRAy@wR9m(T#hb z%E9xUy`E>`f}7VvcFJoQA3Hr?AQW z#fZE!%qffkBQPh5mfyRk$A2~`$|Dq=CAy#UIZSag7KPS3S>rJaIf``OPK6fjEeDI91$+F38bnc&GYOAsZnB`nup|7Vy0 z|LwMWUVRVG7$^vSQRrCZ+X7#s3PV^UA&_vTcPgvDDzn=7Bs@wLVR%U3?BkYw5tZQ_ zIiqkCyqqsZktl8nm3A(i#c>rAjZa8Q5vM4i_Lm_=8Fa#_a`}o<*-r{xaMXIN{lpVb ztV+y%`UO_Q_PnLd_GT&l{=8$)J@+i(Qsr&*0iE%^cc|J-`7$q+ezls3LfLtXo-%O50IK=^c4iHMloV^e|N^eRdXkc~q3SFaM||f!s%HmRT71cw z#M{yX)o<;Z!4DmRug0-=ltu;9czh@!g#KfWIi|dKcp{qQw^3EK?K1@mJcXsA=a*da zp_(rRkO9v;C@63T3@LZ!?)~P$z~hYjJT9y~MjLdKcZty?vJ*N)sq(pNeX>@0q8ME} z-uoAI?$Hj0O;x+Q_6{AruqUG;86qo*u0T%`m1T|a%lo>p(#KUz3;U+=yNH|^mh3Cs zGADb3|4Yq*%hseyf-7sCE4 z=;ymfIg3jTm3;iX;x=s_&!|uXheFBHe(#5INxUnPBx>UvTmnoQA3`ET{Gfvl7+b=< z6;9LRXrV~T`bBhY2#f9FF*aTlPD*$XCT0DTl#xlv%+vf9Shu~CmUqmofsg?CBit`# zKGWh$yay~44%jG5%QWwu2A8HO#-heap+hK?8i_u`%DqJc; zbJ0Z~m_MTj)xDSq=1aj+3DbRqe+}h%kW_@Fkm=KhcnS+dz%}K?d^+pj=ZmSh2gA2+ zzkv&H-cCF1TzPv00)j0;hah`puFSk`3Uz2hD4CbpMQRN+AxK*STHWU*Um!Ql2*VPm2U*DlwD_rm&xBQTx{K{E=#Fum3CIp zG-Mv9xKT#TB_UeqnDJO`;U^(c$d6{VJevFLvrpZJ&I+$0a@ zQ=&{PPp(-D2hS6HC@SgQWj}I;FmWML&H=&xLm&Fk+- ztb3MH%A2e2rlL=bBP{R)2y5X{&{xzL!bJ%#lN2{+#hLLgmVUycdBc;g$@#-evAg)< zi>pC#8-ZaDx)w2)7ETZl&BJfb0*kWq33n)!?!j9pDQ@6Gs3P1igjPSlJmfr6=!2e= z1VU$?qOP)Y@>}tl^UgbO?pMG1Wu3pk82*?erLf&|Rih~lgfH*5H*KE$G*uCQ`O9CF z(t)116m}w@YJsGLyD=GiPCxzhGQv1p5pH>hDIUN1&9Cc>1;&w2D7@B8fNVW(&M*3a zhZ&paoB|z%%>Hztcuy#KhB4`yYp$ACGG99IQld-d0B6kK`63SpcXKuf{#$PO_(6fT zQRkrZlB`#uU~t{K(LdftaCM>ODv#?+YmJOR&KrY(ITL_+Y4HwtgoXze_OQ$KU4MRm zUs5o}3!G>42fpAn-V^U<_!69B{8A)MNNl`t>4yprDA(tlb54E!KmX@H3lGqUPkriB zWf*Mn#a>Vh;hR0N2jJ9tZz5k&fYJMSrocCSj>)c!U(T`f!GndTP~76d?qIm~vS@(^ z&g1U|Wzexkv=2;#(u+nA_3_D1ezN9d5BiE*T5*8|TJ7_sN}cFBdPa%Df6OCA-xm65 zc7_^83Hy=vo9_uH9A9CpiQusw?;Y2})12U&{f!42tP_&ig-dQ&@N$;$B4PAkn1~;8 zdFK^8qxMbJ(zKO8f5{J&K=X-FqLb-gc)LA^8|WiL5@QsYh=k!8rsO+U?cR^_xPcAN zZ&5FRdw4@kLKy2tJLbL*x!iA5!>2$22lhg7+zZHx#Rc?KY-a2tr381p{UP9y4m zGv8LA9@gl07_qc?Ou;_@OhrG4ifLkIu|CuCy|}vuinZYu z*2mhfe;C2q`r|%#U&{NYkz#*6EgW+1G~Nvef8KfLlyH_txx>aC7sA*gl<`=p5hKe;D^myx!n|1hql<{FWF$$L^&B^||A(IWi9Ap#p%X_o3)7EMfrQb!@Qr-YK<{`OxAex74xmIFb-)3}|WCQhG)TR2rL z+18*?QVA~28H>-W4MHoQ8KT+_S(vGkQ>(~lJj8k8ev2~ z_`&x|nI0zuMOnl!&7a_f*`IXMi38^MkN^0O14CK7*>C}K8YLJHQ``tAm>vOwk|Tu5 zIkk5GhhqeTcs)AhckQB$JfIjW!3c~nCHL@p`ivK>jGRo0y?vqxeC9KsDj_o!S9u0a;aLn<9*t7fHfL{fBBBW4&UG!C6J-Rx(P~zHDg#4;f28gUGQ0M zSed;GJP7Xg4c!P1CEo=7l4}wxd3Zme1?&i%aE5^-xn07c<@E?rrZ|MQj#G$?Yc6m! z-fl4EwUqCsf2XiPdrAhd_T6^dy_6TQh?h{sT!LAb=d{2ldFu&vi}(DsWkvU#^K5UH z;&F4Y&^#Vi_~v|4pjg<~SY!2~OK8ga>;GAWPn!<`aEBds7P5Qbie!kNhyk8LnwtiJaFg-x<@%U;)uh`qhx=)!`Zb~9(es&;hnV@Ut6c6 zk3O=5Rst}bMn^~Sx+rdxE;QOZ!Ji@r55l)7gT{e#_CasjHdGR>Gn|Bem<#xrD+K_K zqQ&U1^J{<22cJR5&^PjbNxACmOUME)&Y>i2oR=|UD!@Kn3AOEQ6s0-cY-GwVH zzNAm1XO^P4!43S*Tqr_6{NeY@uqi*4AxtjX%{TwB_5>{PDQAJF=ic}3c&GO}ljK|Y z1}662yC^cP$Bof5ikt72qPRsi2Y+(~ceucq#Jd;c#wf+jU;pPNwBL9zLl~S(4)Ul_ z$yRYgH$(t1Mlp(lp}i16^SH-#-Yen0LKxw&F`NTV3499gI^&Ep$`Fuh?2N?V8;@IP zFz;`F&&dh)op)4TAz1^Ty!qxI%)jG>1B37|`6_E+w7BiI+scUOObEy3X;llL!sD0R z4&eE7>uj;l+$tCdL}0-)c}T`hiP5*Ndw{k87EJ^;;Rmc(7RMu$kec*Ni_l;*5fzNS z-wf4#-p_?PjfIl{E)?XNYpyOqfpr}b$JF&ygER>hKnyXI2xl&?Q{S^PBH9kR!)X45 zOoBbZ69MCLH@8+Ga!?4G<{Rdl!V2CgGzX%BB~M*qrj6kMA)tP-r!{ac`6VM z_>$g#4v=vp9HpA2=iweW!9y07ycd3Txb*Du5VW{7Zcf>E%sU}a-VuCDu9JO>Fxuk2 z`P#eeKR8blVhQgMSc(f=i{jQ2M`KwJcnMnpFN_P3Kwy&WyMX@>D`vz(&VYb$wjQ;3 zk1zy^IRbWPC~i?mC{u|Qw^y3n6Z|M{=0m_oMB%iM56T+cb*2d^=I(465A$KL01NwO zkF3>Ma}OrxH_Xtzn3{3X2$nXUDPtqBU>X?n`VnjrzK|yN7hZVbAnDpXD8`f`cO-yfABmU99MYfgOc> z%3A;cAOJ~3K~#6#VIbUszg!ARNms1tAtkI4qR=?Z(|HHGTW#kG68yXH)!eR;a_Bz5&j3Z!SU4#OE{a^m2ae~)i1UAzsZc(5K9O0WWVzzLI;s%$( zQ#^)+e^(MfVtvvv0=k&nbCl$%BsKMz{fgV}h5n$NRg= zDt9kIRk*A7nwKzUiV)ZYZ;fN`w%B6xMMl@*d;Ww$^;~#nZzkp9^}WLKaXcGCkNpRm zd)@0^wSS$$uuiRwY(fa8z}Vw>-mDof?0eiOZt=J!-v(auI0(UlFBBNGDvFWy{OiB| zws6Mt;M;`(uRDXuixJ}3|DV140Jp6w?}e|}@oH3xAYHJ5h$Y5eV)+s^ntRP> zG)A!n#TZSl1uK^r5xF)*1;L7fL`4O?Cf0yxLLy2L5d;;GM8z0Oj9==#-?``aj`Lr8 z?0M!Y`xHU5_VdhV@4e=lV~+8Tcf7s4;uVD}<_kW&Ze#>>It`}%&6EDaAO1smaPWNi zZGQ2_q<{v#EIclu?s!uAl2UqjILy;$cryM#z>m^yKftVo^xn2`V+Chc@FkHJYgOE= z#T+O<_F1kg_<#v7tnuX4nmgL+Vz}}h>(%2J?=;WQTr`7>8pRDii^q*OeRDi+yXt#lv66SnVfL^@yC}pFSKcs8gSqBsq3!Anr+c60EmP|o_gwsstF>EWK&E26yv>}{>PT6!Q%$FN}p2rQ+f`eiO2seu+rkGxM z$#>Ez{uDRorCRAvZNqvh!i2wdL^qT zaou5IUGc2-Iu!FPxq+i_D(hvH7g{1L0Woqfg0kk@V2I$P-9!snIk4seX6DSQDBmPK zX6gy+t*G5r%0jV^b~&&It{0Mxw0rmSe;TzFAKcx1I=R&f@8v4UG6_5h@wR zf9k0%oTQbV-eXb;OHKe{&J(y&*8BEFYlMPPa99_c(%i}nvrG}xop1Y2*l1;r_bh?V zS#%E}w^pCWlMR=g4Mq|)ErOMCF-y562y2L~bKtDmFWxu58H2v?g)h_|Q3@`&;L8;n zW!#kajqreudEObX*!2zG+k|kqoP&8eZl0q=UViyy6$%CiQ~|?0&@b~8rV#whc^aO4xmXjWup~co}{uB%R%$ZlgjWsou=fJ8jf;BJv z9DJN(!ln5pjJ8+&TJGFgHQzpO=Mj&1cnM+V3HPiCEyhdbc9|pofdojslhfAb?8+Gl40pC1;OisF`YVr_T>J|?0i>j>UB2hIwMHS0PaKnRVYp;ro1 zu%kC@I_ELqB_var9Zx(#IAL2cF8GYH5HE{)*xNp*$sXWuj4=J4pMU;2MPJOrIkGnq z_!ntWW6l&eaEl^G&Hx);61L`g~qX`QQRm!40>P=M|ncwR*X-^ptw`)8QRW2|NISd+zP%hhJjD$%b4QU zJh6L~49wt05s7k2af8d|*@^?*ViKP3Z!{>d%Vj)k!8^SReu^Nl7uLXA|Cq=8c8x1- zz}Yb$c*jc>FWg!^Zc%1j_S^s9CTH`66Hb_nYwzt3xz~H!XFHWA)SP47xzUZbEu2Kx za^}ZysrR@gYAw9Z`<+*cKX^t-wGZe`Q`|l?*;Bvi3gDDz0uChK@to&-8E?4f&atzB zKI7|gm^ix(wB8#fRCu?0=9v6H?^K9}?qvOu2jD+AdUnr!_AaGuO`(#%yk2obU<^X| z-(!!xs&pmd(*X3U()LYQh=I)#GK7IsJcK2%g8E;T6cfZ?cHe!si3f!M4><`Pv|Y-I z*zOQ|z-2Lb$2;Cp3}KeVYsDh{xEhCmhY&(4E=i2;hBv%XRd6#GanauM<~P5&!bluA z$UwQH&AS&N%SGT6A8)PR<1;0_S%V-7Eq00ImCca(+*Kzh(&xqMFp`k_cVEiFceFkftFWu=OR+P52>s+tqK(DiJTD1 zDq)L&4W*kOoZE1z+in>(Q+s#Ot`fA@EvP-~+cQIf4)xCkMGu#sv&hyX=- z+ika9kI*L-fegWAxpR=aco_Kn#b)!21q@ z;Vd}FDo24ert`h;eYe7^{148*^E;29n-7t9NBHb5S@r=T$Dn!8z{y#ORn#639-Eiw zHmkgNh&&_~+`f`;$1QrRmZNGG0nV*L%CzAIeL{|Kw9lDzAl#o#D7feRe-JRGyXl;lS~ z@==p8Rk<-jzlN31c%$K(ci1DslB8nqKoilNFf_2B(6EN1nUo6e^1QWUEO2>P3Vy68 zhxmMz!sG>dxBuaubIXE{@V7j!o0kHr>~q45rzvjc%c4BYX$|u{?65T-n>##aGgpRxyGUf1#kDNzS7Gc^9s_ z>f7sapyjyv46}{m*5hwN8Iw!WszB~IF&csw`b-Jq(T$=s>m0!yLM0Ee@56sNgeiX= z<%V*HM}lJv4WcwY@{tc$P9dR=(1DKYr;270ROIuS7v2IU=z{MOju%6dB7JZ6?C=>f01EskcADlk-xz82fvF~uexpKamH+RPhS0&u{#Yq}p*{=49az#jr z;i@TR`;_5HsBtQkdUu3NvWDVgLaF7h+Xn_9V>KMTc^OvFgea7OF}gX-BWz8bZ@JN) zN9eaEGJ)p^z_W63diV)76cQR76$RuXhrrJ!pfxWjc#xY2^}#`Og~1mddj<}gORGZo z*y0J!Qwk#Ow%e{HG%`xyXVNto%#9mi7oMctyvQ2LpZ=WWG<*w>4qXx+24}zrjbS8m zwhuXE;~cjb8oZy9)qC7hJiV~CB;gYTB?66u-z=Z^n+P+M zC<*~!2C>B4QV?Q^rRYEcYfFRTgexFq4wf($n}Oj_4BKaSsozPeb=X+PFg@W|1Rmev z0+;Uvu}*Q~A)0w5EmgLN~ObK_&6r=9kpi3@i;X>!LBLWNZI;R=-7 z6nVh>2-Mzf%@jI>!@(Lm^yZXs0PBwR#rW`uvbN)nJCrpgu5t5r;8;Med)@04VHci( z5eRhwSBKpp7S`ZCyn#y&5WzjAu;*EjQc4|zNiw=n8{>ZX!ylf682JqbO1HxUuwdbX zKYi}VqD>q_%zIB;`ki5v1T?tJ?XKrb2npsvkQjzawr1M5C<|8*=pl{w9XYze<~6RQ^nYf?fI9!^re$h?dIlu3-^W({a(fEkdPZnl5_8DqbU@s z4}IuE^*(gYo?xtK3F8UH$32Dt!U}2(g7W;-F^G*>I;<=;T*-r*0J@|$p@te{P zK;Z`79&2^>S(RB#6ZY=x!xJ<@bO56pB_52?2RO(GH|*aut%-Kdi+v!tCfb12cBt@< zS*YPY7&0cBGlt!JSiy;+(xM~IELs<@EpLf^2YWP~6~1pr0q^X$H8}_9LJIRxc4Fz} zMKEtdSFb2d3n4c@^K5;vK2>3d@Ql}n!sa~v;0NEYz171=5{ zJ0%GnpsW)h37U$NfW7yUvz$?LvhRvf;r;fZ59P&A@lEH^-Z2bOZl+b0Br`F{Q&`N` zc#ST7pdwlDo0Y1PyKGcdGO`F>3qSqfVJ#%=mXn@l=pZpg21NlyG~Ou-`F!iSd-sPcfIn>Fo7w7Zea84_|rZw`y#B%~=%{#z2!CX~I0E z#k(1DzWwdLtNECB=m0(!!>FhdcxKPxzQS37ld;>Lo;vYNCJLh&dv9K$`eZSG&kL0V z13b=n41V5+{*#N6cW(@yUSW-wUV2H<2y_YFFnTjwxu57V_|S(nqZRgU-MasOBKMF( zMMK4lK0I^II^Cqlefmqh$nZBj4D2cTl=IM1?@%S0jsU)l9f<~*w&$%t)cuRshAzGK zwXdDv z96FvnmLRY(uHP&@O>x_?l#zTtmDn6!p)d}9Eac$iS-7KAJmH&%kkIp`FMV->OT0Ec zF3qxzVoVrwj0?Pezw-D^`lS+QDD0(dm#vap1* z2nv-5af#xVu%VuLMscHn@WLcyWG(Z6Ghy^==~Xo=$E|PnjIpx(_syXbUc`&Wz`#P) zE2SyuLCC?hvq4#%<#Bl+@76R_&@}KG0n%{p^Yt9@cz{=D0Aj%Hg=ycHLn3@V^6{JE@BF|e zLcgepJPT$+&&yiy+}Mnd+4C{R9_F6t2>;6+GUo^}L!%9)$GEE6X74gz@Pkv0KHhd! zzA?k1J%>wKqq(KTcIKccig!oIoHpN_V@5JKiU#48QS{BxeuD!qk^ht1eVf~~a_aWl z-k?D_hxk--+HyJ1;YVn(uwnuqp4%H8lIv!j;Fx)~LKSU4oi+1eI0%h!AAj9-*Ii0+ z^u1YCET=_BfW37lA9mKBgB>1820-u7CB~$LYl|$fmOdYypa?eLMOlZt)&q{-n_R}w zP3v$E?dp|GG={R{bI+LTSX-DV6!BWg85dauzUFJ4i5!{L$1Os$^QgcAPZL92&b~+^ zYk|M!PIJ;XQqGdt|#hPJ2Y8dyH+QH=(R!U?YUuFp6V+$U5s zz{ap+@6ZZ(3BSRCOgXInJYBK5O(~GWqEP-0o%AkgBWdk{exj)_Dan$K_!Xj#diyYI1S4Y(<8LJlYy6gNdb2x2Vb z1bMTqDp?{&*J%^AsM+BP-=R1&gu{2L4aEVK{(!SZ6Dz{>Tln@V71|>7dPGhAD9j z{>fYOeU=T%I@qwqbB`hZ~A1qVs!2RUY z#pA~7!ji3cL1M-iEnOZ#O8(MXgxYx?w-s+X2UH$AGCOriE%C))gjJoGMj#=xQ9&lrUpj_xxNfGLy& zNBK>>SZk>WI>e`xFi%D2A^cWgxMvlHX+5HL+XxP0_!rouuT<6<_z!z?CREThEb10G z^ai16?UmxSnnsuUD2=gkS{U1{$}r1o)r95Su3A^-xpM8kk#g4OefEld;02E0F>5XT zJp1#O=!~qV;p}SoCLA6N@K7E|3W>jkyv}OZGS+jor@xtBKcAeL(AQxIZg@(BhS~95c!zj`{F3qd7 zo;i(06-0(Grzna&98yg_^lq`r;Q=0Nl_JTquUpsT3DNxtP+# zLc31^XrT}LlmbPe;-z}UD_&mVjFcI~J4ut=#eP^6=M^VO2qr~_66tfEr~mkme=9|a zkV`A(iQ>*oNCEF(->mcPZ-0A*3W`aknN#vu1}HNG<5U9r{og;hyk+|2aEtRu2?e0w zs@$hK66Mbtg-fQgj?cK6g-n^J+!U}n;)ug*UX)=94nbg^#|=ynOWsZMWsOOJ2ZYqP z!Vq|2%nyZ=;WW~J)j^Vj{$zx;pY`nIn^WraTxMm-A_LUQCRQ4r+3iDRDDi!DeA z#`cq<6MXsckAGOt@{kG-vLF73S3I07ViZzvPJDU`EopJz6w_9E{g2AK%gbg?@*jjk zEz+wj1ueiGQHn*_T8+ipM!A&d1J13$!W}kvT@NaJN~?*@5lTa#8Af=y!AJ-L*ZEaf zeRmZRcLuZPV352}Ii#$$ly(A;P=Q7J55+pp!O#}m@t7r=Jk_T%o-nOwd$1*?M?-dxny1Zu^euwwWJGcEB7J=`k z;>)I-sYRZRvNC4;8e7ZQ_+xV&o7Y>3lZoOzTa?F5!^3H3c@{3sGor4A@6N)twVaz- z&!tFCZ>X6@1A1P(8)L)59=F@CSKJ=HZpQ~Lg>hjEBShUV-6TE8mjG z;+nAEKkI$Fx@gswyjroJ9m{!;Vrjn!>sr)!EMyxkfX_o5m;bjq9bt(}^Z3d%Z}qI_ z)>fS4_Umr7|0CAzc;^GxUCZXg&FycBT->e+&+-CFT?=o!Wg$F8rxn^*2~EmmD0F=s zEe1hBadDpyEl}PiH*8*5OYeRiHW@W<65u%4{Tx~O$f?LGsk^53Uf>QhlCmoamn9n zA+~A0KIRedx%tBHJ|wHhw=G$rG4IU2c}J4c`<$ojd4Co&FYtno@OZ64kaf;$)VsA5 zw}ctO!C~mkyfcsru#5H-Tx2d=dffSIzwL(b?3F8F9Y1R()`!sy=QA|YtmHH9Ggnbs z8TU4;!Y-|GEHri4^K47(=gM04+$gkYt$UuZIW(fbeCB*EQhD-cec@AWp4)9S-=3cQ zq9_!1y3_s(wQpEUb<^Q~_b^O3`>ko{SzcQgXOhpQ#QuKlHVllEVsgNec9TPuN!w{EicZ&-aId@G!A86 z@-=LJyQOm67Tt?@=H>VaYg#0?wS{clp~5>{v&!nPRXFq8nC1X1hMNEYAOJ~3K~%Gr z+?Y*$UrUPrwKC?&?NzLW$7WLsX>5thJ9(qcg%#Fs^D)mp=Sd!sIVUlGk;eDN72Ob= z;l&U!F{G7}xVMxC242g@ZSei|!m-v^_coI-IKO#J7Qv;=X^i%#(fTz_Y0DX(Hs4Gm)?x2eASA!tUXL2 zl_3@LkteEfja*gpOJ%a*{D+GDB1V&ZmUa_DuD|o0?^ID7Z6;KrQgv75twasv-D8H8 z-cmelH8C_o%!5gqCd-Z0jzY<7xu*7o(vvW6W#;8UgT0c-PkPdmCrQ|2dtA|nt2DqJs8VjNx_vx!;2OvuCSKm^P#tLQDJRM%wx;$+59M*8Y^a$^@%Q4utwi`Q?!uFsCJ-GT$srKqK%B!4I z`}M&OesJBv2S2llRjDGJhOg6dl3Ux6?F+WrcF6Cgd}$o7SW&!o)~AP&f>q|yhb>Za z6RvHnmWQ%2jmhPm8WcbEsZXuYZaeSyuofyg%zGjPO)DFHO|<-{07}ANQmMu|wszh@?@ddNTc3B;hewU& z*=@=9Z%%GbpVKxkM{be%q;&XL4q6(3KmYm9uf8g+ZNa_^jk&q|*~-A~u`0CJz9ipo zksPCxjJ_tFk2Ig0R_LKGU%Rywx8xA{{lq6ep%kk$R8O%P0x|EF%B|n{#--KLL$5kL zP5PXqvHUMpN>z^YJqn4xmHj5v6Z-%7kN?Lc*R(IgJ*!BM?`rj-kWm_lEAFEjth_~SoDp@sN zuv5`gixNd>gc!C8dcRQ>ae2v9t);Am77Djil;Y3-{LiZ}MeAv|_oTAw@N$nb-Kx7j zs@9tF%&m&=F4bF6&qtrD255e~p9)mji?JNtH0!l*no_^=m9H$Xonj9>tqLDe#uS4( z>#Va%p&M3&F6@SS6!Mq_Io zdzNq#K}wjBrqJ312>%JQZ&e8&Si(mdOZV?xWKR9P9tMGnF*EL>c}x9T)B1p5L=XhC zvSG{v!J_}c4}PGkbI$8Ul>#NIkrH0bO?As**i`@j zFrO`L3iQ}eLf;q(L9=HXwqJVb*Ghm(wazj4`wdnf{pe|Pn{TIp_qfe1*0%0|Zs2~k>NbV`Ucju=QcC@nBrYIMihd#>|4 z|L@w^_KfEn_kDj3^!a!Mh6$UeGYro4{lv^x*Az~wOrHNqA*-n{_;x4Ji^lA&%x)Wb z4MP@rDcU#3NdP13Oek0kH>RKnc z8?$e1S9&h@(6E4j-pkbh4b|6T3g^Gcs?Dt)%e`@R-^2Jl?blc{@gX`ZLv@uc%bFjj zz9mZ(t0$a(Q&Whtp0?q-Zh?wa{N4quzYSk&pHUgK4p{!* zaeU>$+Dy$$kYbv9Xq`WTfHpO zfLd?%&DC@I6ItaCF!Rb7(UO5@=cg&MYV^91GyB%xxZ8~8#X+Au^cMBEvc>sjw?3dH z+QjmjJjNTc;L280ih5`cZO`yok4tE_ra5`7 z>z!`ThSRTbyJZ>t8?2V_S5Rt{s@4C10ra;8`N2Pbc`VdB`bfqFgn???xFpsKCv2E&?=Tdt@i2h2iPLmbqnxeuvLQ1mT4$mhRHd{=Z0Htx{Zbo zGCyo#V+l}aibo|j0R4+6qw?1qm+8$%xUwzEro<_W=V)$N2~1b*c_;!; zuGS)XMr7;ia}2Ph4^2!eBBX=T8aXuoz33~Uj}Y%oJZbp*p*eHc2TOE2jnLya)CX&Nsw_D;s||uBWp$&!+YBq-vMx?JoH4j55`jsNP+% zUS6eTDLLs(L-tBG3Yvir#6-T=t43~=f4$MG{J>@Nme)#6CdxVgyA8E_Jq`+z$?Tff zb4hKETPWOl{HR!?d8Wkyn6ld9Z~BZ5rNQ6%GIU~|ygo_4iBqVYezyy9j4K}=;Zk{H%6Ng3X59LJg-Me|YcY zksxTo@l<$;m?Veug`#)UC)=%KETMzhdff*S6aeXu zZMJm&Bi9MT!`z_W8dz>ovPmIlMc;r=AB#Hub7{&P(2dq*q*@JO zmJoR2hyPrSINj6fn_Fig7NMq=+qdKhzM%Qk1E6bZM-PF&b$kKxkA>HB0>>GQbEUhL zHXSowc{U=M+Z$3%F$3VA3bcd&*vReL7;&GnG=%#nn8%opbQmvzm-sjXL<<>i1kjY2 zjGC3%3_4ptU@EoLzh|?po>BI;KD|yjL?m0Ie%rbJR{km3OT{H!Uq24FgfCof%=mOCJ-CI{K_i$`5a< z?Lhy(Z>$YIXhUOGe9j+oj5Qc*K9!sv zNwZ#zKGRUv%C_jix{(KTOjXPtO{xEkzZKQy48W$sjbH^k2aWB->)m+O?IGq%h!Gxj zr2l!=J~OPJGTu^yUiJ-?O@+EP3k7Px=F=*=q@cVPrRHT7j4SfDG)MWI%8HT=iz7Ag zXV6!q%s<()+s;sL1oA(K>u9`~{VR;72RDIa$VIC0vR$_!Rf`oVnG?@wKa~JK^X`yf zt%W~YrK&sAjd_Q5UpH0#qP9T=-7c<}xpDs@w?R7MPxq_%8 zWK)oC#Jwr|f^00l{b|@@r?KAkbN?z+}ZuyTXWm%YQ~K3C}5lO3Ydy7wXZny5#9Gx02Y|8 zy7s0r%I(yA)?4Lv%V+;w=jUGuo5zbQBS}`?A4bu4V-3j$Nqc=iN@#6ez4hs5F(1mT zN9qjM{mARa3{`?y~v2UFoaR3yXGN_zP**II!e}}W;$P74} zP!%j@6dB}s$2!djVi5WNKb*HjY4FqVdKy_Q#|Ucbk@zm{Bg7m&H$6X3^m(%Rny?o{ zn}89UV7azm@j`rWOdbV4zeI_&yn z?LGI1i4@a$O?PfCFXWND{$} z2zzCG2|L2ta|$_&af0dPZP+%1y=y6mQsCti{j@gAf@FgCuW_1dp*-GCxR5TX{Cih7 zv!eXS%=g)tFJl{IRT}W`ume}Hc#n*rVG?;qZ3Szz$oRs+wJ}M@&Ly^hchPay!;Uw9 zhg@5?6;P%e_RGq1lrW8X&JCx(TV2-N*og-Coyg34r*}_=@zKnBzKHg<^!EC({}>oN z4L!o((RgufAFlk}NT+*fzf@y`8OUbYtAiM~f|O6^6n&TYN0CGbMrA$!m*etV4^rB2 z)(SmdE)^&WHoc3SMFg*(>{smKiGsJmP~*SHtd}j$$n;jD{QcJCv#qxzaPc^;xkr%Y zop>+Fl4-zimkvnghnmy1c76ku{4Jl`rR}kt4b5IEPqv#k`L6Hw?twz^p#&Kb!iMqH zvSWUYRKH&JkuooO6w8Cs!`1q1E@X@08({?yNsv@4i4t1b6!901nzuajj3Zx95=X>r z|6_YR?oU&7W=Z9IH+i?u!2BN@6Ht(6&-aT=As;S5`s>?^Nqi4RGe>MZEk`2tB~MJQ zs~w$Zs?`=lV^P}|i!g%;J_$mv{AqhqyQrGdo6YZomBY7S{=DOavRMZ4Ep&}wgS1Ia zOVN8)0e}DB8uUQ4$L0og?NMuY6hT*|G`l@}3Ogo6?rsS!eG$jHUmJ|1o8kIxl8O~c z8ZtG_uaQpQwV!tDl3Leg_hOga?uf!!2V99V2IgX1A&x+`V3g@39Br^My%l+#cJeks zl`Pnm;S_ei?@XtE${M(1BNCPPzaq=rT0X2&;2Js~XDtv<5tb4f`Nc>L493SpLBXFEPj29yS0{+J^g%M$Y-Bm!lY;W%ztat=_)1lfgSj7Wg^s}_J{ z%h|Tig}Uf#nUf^P@7&u{o`@n~M%-u7YqUw$gwj{p&($U*FMlqdi}0w`I~Yq;6H)n# z_5vsc-iTm-M_-AFdo)RsGTfJs?;!yW9LxWAckc#@5(IdvtnmqA6GdQOSz%!y7iO1B zf$rE0-5((Vyl%4EKxBAVWzaJsN$sD<2~1#eT>f7VG7m!EzC*0)kNDTo{w8YZvw~!5 z3`c7=#JK#3b}T#S8r`ygK)`5n#WK$`i#Ub&lf_JyBFY&vj2I6Vqv&i6_BJ3nTRiRn zPx*}Zc?QC=@!tO=m&wgOMDW_|DmXzkm-YR0@Cyu-Z|(1cU(6c#?D>rb<@qx8P6gm6 z)x)!v$5qC;&dkwpwoT!+zvKe{07JzS->HARP$oy6WP861f5R+}H$=Z4)lL|4#Ak#J zE(+o`C4&%9`c@&}tzjg{l&;X?tvYuQC)^ItMXpa?bK`kh!KX%f5Ciou6U~* zOMkz#LymHj5s?i9c5Q)e5H=gybP;;&faStvtTGSeKL`EhgL zYL~GN##l(e1CA)zmj4W%-@UeWElyf8aLcy<4TuxrV1r%32tT1c;cq5|VTxMbslRPz zV7_Ntv)!I#)xq>zG1qKxyW=?X->{xPwyrXwIQC$iTtiqO$FOfb-}8$H78F<$NmoRv z@8#>+zv{N~*D**LkN*O=>)i{8N8rG6-%SO+%^i!o1lxJf+DgRUqm^R~-owildE+_$ zL+SnqL%DE`LVh~CAj3(WhOpTK^i^H+Hf=R(4EiAx%Q5Xe(>K&XQ-q){I)4$oJO(^H zlOPu(f2#JZh1;lGp&4qIa}!mL=sH0Q@H;mL z3&ZReDCnui)+J3xErz+~zEUCi3sh8Y@D)>|<(EJ!C*37-1nNA07!z@1RLYy?x1KfP zLUfOFz@k@176ixCmfd6}=9!BtccXTuFU$g%>qdUwy@_9$Xjy17Cj(R*pHKWaxH4XgBDrqtr*&z`22)YzMAy9wEF#8j& zatN*!M&0!&1$}_1;7=vs%C-*bYF|e-AM@b{LLUWjY!6MA30rD@!#PO|_mNfKHCr-g zu*0YG?&tH;oM&$%wNKiszV<^6qa^I_fpZCbcx-oPR`o#EE3HA1R1%^pb;@3K6yEYKw%X}z%5-~if$<}^|W_$LjAqqa% zEe*F*{ZK97p#H9BtV3{8w{_BiKUsK3xc5bWRz=Lq(kx`g!_5h?O>ok@#1|JIOsVMX z(Ghxu3^fATFM9s;Xm_+N=SIXm$+iK2puR++op(Qmd?Y*39U@9VN3vD)WZ(ATq-W;u zj>aPGoyBINrs11989TT52}xRkf49Ey1btT%vs|7faO!g1?mJh!C!%P3Br4roce3!c zBq8vkE@|<*Y+g-!qnB^ODp$^Dt~c!h^hPcGA62yKYoc!#Y4nV&5Ed`0TfwBC&kW3l@hNQVu*d?414~96N?YQ`}Nn-|I8@5xdB_`=Bh&^7Smj|d(+bo-UUnI19 zIt^Y5=(BjSj=Kp2Y`I%tmC!FUn9t>{(VP@PTV8#bm#r*@E6_cA%J!*y)Gy$V=}Lux zgIwQ^y?)d}$4)XttU=knUNb;deR{qe=K{okQdzT2TGGoo>GRlGGGbAw~KGQT`KB&KZh9(PY5wMpNE&35OyPIxh z^{X5cg5=;X-Of|D2eDkFqUu`ZoT7MwK0@C+ud}P`M9GpHk3N&@05u``8;yZ^La3;v zMt7+HFjc|8TLD2$TpI#uI0KLc$n;NJgAb3F5GT`s7?G*M`;HO_S<_Rz{uPmUNl3#v zVI1oKFl$?YLs=rUy^di|-NWltg!;~GwQ4Evt%S(!JC75!XF@+XAo{H~Mcum9p zjkhNSZE$S@_S*TV6HU@|Cb0th_Z)2$iq6ss!;Z*xsZy;!EsAX7T+cL%2o^oxI!n%g zyG*fX7##Wq4owH3`%N=ZrDb7`w4>)CDGz$7Auz*&I+#C#1(K|S;Cow9HMGaiOfPbj zAmGl<-Qv{%ENwx^!kn+XYA!UF$$4NugwIHsqauS(Qu1s`$Y$+$>ogm%aJ_WQldG`RKy4XwHi>GD=Mz>o(3D!BPPO}CPb6%bDHEo(*?~@8u zUKF%kT$AQ(8l1^>(2AICFqn8Dr%9J`w18)jL@ zrGI*OsZ(WhFK3jrcV;uj<@%uVGX#AKHDa8ZWc2g0sJf>|%^GQj5IV&8X`J_5qD&-tb?~P&5AnWk}*=P?w0+pbo$HTx|X+I{TS7vD(1C`ra}1SjkJ8{=$Qc))j98 zb=-h^Ax@nrot0DwyLE(RHGWz&Pti@edB`119IEe-EDjAOU2Z7dfP~1Eg($=aFx-km z6k|}?GcCcw>z@!{<92ZH^rdhK{F1e)u5l~(6zCE^#_xSFewHqwQsvaqBZ++6I6c?M z62@6!Rf^eu<2Un6gQ>X`N9vynkngvqdIaJ3GE8J8-OQvP2yz3%$4E(hra$1;Ga-hlBpwJ?T9d z%k9^tFMgXuXXC95@qp57eO5Efr>B_WOeOWBOO zf1?<~?M*MEc!+9zTGzbtVpUf@8nnIz;ZU|eY~84)&*S`njIyiwjF5_yu_H`)3q3i9 z2Ap)LyOiA(FBEvogMYb6KFvIB8j3PG5ay^j?e2@vw&bNJ>y&JgMf0(3s(48P`+dC@ z<^ny=JVCY9zpgxZ0e}Q*3dOVkX#rTa@^*vnX*QpN)BPgnPBaAio)c)3I_8->?$6+^ z9c-3pvs#Z!^_`>#puLk)y;mPL=l}G_#aO@a&??}~&{o9MVi^;hT zN!)1`e;e0SMQYq>r5~LcT6x~sLbS(P7we3*{k>H=V=09M|3cx9~QQ>W%C8smZuo*55!9<9R8$@2zgT$6m4Wjw_L(md@R% z62?s96~forh`C$e(&X{>ialG)o&~(u6M}#C5nuN#P;mEEjZ7pS|Ny69lC0) zWEa?3K7|{C$l$P3NeY7bpJ^zKH|5;1@TPS-M>$+>bBN)8@_c*fx&>MWpf$DjE7I#$ zMcRoqWSdA!$ghf;L(AJ)!o}**{0#rapJxHNbYrYAV4}ZBZC;tdAPK-zFiPoy@3jh; zZqO?;jY{m|vhbR*zGEd6mx09{bIbtrRfBlu2Tc8Nbok>OrMCsOhTGt1=0&c_zxCXg ze_H-1{P|D;6kr`Ln3yAaeuRI@P$T_I5=Xc@zgdHHtT6q;QjB@{>kq}fZSmJ)pYdkx z2z!f7ZY)H|wn#cEI%H=ao~M~{l)y8BAItf4-R5uiv%TNY5Kw)X&*K_uBVVIe+Cril z*0`%NkyziranYN>`aMuzqkZe~dd*r1+XnBAm72irgg~4>muGW@M{XS5*7HejV_Ge4 z(bb>zl{~*?U0F-le>S z6ji;lL?r;6`zpSz4oA*7emaR!2b_&_S1R|u45lA-hN;X+dL5Zl<3E&S?Ql9ny}vv~ z_CVg+C<*_D_(2^`O&63rL^nA4V|jiv!$^oS&$fy6y05`)&NNg%ViI^NaeJ_kgVu%f zA5w8B=t=x9va;5tr>G8-zDdSNgjQGmg9lfSj*NV2e+6OJhD8!S-Mxei;Gd*xcW6X;0bkw|d z?F$Yrz&fGJ;K8h>!3NIPsL3$~jcKC^qE}K%L(rj07}0(g6$uDV8H`-I{&Y*2TVQxt z&`ext_#{#IkGcQ`EMfU;(Y=gw!}!Xnw}S40`rB1qkx*wPbRalppjQ`!$LP!2{U~FpUU@#Mv@Prq`YeN!UlQEYM(~to|jRYbkZfZ%-!@6dcvO9{~nKg-VA`e7W z%({8X2qstM`&uwN!RlKOBHD0OFV~!>cu{kpOPU!^>HBA@w|W-}&eDI3Zvk0UDCQ{3D<5d!sY6i9 zMsn?_&`dpl#x>=ci5X76V^Xl+X3c_MRP}y}*fp4=PsPMC1Kmw9r3pSeDL`xb!r&r-~mQpY(!snr=QS@ zqXXtNcyW^PQ4i_2mFA!$kLq5lk$73ewP8sHxsnD|Kk%v`{%GGn^z!(9$gRz-rJqX$ z?(J+~*H?q8%=B_x!1fi*X7HlNqc+XPkC_I7-Tu8xk1u|NdNVKB&3G(G8x=}h)O;Lu zl4b9jLj%}Xh9I@R= z10)q19Ecu-SOrEhE#*`5`lUYxjREYcYztSVwS99CY@QO+^!Lyl!*jv3`9ydc{3=c*0X28@_A#&#Xz;B_Y@w=iH z@qI&~&HUlL7`FK6lTzvA_X||*BAb;(!##j1PuB+HKS3>Pal_i6=CU!E0vr{LYSw}= zPOX9%lOjT|^8JPfrprbX80aS4|CB03e(KIB7V{Va*x8zw^;drrn2#|lSvt2M{g?>L zNRk?E|Jg|4Kz|}bd|>mMGkQ}mu_awXt{Ru(P7(#q+?Gt(%S+#*vLUPr2=_Ja z@wzb>6c6V{CJ{*fU1+5aw)j(JFgOoFBRhT}&gQJNL-dj^9lvMMMo4*$(-|%qWx<^2 zQ*fBNDR3)z88EDS+(#Az|MQWiNvGvI@9{O}#jNI!Ow)2IotA6o!PvZ)XAW4rj5n}u_S<}mP6Z)Q(cTmY^h1&o@xIBI;tR0(x_+>;pe7(A&G-*{|U3Nf66p9y7)Amq?5$jNBm=Si8U1b0mH0j6 z^5Osf%gUo_LyF3R`er^E=T#wfH%pqqK~nIKM{jK>>p0>&OypMmlJ~ z4fjy-eYJb~(E~{`2ns!Ns5EvJmNH&xg zXMYCHTEsqzIS&JTYG?`wtD>u=r`Dx$xla8%^cBukoj!+u^R^My>CNEG4E&Ulj^T)3 z1ddL=bZ16BF4r@fUu5$A>2P*8jYF0=xIXA*Hn$QQHsj*rU&8g-UIM09Zf0oIXYtol zDgNQ0mwrs~w&kU{N1oo~4lXu%1^%hZLpzCHa1V8ne4oLnOA)XG8^7tol0gWinJeo! zWXx~(@57;LPrnFUk5o#POf(Au){w&J9e-Rc?H9yJG;*~$$LKmnj|0s4`F4D}`5~N} zGnXKks?CXldJ`Y7l@h|RbvMBqz;(=gt#tCLcA_jK?ATYYi`?_3rXfi!|LjNK9IPm1 z43mo)#j6_M?$b0`;oA2Nx`C#jBmNK)xhF(L8{hGDkLePJDBSOizZ8UBmcK{KJNg3P zZ4hK|D%@3WH*S0JA&`{id~CuU_3!j|zwda)thAcX;v)r`b5}Zn5;sTB0>z=BF5-SFdF~>Z#ms(iR98X6BzN>6U)0-_X52d~s z+T3u#fx2?@H*R(muaQQA-yX^Z5)kc5f^e@8@N=S-{hq^scuEi+)sf=pT=T_p0*~CI z5Y=&i4~LOUDUvUKAw9Z>6X0oO3U02f8DqqVD$}uL!HGO-+lB@HX24OR^>!v2JK_e( z!Tibmit!yj3*~g+HC?vND)27TUj}Io5I*JM{?(d)2Drs;M0e^9l!`g7r=0en4k&&D zB27$sh?bGA^j~mR2vLzEOPLhKp)t$MqtI6uuA~?ArDlZGT@##`WN+GI9rgp!WZZM! zydd9$vcTZ+LFi?seCDNxY;wyO5d~<~)BmR%fA|G=Yv;@tI1nPHQcGPv)u)QV+#7)J zk`#J}s``15+kRrxh57J( zh{^^T(@60P|0Uh4cZQ~hx=xD;)!s?nCWOjJ2s+xH=7CyyI5S=YTaCW>tP3ZxorY#g zLNivF3pc1J_SA%YNctgU%FSfrKf^{hpHO~-MFaG`4_k7KQ;ProN zAI!$CdIu11#(oXu-@cctE;!l)C%Dr!Z2QCAnLr+b7KG-W@tp&_D!N~T zIWnV~0G;qpWjQAgMx3MbA;vA>oGH5Zw6OSC1L7(MNvjZ7-};y@ayS19S^n`8v8rHB zzFfKdyFn8Zt=q%n$d|e4-WT@zFts{x<<_<_WQa=@Vd;GD#QzRWwzb>2|H#|%6Rjhm zA9wH_0vDQe&}K2hSOEU+AhnNm-3F{np)Lm!M-Gw=iIf8i^@+i>b*q6sZ zDc0)5h&GeCn!&iml$lrYo8jtPcuH3>4*N3m;UNR6tj|DwGI?oVwKFe1QS|Q835M8J zmx~gwTH@WKoy)B-j=!O%-QFEcL_OcvtnCz>zkD8mih#nhSXA{!*bG&nY0;YWo6B-9 z@U`>2^RCf@2Vue2IQ6et{MaqOQHYEtP!P_x{_jY>eoLO@A`_cq4gGgM1lT-l#IMkHd9Gdf*WWbl zo9*>KzvvtPrz2tP8mmwIu|-Uqt60|itHc7+7Zh_`EOfnE(nCn61sFw)O1y|QRD)O^ zR+ih3>q+PiTPAa&|McIyb+Q*#i&^Euj($(QZcR;^{jH@}K!3IOHJ_%^%_LdnE?+^^ z_XB3ucN5cl*JwaxXqAm%x&vEtk0{s;44)g7~Yu+mo9)i=&@plXEo~*KvSU z#vD26a(acUTQ+Sd^#WS*{h?wlYI4OJ`Fq&fwy(ew=I?apSTTfy`ceOdJoK_PK*Lp! z61!C<fD6?EKL%7Wkcjf&R zc!G|FGbU)IrfulAMbOaUj609QA z<3+^MsexC)57*nKF5J%uKVZ8v2fw`<*%vL&;bbm@%=7}Q%qiPo>$Kr)hl)2mv+Ti!oWe1H8JT~Rnc7*J0>Dfx^3kRDI_RnI={1$lVo zxZC8)aQ#f%lu%%8gwMD1KLUsn2hMo8J_-r6&CYz^j zAl>Zt$}RgGQ;X0H|3>x(H-43HmC16!v66#IHCf43;eN5nE`L`-@Fi;3~$Y=(pm) zRH?-7Y9dLVRP?U_RjU@Nlh~yNegmPc;Sbe7(w$)>V#&60z&H|qarF|Z9Am0pxhqud zy5RK<4ONo&G}gR7pp-i6lq@~f3Qt$UojnlOFFNOKaLU^5tH)MR$yG424;RDhxL{O$ zx_=SJgfSCDDbX{a=6a+EBOVWz=9%{M{ybG0%8s-7pGEETKN?bmpmB`*~p zl}fntq`}}B0XMM3B}Kf8S&#e&*ktu7TBb8uj^3sPZ}R(&5zJp?JCOEa57_z?jr6Y5 zs($Ls<+>AAU_nHRU7=x?B{Mq83b*^6H4eCjS5yu(sEAY5e;iflUXMUZ|1YbPcfJ~Z zyllFPWctlS_u>a3M}971RAG*AMt#_$H5aRnC3Vwgf~0r;^%y7IuS0=p{KJeoAVc3Z z7;4Y)W2Svvu^La%>zQ(fipq|{!&P&Y-O67={apP%=QyU4{=h8C`ruK0Rto`Q%IIAF zp+?lX+|;9PYm?X5ofSHmkH=07>Xvw#l6O~5P1qYzMH2jlH(Db+8&HIY)|*W7^juY$ zFHKoX$633Cs_{4|ueqX+8qTacrOHdIcCWAZ>sEq>>~0<nVbSM%g;a@I*E%8P@er;h9GVIxap3U@%4R!Ux~zn>lS6#Cj-A^&N?=3{zc( zyw^+@rfKFcNRGueZ&HojDUHQ|s*Jb;v7Mc|bVjE(SO})@e0q23e~&wGWrX+t*P(W3TeA7?F+-cMz$f<-jKh z{=$7|UoS^k-ObHkz7{==88-a&JS|GVY@gX>gwQ8pO@`P~Ie(PShhn>$(8@8QSvVrf z;0HN@vUrRIgYk3aa=dRbt-X;^J3rdw4YE?XmW50+0T?uq9QHq?UOuBy;lSq6A}10> zjORS`KZ56rbHLb4X7A0cN7#TC!9o2Co0<4TF6o)FCdiMLi9aZQZK(q)pz4nH9rRf( zZ^f`23j{7wc<6=11#jcRtcY+(L@evcMb}Hapi68s9GD6!*oX9DPlp^_mDXSW^Xr6; zP|)M&ZK_1?ezCua>bY1a9IdalzeETBbzpP&Q6_Uj<{&RgzntUeX%FBh zkpSJsSxv_yvV$rvJ1!NXw8!3Pt0*}*0De{R2?)6!Qk?POQ#=!=hRU)w_r18t1^bDS zqKfV7t3ssAMfS4H`RrTn_wn0K(bz_Q8W zU7POpUaA-IKKdG{$rk*M-?Z;9I@vG2g5tFpKyFxTKcUgb%gpT1F-hSA=j+y(W&RF~ z2W*vyaLMC)RA?u*VILmIKh8|fe`gpSrldrpXqnf(dcc(6 ziA;fm&`yyR!SJZhT{p|XakNGW7A1S_A|e*!Rek@fTAP7=E}V^r{DB}+ybP`XK8;Ri z))jlw*U{K|8gv=wMKXolVE(IclaRQI+kfk z7t?avDH@vBxo5T`wZzOCt43;djf^{2=1wIyeVwEM_qe_(udw(9yK^%cC4I0Hy;`Ym2`nM{o5h zInQexO0BUdlVlGHWjt1lcVO~||NI1Lz$A8x!iVw4>!h1ND-}2Ta^{E`-pzD%Zhl80 z&KcgPwmI@d8Q0J5Qdw0BoU2bCE4G*AB7HJPBB%D)IhIHTHhE2n-}g?yLTha#wA&WTMMar;Ln+W$Q0Q7U$y+ zXFasWMn2xB0sBnBjb$w6F;_ga9~{23AWK8QkJ;@{@qR`|g~+D6T%>KMdq|Qal`xP! z{}F{Qd3f+CkHn;|m`WA`kieR5Acr8TI>cqlqNIRwf~6$ua3KFRcy@i?}hXN_Qu- z#CoCmSYvBDMT@3{GG%0UAIYqaBpPI z5eCN)K$=$0(49IiTz~9$B%7|QrgXn{p;QeYpQMt&2qz!4 z7gH@m5A*V>a6ZpR z_A^-!ANT0bS6rrBbx)sYD`d>Uo}?kej^whJyIZ*VMvi&MNg9r`nELE7<~sy@6_=S| zjcCDvZ9--UN8jH?Cm~QgNH((P{Hg8xAiR#Jv%`L)w_p{1&#R^%kI;*a(I&C|SHpr@ z$LFM|CUed>INlQSb32~@`kKNRrIP@wEUUj38IYL>#T4yT6H2ohA4yd%Jh|Ng+FZEy#E`h8eW$B7EbSUgsb7;N-sRM z*A!JhmWm1ol$5IfUaCyhYLK9iMrYIaOZE}pK5N<@W4{XLDWX`g_gbB!&}6Qwbf{mM z!ECPXXYPtd_V_I$;YMAP;IZPM{ zaprRtDZeQH!)J!zY6d%H(IXMa=LD|RsY?@E+gYh3>#`QWle&TDgb{)c)Wd^lhf9x2 z*sqvdp&5aXHJ_D0o_SZlc(wS#T%KxT7!qiHQlT$j$;7O+`u4rvI?CRFTTB>p=$q|% zCCOmlPyMQVY=)IwmLDfklrB-mX-YpC8gg3gI1#;k2gXmQ?@)E}z|R5v)Fdcc zx(Q*7?nDnoL<%P4s*Y24Oa^*>Tcp+aoX{lzWr{oE)d#gCC~@bJNigRU4#%ipivK-nh*?g1ToV$ z0*=0iiRa`~ORaaq8l5}VmyUKyoVBS`E=1PcJHf2&r~fJR#t4y^%sFhfti&sAtCD1D zi>F)SXQTj@8+}0F5f&n;--Acrd%GJ4@_Yt|6#Cq69Y^O&96Aie>d&_op?G#=topfR z-t`D~PANfJS*npLgHwK&&NS(B`WORRWDMK|{;{sy(V~xMsfFGFAG>aXlAUh?#*<%Y z?1~rW3Yj&AofJzb=J*crr+DvCYZ}Zj>hAP>SdtVKqlt)Py{_>dqdi&7nwBriluDvu zKB{VOG(!S?b*kcj%+p!X3yP__Y#6e8OTm|`6O?Cgw-e%J7=~Mf%J5jPpr)ILxA1{| zemQc?3Eb}(ytbMuaDXxG9m>5M?`)c3mBtlx&@2G@8nJJ4I%WM+GT?f1Md;?`Ag2_< z3Cv>ES#j`$-VNW5SYp+s`U;0E9TIxGXr4~qT@*Icq-cIyC6F#goR;teI#X>ESW_9c z_Y)gl^yyjU47ZT~j1{F8s>+C(p%8i-(Kulf_ta{HDVzCk_VU@AUd^tdpddD3hxeBX z0iZZ zV7c-2H!SwANiG&`CQRN9Wlc$vj)!i`uUK-#jfpJj#D!gdMdKz#S#{;Y`@TwUlC>ZA zgpu1gyvP^hv6DPQbKUvJ((WT}LvEEQNGszC({^Z{h4aSk#~vfva#=vXyr~aNUsRi> zEjd2ty~x>Dh$KeQI-Y9Vo)n%-?HZ@dNPX;Z*f>(Hh{p=&FoP0wxE;cs!1T*un#oLj z?cPPE`|b*uSav8)s)6R<#3*QlXF}1>SsQxSBkiCR@%fc2{_CVKX~ZcPPdZjEpT83D zntk4T5XM_`(eg2zR+40poq1DO{8~uzvp^ivmg*$cGSugXO9NKRD@$zVCfe+5o5=Bu zeqmzjeiZ`&DwXGatOku2sA&-h8Y|*7z?5fy1oNB?1kP?TkfeC z;G1&jk&>3a5r+F#gk>;eB+$8Au@2bHz*!vdns~-xwsH7wG~H-e#FJFI0^4Jw#*LLu zi?rtCc8a&B=xK7>R@_k}7seZOsxI^M1c;Ql=6HlQu)3m49p6t$hqNHduF5brK;=1K z1hux>7j^_E%^oa}zyq7=dtpoOdO9Zaa`^lat-V>Y7lB5=>*LJ1ar6RdorX%}_uyQd zL#ADxpzMre-%oM=?O!XYQgyePmI9IxTSH78xpZIWu$ZLYKM&u*hB6}UXKw1h38bL{ zY9<4?8e@za?EiVC47)ijdQ4Fq(8xvrB6oS67K8Q6)43ll)}7aseBfcEQPp|2b=DHV6Tag9_Tx09z9+S#>_zzm_Dy z)sdf5CIFQE z?TX~E+;dU)PDGVbDt56dQthBQWwU8h0J5?-qw@>7R7XXh!&ECZBz{p0!23HoR&mC& z_th&s3gf$@Z`Qcup;$~-9O6BESk7AyCO{V5 zuI5KiTh;TdIwM)&87Iid9-%r~->v-zI#OydFT2ffXL<{bchrrlZ`vp!%A=9k4&GsD zqqBJn^7*OTTfIuf+G9ZXe*jEDv%a{)Q9?2$Gqg=)gq*}wTZ|!w=OX8Lby2cA)ETCD zp&?^)$ho$T?Mu zY;YDStl-N)7LTxdWH?@VyikNg_Q@=FWp-E(s8z|}oC zOje@|1P`M;^OXA@rKk5y?!EV|OBuqqf=h|m=tG@{sR~*Rp!;CtcdJXV_Xb?Q-G)e) z_ZJ>XbLn$&Tln=u%c#mwz{9#oKT0{3&N6ugefJzgLhc)bBKV^p{jd~RIOx4_9UYIM zBInWmfvwM-ak%2Vkk_2;@TFGQ;J&rDp+}1-R*iT5*N%5Sa@D>VtM9KkuZQvSy1GLp zyBs%`3V9DH_&{-@^@q{8hmj#Ri9IK5BhC&aq$7YMI)v?(V7>dqO)Pd^I8;JxyoaD1 z3pd1(&%~O*gVDSxhfa!OwCZVR7U7!~uGbeQF>f9=^GQzL&2H9|&lkV=C0)o$uY9&7 zSLF~{AjWOb6yeFxEH+1881Jyu=t7uvuZ z2VM>o;f=sy?Z(A)(y-Ya> znBtakDS`x6#*B>1^Ga~y-LzLeCsZMtLh(|bo5D;P1tT6_pYynRr;s+v1i^^n#ye&& zDYXO)-djuwjEqGo6fR{>@wgGF((E_h(0DD(G4rMTVz7M?mCb1f5bq8p(w+_*wWm6w zGu9W<$vfV_q^VYDFiaDfw?jJ z2Idhg(&uk%PSZkglV{cUl9OGX6eyn1>+YZoP*Ky$de+f4B~386BmRuhsi!4C}Ji2y^KR zHN4VekH;Qu@QgiQDdM$X@q<2ZtqJ_QP6~lAf?7xL1#RqM+@CA3UcGO(nZRLIVWqyW zTRd`b4Sb!cgtzwn(#FP#vVtC=nGAYSjN>&+A4hY_-~G9>?$E2TceL|*^N9z08ZGMQ znH(PP0*{0}`)=SC_`*>}*5p5tfyf^U_28itCW`GmyvbhL|9D3FO3`g!ZeH_(7YX$< zZoj|5b@Z#Va%F-e$Sih7J0i*vuVv)F0EGlo5g;gR{8Q$OFn zf1i8K8|7FFyA6_xCt?)NU-p;B=RoozWZ)vIfv{lL1K5~ zt%4ll&SQ=7YzvD#yBfa669UdK4lJ31MS%@b^lLb%gbz<a{o^11uoN|G5TZa?W>phfD%>{6t|SN25*W5%b54J5W{!Yx`dqm`@jEdS*P6NA!T`f-~(G; zitkW}?Ez0__8krj>yjHN%q)q>JekI!FthSeG~pwhpa@X_;l@}PNrZAZKq=(8YZWv1 zD=!ut!BkmcS^I>*37=x^N^?&Id0zCQL+X6+Bq$E?z3+XeswDDu@ZQ0zuYUEy%6*|A z8qb=P(r3x#kzz<--Sj)*OmdW3squ$Ra5Ns36ii7^CWaXAxBr`~xb=dJ_x5`~Y`>6s zjkV0kvttd!-AjM6VI%fM#~m{7McN{)wSoDpwJy?LVyvad>NXPlPiVLC(jFw?n`lk1C}v$_>lx0u zhwZF+ExMNQ`7!)OGsbW<3Ll!!bI5Co*7AI$x$~kuRfn{pdGuGqq8FGq-rtqavW~Gc zwN^ShHm?>=y;{k{uczVoknRk}ZLO5{AKmX>M(A<74-tn;&AW8F0sQu#X;7O*&lZ8h z*g4-6x-_KwWI1x6JlSD;t0CX&+XT(R;W0k52yRZ}ol8aS=h5RvaeKnLYf-d#vA*$* zuUFM53IvNhWQw(grvnpY>G%8m^UtYXI6@k^btwoDhzaj06Dw3faRp_B#sBjTX^NTz zc>-teG8QT+Jc5u(5R`D~f2DB=+6XJ*ytfPv1!|0>Ap>?GvYk?(sSitXo**_NAnN z0cD8S!#pv53F@uc>=Bcav*yYDE(Z)eco7qKFRTarBu(@1r2MkygrQiAF@<3g%v-yK z7T&<~LE$~?tk0Lng)qSC!sDj894{8-SNOxP|N5^L421Kv{I^{v9s%#9bfo01@Qs#~ z{)JMCC=g+;z9Y1O(%I+8w6ecXtu>f0uN=5hLT8mSPtO=0reRs+J`YZq1O zE!76%>RL+_Q9M^zzet>U;m5xyS3F_D(3`CGm#grboP*yoNc6c+OI(`0rqp*>^2Ft} zrE}bNIN(X^u9fhaBr>LIP%oh8^CUgyJ8>CD=*uA#5|VyJ`F_Sv^TWgf4=o@GOKG_s zkEqWT2B74ygt25y3lHj(&&RCdQ4ad>t*jv-FDvtHYaI%uiT}^{h7CgVdB4s)6F3fG zoU+0F{dmM$bEURuJV;;3W#N`)NC>ZYBn8$6}UWD$Yztp0*9WT%{9O%z$ zf5HFcFU|_JT_g-^h@buX$NF7uN%*eSdmF)j8h+*s^m{e*IBp5Sc4hBYpS9t69iGL0 zZ+OPg#)N#wV-#=QaNPdvO~cXQp7(1Wo6m6EdF$HWyzu z6_++=yw&i%<6QbN>pb@Vx4qhbX7t6DTFc6N*G@kc^%QUEahKOt_PE`7z2ep*THm*3 zNF>It+#3_HdW+8R8h)=Q=n+ULdcs_Ii+C=C9X|j0&z~q*vxJ{%hh`d+Uv$31gE?*f z)B696!8oq;;g}9eN*W8POohYYxMKqB@F31w%QVJ2eZKQUy%uR)J!^la&9~3LSY+Od z?#&RF7p6+5cV8@KR+;`jM`m8Diyo%- z4D7R4)6UH-9x*KkY8vkJb4Y$~-;h0X+ME^()AINjgXArN?-18EM~SjG&O}-{jOB_6 zyWdhuTk=W0&wBh$o?%*LIOpwtyYj63LlHGS9-s$F;Q;%dKBOOM_PwWfp-aKh-T;_B zc4;}$_O+jHYo9RBU>IXN+zwrda@FTEnU6IObE48*Jt^dI^wG+1Fd7LJnu9e;`(tE9^OS6pBt8)#PJ>9M` z?EtRHi(*Am;Yp<>`C$=PK6;Scec@ymUC)cIg@f7Q}C!Y9Q|C~6A~;pP&jg5Y$XlcCC{gAN3SsXu5ekU zu#@yJgj^V%d|2ZeUmo!+qf-kPze{;ktwVtXVdZ^O>Q=dLj|xv0!kq#OV+9-f^4Yy$ zmU~;TvYPBafU^q?=Zx zW1bS3?}DS8A~>YNqO-~{nzOhmUV}b@MI}xJ&s1j=5-wys=P^Q}&&P6AhcKKa9Iu4> z{nrYE*FHjcxwL?@&px|C_bDjyp25&PXA6A-b1+t=PXp@|y^-53EyG!que@@OKV4_j zxY8|BL`ZQq;|aA_&@D=X^bR;BXWpKBm)vz@%IOlWZd@=D@(%Y@YfX`~S@6{s z`QTMCkb)t4qK1IIlirX5Gh?3YMd#ZqQi=Ep3{&6+tnJf~-u3juJ$y&{PH!;Hcl$Xd zRpzk64y`cnq}z;*3#U{L#y5L|>9CN|EJw_y@`0t|HWn(mL2>JmZS2q`45;r7v{quC zXBQC|`c21t9gbnu!$reDHf7G&q&xx#WnS3c^7_xEyv5r4v&M&c9yiQ_pn_RqGOEtW z+e}LUf)D{mp&_}L+B?WK6jBPu38t#83Wt{G$J_1LrgoH~uplP7n3mceln%(z}r=wuA8v9OPfvpcET`Bx=$B6(ryqA!nK1_7%N+|DI zl*NQR%g-e!D-=N>mTRqA@r`f%UrH#W)G6jek?wPJn@8fdm4i*N?Hh29@v}rS$m3D6 zTR5`4Ui6IRJNhU&2Wdp^Z$h6UOq3M)%0k`=LMaZ^k8z#rT&I+Kb1)YCWW11<%6O^u zh$xJ)!ac?$@Q-=ThQee#*P=NXN}MfcKv5(`oRSwDkHVt+7JjXj3?)XdMwOWr$O2DB zr-btJSWu8-U>O#EYWTbBguV>JorilTr&ykrK53U+a&Z~A6y1u_j`rN+9`~&LckOlL zKl%(j<$3?xzx`{SJ^P}Eq#raw3lO=Dcfb3uR8KZ^%l;^S2G-~iWswnqVF8YMw|z$6 z>>J}stHOQrQV1!v_5j@Fsek1w7gXOq^htY;X-ZV!OG$kmjtOen84qpSLlq00)jF$~O7+@eq^T8BQu73==&XHPFfSgJ>R4_GRA7y8o6 zk>)<6JuZ09ut90{cVBHdMh42SXNMllF}mcQeb;wRodxq%*o)%rH=03-f6QZkyXa?Y zR=)cxxzl^>m;IFU7=Fj7V$bvfcBU1)>(66PgUvT|Y2Nv1bbZ^R>+nx?)3no4jg+$d z>}Nl_DrTqOuYBIVlCB2m6zWuY?Nf(ZTav~XQe|DGc=ae$*k;@i{@EL01AFa=oEyf1 zJ`E}3hTrtGr}xmJO9{E1<>g!|Zi{-{x=_iKB}K>py8qmv^ttk<+|G+C5)lYg4Qgd% zx2r=kD`_)_+yxO5MgRd8(b)TY-bKhV=S3?-T@#hJrP8*%Ha8sQXQ8m3dI-*)ff!VhT$;8}w z6k5BAT_+{R(*PU;CydNz4CrX7JsrCpu`FzdtWz?A^2v9R*m z1ZSQG-@&M@i_oD8Fy%MOYwN+dbL~+p>3xe0rQB~m33pXtwZE70>M5t4&-;6xC5+k! zf47zh`))9#O{e3@kEWOs5S0s0+Y7iP=h^;J5L8Z8>`2Apc-8zSuqng@=0htm97^kg z@U_f0xugpFB==`gg9-r=?h(QjAtF4o;HL*F!IW^T-H0|M_QZ4cfWU6PKJS&876Q0K zDGWR$DVWrU@b0_sepQKAMPo`u;MZ3I^!+H5V8z>(Gwc1ytF>FAYP5HcI;SI$@;U_f4e2m3g&Oo3dG9_6b&98m!;%W!robbTkcfv)`&k z^W?x$^Fx9!&SYyZ)B3V0 z$m4lxNeh@#Dm{*A2!ecONZVisw;Vk%Ai*u&E%=zb^R|>33 z+29-H4ZJAQj4h(5C_`{Am7OV*3|sCg4i>tW{bR(Ubm0$Kqj?SKlCx}Yc@-5}Njn5{ zbS@bbD2Mi2VX`)-gG06A66lprL^UM3yb2OhRlm9eV7qqprWB}@{P&N50y-8I%HxY7dmAQ zi!$NmwY-+s+CwFMj=3Y|LL!Bdu(*Hv)1N4XO0!bT5Q88*VKx*R?G!Wx{qToBT!Mk7 z(ijuE!#a);^EMFT2q%OB*5c26=96`gpyj&^J*?0y=Y%antaH*``2vw>AG?_U;5)x~jSpxH1VSQBg!O2u2Z9 zMrRxv6)_QTASy-)7$Y$ehZsjtRFFw#kUz#M0s#o8XAl`4SyIy@&_nv!(efHV^Jra83Mj1iNd-eCsGtVpmdz!0v zEN)zJ^v9uXOau<4Bq*@(PIGeQl~-0FTZgav2w{Xjzd7Vt4Y@%Ph8)HY`CtF~mj#Z+ z3(H0;t$-wkP|U?umR-f8jR{yFK;Zl4jD-$8 z{ruO< zu|9-q1)vG8=AVFwmVWiCUlgzb@bhl2v8*$MO~9=!QKE($i`Mz)pI>Wkew2)fa@Blv zHT51<=R0KxdIla7`$X8KAa&jXJ@zvpkL#ZO;LJv2+L;C{>=AVP(T|>0;}yT%#ce%g zt7rrp};~(F$D4~lr0u~9^=7KeVGDKEGKm?8Ie@mm*k&F=cGJTf`QE8#p z;?sei4NKUjfU%dlI<6bmS^+eyNA@y0=aS9++B~p$cXdf0SmObnVxd8!ltYm@@H9Yd zoptUpzs~=;6fS^UN+rppoy^$gG&OEn=$9%IZ+!Y4*G_u_Fab*1BvS#<`j%2JDHp_Y z@|@@FIx57T8hg{|Tg)8gi+%=lM#<5Yx7lnS3?5$ZyXmGI$`Zvw6ic7?I17AdznWY8 z!koAif49b$Ui$6Y8`d~;VU8&1&k_k!|zh~Jhgp)@PiwxPapsI$BS+}8_T1$ zqQnG7jhPYy*a{!T6P(e%{N*p|9I(I4fp=bi{WWzzmuTy1{VCI;+~D4c-eo5jM(~SY z{H&CTlS)brz-?CGw)foK0S9jljI$0W>XpSAIj_h)TZ+ zTMo?Ck3YvsDRjwC73s;e9~Pfd{_5`hUnF?*B0 z5(Sbu@-9}cNj$FwZUp@nxakYmDuMt3+dw5BW$ zx88b7%_(6+|5+(1wcJM&&Q+Clk^7wMh$9ZGH6p+sb<|Ode)E~;oTt^A}!~Kn8MZ)BUQVy8(gt~R&j$Ad0c+P{24nT+MJt9!Zsnr z_#-$GD!2wY7Z#7@y;UnSu0VwUSuJi!BBDIZF~=NJYu5?b@1FbM2R~SrUgxQG4S?_t zK#X7%5TL)#V6JcyW~6W=nh*gU;?py(H+`9Raaej>iGF1#8t};MUb~y>IPt^GIgkUWjg4fGCvq z*yH(g|L_mD7wtp+4hGLR)-yS*vN&Ne5f7#oYLzX-}pu;c@mDGM3DIc@LN}PbBBkt7Pst2 ziY~G$dcc<$9K??*HL+Bjt+7)$Y1e1(>5|mlug<|Qed$Xz5BjT5l%xP^mtlL0dWOsX z)1SW6C=rrzC<$a9_0O}cm-bW?V9o>$s_-*Jt?<2vAW-(_x_o6ieJyOyv*_~)g-1%_~He0Z+@;pc={f4Qm==Hve4 zT|j8}x4Ra!>JRDt)_qRwT>FgQ+#gp@YYJEro~)Cap$`2?f@**p?Q@&-fWV2C)>>=r zT3;aEnxhG01a8F?dbcs^3wlh9TN|6v?{7+tIngLMJc`oQgi3%)u6ZZ2&B&n%wS(EEf1plvQu#sPG&X83=nz2C3| z!t@b60c!*|a|#$G>meGnN8CeGE=dQiIV)>oXcE8PF9)>UcH7oC#JSS)6AA-7lB_^7 zk+zO2uw}o+dgdJjey(H27b`%YMiT><7_j95ZuhMeo@|WxC}6=#Hm+Pin>Z$}sP>@#n?p%e&`wGpS#RrSPo`*h*4(@S@z#b??q@&y zX#qhpT9Sp}uja#i#HWU5uYiuMYZQ9Uovd$b^#t5l0t4La5unJLqYwSkS0IIpbK=9MDSxaFMH#+s zADct{aNdy5Dc8)8v(n+qNUG z6Q7MiOgSY`fVy{D%f~(Lv7>}E{!&^1nk=6bbm2?RF8qb^#TW*Q+lm6WUAq`Jf)9^TGi1b~1bX_^e$51K>^XaQ_cS|wWXWTF|@DGQ6JAbOjOX3?RV`c+G%AC1qw!z@A9 z7!hCUE>>c4@Gg@&4L)rICgY%-^vrM#*Kn;Gi<|GcIS~x}AAcY?$Zp00#OltC%K?-9 z4Ujl!cHQ-lYTtHoH(M^t_V(@)BniF*o?Ui%c0Fe=1ADaBegjfy6ayCYhkJ(jDt)0P zPk*(`&4r*4*F!vvg)Un3?YG~q4i|1yH{5VT0f?^9^0jln{N>L};Bj~o^8A)!wg3IU z|MT1tM;uXYMCc)~i-(9MZkqCF!Bz5aYwqw|LXE?mJ1Abf+h_y~K#U+9Fol-T7i$JLM8J(u5zyne zR#5eBzzxWbV!<2}q^`X3`!&Y&*VqX$+CdY9?+E-$xlHzfTl#NZ&`k&2PAhFZfw}_> z8s3<4%Wa~yD!`~yAE_=}G*H)z4WVtM3>MOX&nyX>S7 z8P$*U4(oBrCEpsI^E>YN7-UZUuZ5bu5f4;Zy>0q117z5?F&$t%!i5X6^wV&R>HaF$3kiC*nJYk|hmXlI4` z{hC{IA`Xu$sXlv7Okqm609EKXF036u+PK^quejp!0$|-<{dNI)bj1a+&zAs)tFF4T z#@$)VwyQk})JADw-`GoJNn^AQ_MZFGKXS19(VAzI;4T(7X9M1jRsygl1Gg_P18xtU z%0sLpmr{xsZDpTRE^r&Rr}b0c%sD;=e0rCAos0M#m&VYEc`|1KpUGTIrgtXW5BMHH z4!Gho+KXK8-UmN;liI(DVT&gSeg_M*an{xVZwqikN1aE=0Nhqx9k+ev?#3JpX=5^w zGD64v9sJxRe6|^wI}wuwv%ws`lPqr09*Ajhpr3ZysYSfZ>_;5&-kA#i#kJzCZ+&x_ zza7f_*^}vJ-1A{h4ogA;fsuQTgG+Ga?@}p&;To=gPv926cCIM2>lig2U>|a&!>sWG ze)tYT?kWJuM?UhA+P4llhaSexg@Z7}0_OmBxJ#}5{`bFsl)+4F17PPjhu3F6+r?CP zmY;p%0~~xTX?Wav>#bW#B<&KOlIeB;4A#rvPYz=kY!X8oE^0oof*xh-+8pTD0-VTIb+3KeVa%IUYzr zB5eNTC%2d7rE?$Jtk#K}l`&4TW~`{iEw!!04msevY@!F$L2q2s+=dd<29Q%A5(LaK z!Tp`@d`FFqq7j%UFmj_4JP%}cSp*-p%;LF831cf_adU>CQ|nIPnpQ6_u0zf`Kq~dK zj2Hdi>s}kw8OTaONKI@N;T3S}>S8@$Iji5vhb^k-h2 zbHGFZY-pH3D)m3B9buGfDYr_lu4q;tSoHu_&)6R<6@Vm5h;|dJ)>?kJLMJ9Zb8f5v zVpsF({-vo0$e!?oPJwE@$Ph&BZq~4KUE8?&W&WciA`5ZXGfs*XAQxXU#$%2-s%RLWVCAvy zluZ;$#t@5}xv_Vb0&Yp+&ZY3sL*Fy1c}Zv&zG5x1C-oN{*l(2c0m3Y&cyQ;sxnbQa zrmD~50d$IY&vb6ePc3@&E`0z<&^kBEBrswD1Om~vc}*f9E{p(zy#y#zP66O(1P!~# zJaOaYD)0ZX5DKs1U0{E#yY6~rsibg@!M1<7$(yu-sWUZK0RPKmKvGzj?d-=tnn~av`y`gFLk&7PsB! z90mte z*kg+q5!~83JI2kjclFg*j*^p@A3RgM&Lmzpu5Kd%NfHq*qIj0R5nPOe;6R~ka#*HOXo7Tqfoq)ULq8dx>)vp26zb5^b zEOufBY50@gJ$!np?7*FCfP;rS_~#0ct=B4RzV>o;?rf|EBs%!%q=w zUs9YH3n82Wq|1u>pi#WiLK22fctl73C1tvEpQY6qEap(wI(=qI@Ef6uW4HsRY+NpP%@XIP_v1b+dXBp_iSS61aGKe?^qK*@5kqL>r$oZ|ZMO6zA0 zGFM5{?;l~^8vDQb1o{Cpd(K?oZxjM?tp)1P6T0`8W!HOwA@pw^%oDKp;~(Ez06p0Z zDc@L-&`g(Kq2tfi!~eTv9UrR@9f>aDy)cdz%q_P{9ukRH?q}u%W+;0SYiJ!<>h#%K zC@*8bp;3GojdEE>Uy0+?S9|8P(@q<$seRyn=L~sS92z&|S*)p@^6eS5U!0-VR(pUC zo&aFk2T52$u>!19Fqw0-hF0--v}XU3<;m}{AnLm|fB3_j%G1Ia$j91s)`~~Pm$cc% z1%A5Li>C?YCcZ1VmopIf?$^lVh0!YBoW<50{r~7kKdf_ksaWp;xJ?0W+b&B^;!t7E zw~0+?d|GK!YBgP7CYVWsjps;Mz;@^n44}+bb4U!l3mMD@AjjSZ;km zlZ3sv^u-O3Ma1*g(YjcB&+;^3J*8mifY%mv?h?k_+t!xSFY|!DSrHO5Hm;Uxg#XS; zwN=q5ms1(#xBw@NLI09OU|bzk?K{)CsU3IRF^lR(88g7Duhx!b&sw^Nf`c-H1)NqM zp!0tq$=r0M5jq+M_*v-*rESumrIL4;w^mW&JM%>-Mfb+)y&0!|Iaw}i;|>W8#GJ!jzy$Z7)`no?}9FviG+ooQ#jcOrONo%d76<5-Y9hfeX5w3~Tm!R=`DjinUI zUbK(xVKOA^3xJZ66!EUIr-3E|n8VDM zeo)k*Pc(+M?SGbIdk)`Xb+^yCgl6qSUo3T9@}jO>%NAQaeA)ZAtoyC4ws~tT=1XrG z<(be%zYe20%o?N|fc`w?DNil%Za#Lp-n_ow2*O`v`K8h^aYW7 z2O-Y;qQ#@R8?s6c*Kn=g7`F&+_MQFL7I|*1@zJ#Q4;1^?Z*5F!>pGp7*KzH7#SWc>8X+DxlzO6$!t=&m;+@;&@_+{c#(g*#=J6TVXmfN`6 zlg(M!Gi?KdiM{Dk#p6zOvZnkKB zvaj6R)@kc%dHwzsu>u-2W zyDojc6rPoF_SdHWuB@l~tZ~=R1v*PD!~p;7^S0e~j?qMDs->eSRI&!G;H@v6yXxO8 zDukUm44tJ8UCUkkNd)wH>X|&Mt<33+W@#y}V z$67RwM*GFT_1|yC+drq!S<9FF*5@7Vy0&$Oy(hHRo{Q~#$4HTL7;UG&;UC@|SL^;9 zbQai0Ez3yx@Lqn3hl~s-iCOZM9h{X{t=v;dgI6Dd6ax7O%0$Wtp($1RBdu)_{1 zGe4huZUIcB4nQwp5^WFRSz^>efXuL%FKralDeYMTK&2ceNQhzckA@(HaG`tw^A;S^ z=W-F#aWW@))?xW?|Mq`IOvZ0a-GXWW7Z{4xK5V1{eBR&P0g+%ryKZv}_e4X-`; z$Njdt+HHTEMG%PaIY}Vy|29jzSXFIxKCgqu6|Z zjO|+V*A-x(MHYN7K8vP)ML=7h*0j%xObbo}pUc_wrZ>H*1QKqvKw{3ycKyfEbGx?F zTsNoD|5E#AdFFR{pN){){(qKsC(&;bp3w4JJ28wbbJJ?aP1>i^ct?K@S9WdsG&&1k z8rRDkbhcl~M68gp`iz_3NjzkE`V^PCadW;f);rEwpFd6dKKr)ce%q(z z>F+e!o~DRf-Zh`p-`2X@pZ@?)o@^|YE$_&>l2M=hopk0+`)zsK?VowZ z!g9zZntLr-K63x+R2JU#lauV)l>-Q2`ODnO5Bb->{>QRfLD>#@{?jW`ygJWdLSkKx zKmPb~C22Kq5IQTG`YkCO7_Fc~k*g&)PIaLYklH>g7*w6M_5k5>B{6`56yY$vx4#e9 za1Gb$1#ZK2=en#{U-N!frB6a+W z=zlbmRr$AxH^kbUWHz%{N(bOJOIFF3&)uz^M5gRiP)AH+RpJJ)G7KPDdbp4Tc(s}s zT2eu<{a6?-krJl3n9s*)cl1rW<7%B~v&)3}kin;RxQ6TB!BsMsz1(J-8mG~XVyD&i z#kH>=qm#d@vfYIk*)2xxPI`CR@4vS_q}uoP``aqMmeLj{Za3q}=XMjN6a96W<+*WVZ2Qr-U?d4a#yjh~5+l^kLHiDI*@E%`v|P?L2`=n` zw*Jw$wwH3p9XG$(W8>CyRqW+<-DjoI<*}AdYo|Zf_PNAF&g$LM(n+o)Z&_Ij&8+h{ zj_*v{kCR-BxuePQx4{O#R~c;4n9Jv+QeT;V&axl+ea(DM;=L<-o@9=;*y0hZto=Ki z;;hd*!auBQ>VMu<#@t#S6I(lgwpHjVIj-npVj@ysWt(lbUZDwZ7cU2CpEv`wQro3( z?)O}t9d}6k-tXhu%(Da04A*e|`y?mvol9^tw=tlo-FNQi?kuJ?0znI+>|4Ka({6q5 zBVdYWO`+LV&~&e7JgbdL+EL;>iSwaX@r=-9P)u zF=i3US|PKerN>t)>NcbBtU~>){Y|X3xi+T(VSO+-?sD(6zO=5Bv-UTAl88Z{%)yEX z?9=AgJ}{5kc7=Xcm7qG!TDGFJG;KWgNcM8Khq`R4vv><7JMD_NHn(9UeVPfsLsKnZ zn)D8RwHERXkiqbrme!W41-Vpzmr4*c4#fJaPk53!Uey*>bA-;VSrR7Qm8>&M^N(!? z_rU?UEngkCNmepUeN}4shHJQn>#l8a>wv{JmGb}Mi!Yx0<~P4NchErxjra&FxP(V) z%_#IM2>z*0ecDKyE1|@H{?8w;Vylu$B)$7qTXpY$?|Togx?BoWOK=py&pnEse&s7) zsdgn+;!ht9vFv41SZnvIUp>Dv%W`H+j>>vPG0)bm(2a^ zzy52bS{Dc&Wl-k^(-kyT!-m&F2fiL(^{mvY;^Qx+J)i%+<*0A{19sKekp=gbTW+3j z_p&N7tcID=E#|H({Qb9;(NA$zbK>x~4twnJ$K@?ytWxRAo~B^#B*B0n$74ZEv$WAt zuPZ4aYh|nm5%~O-YMn6L7p$T{>nquk#ZG*)Dvasc|(96i-rcj!RBr4P+g(;~(0W001BW zNklwVb+^Mmyd*{XVpcg!EC?K;JC|#QSurFG?8LH{p%(`VrfY=in{M8$A8# zJ57wW_ik&hRDpf3h&>*ulv1+O&cdJDxoZnYqj8yK0m9TY>(i3H%c`isj1d>r@zK zHv64@v&>o(Xc~hXn89!j*QzPNO&}3yEj}aGCPE8PMTjQIU3lRIl}?zjb@IvYtE{uJ zo=HBW#*o+~LbPY4D)y|DK&>#C zlTJEuB*00}En!mYQZ;Fg-M`jaYga8G{Z;czih3?o1XDnS0PkISpRo{@&Ao(9?v=t? zJsLE2&n(2HLE93f)R{f;N-E&R=tCZLCp>{q`-s)|=ZE zfqI;!Gyt{DOsbHx@)FjnqtUmPA|v(ClHG54$~bt|K6=!n9$5g&nAAnfSOXx0WT2(K zl`6%^W#x09xk|>pWbDgW{qFg$Ao3e3ftfWo7W)Ft=DpUYZ=t7TNm1+6Q(JGn^~$Af zQuf$B_>kGp+9+JC&RKw&_IKIkS*3t_?sK14>kWjfs~8>ty!Yu4y|hK;(Y*cycrJA% ztE2D`bmzVC2te1?1Yf@Qz3)?V=-w7kcUc5Co; caIWDM3Ijtz3+V|*1ClU_V*n6 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 z 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 Aa{vGU literal 0 HcmV?d00001 diff --git a/doxygen/images/dpp_win.png b/doxygen/images/dpp_win.png new file mode 100644 index 0000000000000000000000000000000000000000..14896b6ab45b29d22e21f85695fadc156a8a3a04 GIT binary patch literal 79277 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

      8mJK`h37omfZ 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 literal 0 HcmV?d00001 diff --git a/doxygen/images/qp_banner.jpg b/doxygen/images/qp_banner.jpg index 5612aa7a1f3290abf147e87700a50e794a853c1b..93231a1ec6e333e0e0ed30bc5bcd1e6640782a0e 100644 GIT binary patch delta 71544 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 Q;@6&Hv-pF|IFQ-fDq70uq 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

    1. E?qAjQ3iOJ$2@Re;K;;ns7l65ltw8 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�`G_vMT5MuoTu|n%a zVTJBK`qTdEnIM3=v=tSrXdN?w}cNd>=)JCq@Bh*9T1s*a`MR#mIz1#X>V4gcIgb>w+ zYP7bwHnt$BD0g6+ffi}tM#GM(ED;q0RMf~ozN{=@2(ZiDS*{EeS)id-A#I7^THRPM zfpSfWZmY|>LQ#p*MC@D`iI9q~Wrv^@uo!bNAsyr*AlRA$$~y$IA{aJ$M6ZC(LD(*O zj4m;OSu7uzj~?W#*U;_-@;(W1R~|);tQ|%0D@D-DrR?%9)W&j^tvG1zYL#NZfvSM$ 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 diff --git a/doxygen/images/qutest_philo.png b/doxygen/images/qutest_philo.png new file mode 100644 index 0000000000000000000000000000000000000000..7257fd85da28316cfb4efdd3f0f5f143579d02fa GIT binary patch literal 80468 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 literal 0 HcmV?d00001 diff --git a/doxygen/images/qutest_py.png b/doxygen/images/qutest_py.png new file mode 100644 index 0000000000000000000000000000000000000000..297a8e17599b9490d1a36ab806534e6684b264c9 GIT binary patch literal 65702 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

      ey?ib2Kj?}`D9xxB;)ndHCLkp8SCmN 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 O0YEY;(p8clzy2S2Dc3Rp literal 0 HcmV?d00001 diff --git a/doxygen/images/qutest_tcl.png b/doxygen/images/qutest_tcl.png new file mode 100644 index 0000000000000000000000000000000000000000..2d9afe8ed6eacdd8f637474cffa09c978a00b144 GIT binary patch literal 109239 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�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�YdmvN2<_>Scb8$;p|(c! zRn+%xqMF)-Wv6{4&DBsZene62cIlE0-OWOoZCynX$(BR?$gC}_XI0I*SVLyM1i=%Q zK2?YOn$$1XF@<@L)wJG`KD@XEeEPwJDDCh!zdEFb^$I*4IhztibJ!(UF^W`_F1vT> z?YsmOybcU;kvjW)){JHW?IWn%hc~jL+r4mi_bC4djc;Asrj1@NJ|AtV6_zZPc;jPk z^65o-9T4gcOY00dzPb?4ytA?JpiFN9hu=ciQ_&C2v>KUrDq(iGb8?7}6)cZ9eI?82 zv!w2I8C#2_!;EzB)w}f_79zfXuQUa}gJxXIz2=^4d2wX$H4KPYj>dml1a;lM^EH3BExMaYW33d*gXAoY@p7@Z3@v-WsrWfIG7O=FRYb8UbblaC`alPYuk#9Ej1+3L5=Qvi}aPV*rT)6moy&d z^dRb!DJfjNLvwzAaz^rp$;fwt!~)Z$nZLVn(n_6qD*zF7G! zg}Y&7xdOg$b8|0i0|5Q1s;U<|JBIEyHaHm>8T}bTUXel`_jq29x1T*ecIwcnVU{ zSvI`?Qw6f5V~WqHenIWs15b4W&-o8r2yK$DfA^}lp|3jr*b};P3lf@r-yWZjzlCqo z$2;X^wR&cDxhYtz6<#$aRY1CSiEW<2b5im%QMjb#;&#SKq3>t~5yiKG$@-W(s{3NY zoy2b1Sis37Yfo3XON(Y!z{{T$depP(!f95z$MHB!!b~psiy7co19#h6BAqeBe7~H0 zHBZAv#Fa8TVjIzO{`?JLD|Fs#pz4Pf)6;i4rsNDg=~`+kxEQUl!Gt{`i%!HNFSF#b z!to7Fk8_yVd{vTLbYM0YPyc>#^JvNmzG_IvSU1m6-6r%-finCC!74`Xd2wwbVT(|6 z@vxMD%0dW!Hku?tLew0{qR(S4%a!(&2Abxv9#}!2ZW6ML&f%hS(O4?6jT*k-X6I@C|XT-DC;@x-SMejxC6UsPp<2@oTmP7EynrG^@}$5k#0L zoN0yS-vZh`p4&j_~Pbk$Qno_S?8N}!IQ{wv@kZ6TR;G+5rtKGy+ z;+oM)sTAo4WPQD8-B)R?gk{BoOM1>j!lAH<{gPJC`X(0tQIw(Xp6fg z(a^7Wp|<)ZsiJxbf~?8B70T?JJd#Y89RGKlB)I3haHZ-TK{yzmdO2)`cLlh!nW%(L zoXMp7rJB`60^nz_*DT-dZ{8)`AQ{uRKW8F

      Yze27Ny{T+|2Fs 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�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

      M;=xe=RB{0Qg=7pd3-+K)|3pI);BWda_G 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

      g$ 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 literal 0 HcmV?d00001 diff --git a/doxygen/img/file_qm.png b/doxygen/img/file_qm.png new file mode 100644 index 0000000000000000000000000000000000000000..d1e90ae25e78decf042bb99a5f2685a5b6b8f606 GIT binary patch literal 1030 zcmV+h1o``kP)FTy9Uy?f2HZG$(CXjSi&`SwJPhoA|1dE9`v=y*3=9(%pdoBP zO&maVU{`=?py5Dy1IBOu009Ix;KZ)O_Ey}#8U6yD#`y0q1JmEX49x!^HnRPPXy5|6 zgqx8G=!O3bT&zGD9v%igw!a1d0R%RH|H}tuUZ5cNAD|zBCi8*BfEsv#Hu8hm3{Y{P z;hfAs&743Zxi}dFn3)6t0tjpX@84g~dH%672mt-Y160fpj8Z-Zh(Tb(pfnphI|Cyx zFT;NxUZ5Z^!yhJ|ZvX)VHh_uY*JbYSEDZeoYz#a=rwf1#h1$*s3ARyKB^ARog& zL7=RNFax849K)4&9FGA42yB3Yy3&5Or?1}e|N1S&3yeN~kaIz<00t&66C(o)7dOLy z5m5#PNl69<2~h?{NofWKWkrUcx1a6<2q3Tl4#idX{vJ76#j}3R3}JpgpaF~wJYT;u za7#)su!xE=Fo=mWFo+5>FbE1UFiHRoQBz?!fBoKrdmq0o1qdLp0qWmAGJNoKob&hp zPczZiZ8o482a0-}l8ota)3#XGAv zMsT~>;^$nOw(HmF`RIY3Q4Uo)`avycwrfW_kYZs#H`)ViNMs;bJ`9Otac(gxH%rLO zOr_z4+&SFP{JNJ|DjqF${w=(KL-b9*@rHa3HUjL%HExd_WNX7zzfZfk@Ac zKNNb_=5!(t!|b7VJenR}G`R@^@jPES(4QF_@9&p4N+o5wC#pjX(6 zhNg9@{*!>F^=`KtrTQ)sA;JaW6DOrXqY;K%THtzfvwYKFfMt{Ex3-DEas>PY(MbH=vc8;v-YJElD81(_ zht9n6a*3*{g5G`m?$fSB%#=}-R)vX}zZ2MDU z{$gq&&qE<;h0%;1a=a0KwORl^RE=Mc!1l@-+?kt#Vw%PaBP1*qgHV_l`zDi4pFr8{ zpn2(fQd-EfuzIaSS()m{IVQ*u(=+EVm>3V ztz0c~sV(?A{0D}!3IEJEe}7}KOS!ce!md+q17$S8#+)C1n*R*$-8_%CZpZQFj{@FU zPTw88B%HBW?d3J<2$u^n9xviK*SCJA8Pk?`WW%d3V)pb~ur}QZTR+F~-PMpXKf&TT zF}Bqeh#YV@T#VjF-LoRt~HV*6G z#bK(D9dWy9&7&)G@Q_4xuWfDKstbuPxxwV;QkXps1JRFQUgTiq#s!!x=8Apk^f52j z{+LGXzfk^%Mv5X;F5D;_iM}+RORtJ!u?N%Q<)K6(*+h~IvfJ(DnB5+<`#Wo=O4lQH xn@#1zrwjK8wHB*QHQKa+Rj@3(XLqcozW_~+B=wPkl-U3P002ovPDHLkV1mm>+(ZBX literal 0 HcmV?d00001 diff --git a/doxygen/img/img.htm b/doxygen/img/img.htm index 1c187d1b..76049dfb 100644 --- a/doxygen/img/img.htm +++ b/doxygen/img/img.htm @@ -21,12 +21,18 @@ - - + + + + + + + + diff --git a/doxygen/main.dox b/doxygen/main.dox index b65f61ea..c9433459 100644 --- a/doxygen/main.dox +++ b/doxygen/main.dox @@ -3,13 +3,13 @@ @image html qp_banner.jpg @section ab_about What is it? -QP/C™ (Quantum Platform in C) is a lightweight, open source active object (actor) framework for building modern, -reactive, real-time embedded applications as systems of asynchronous event-driven active objects (actors). The QP/C™ framework is a member of a larger family consisting of QP/C, QP/C++, and QP-nano frameworks, which are all strictly quality controlled, thoroughly documented, and available under @ref licensing "dual licensing model". +QP/C™ (Quantum Platform in C) is a lightweight, open source active object (actor) framework for building modern, +reactive, real-time embedded applications as systems of asynchronous event-driven active objects (actors). The QP/C™ framework is a member of a larger family consisting of QP/C, QP/C++, and QP-nano frameworks, which are all strictly quality controlled, thoroughly documented, and available under @ref licensing "dual licensing model". -The behavior of active objects is specified in QP/C by means of hierarchical state machines (UML statecharts). The framework supports manual coding of UML state machines in C as well as automatic code generation by means of the free QM™ modeling tool. +The behavior of active objects is specified in QP/C by means of hierarchical state machines (UML statecharts). The framework supports manual coding of UML state machines in C as well as automatic code generation by means of the free QM™ modeling tool. @attention -To use QP/C™ effectively, you need to understand the key concepts that underline the architecture of the framework and your applications based on the framework. +To use QP/C™ effectively, you need to understand the key concepts that underline the architecture of the framework and your applications based on the framework.

      @@ -21,20 +21,20 @@ To use QP/C™ effectively, you need to understand the active objects (actors), which is inherently **safer**, more extensible, and easier to understand than the usual _shared-state concurrency_ based on a traditional Real-Time Operating System (RTOS). -- to provide a simple-to-use coding techniques for hierarchical state machines, with which to implement the behavior of active objects. +- to provide a reusable event-driven **architecture** based on active objects (actors), which is inherently **safer**, more extensible, and easier to understand than the usual _shared-state concurrency_ based on a traditional Real-Time Operating System (RTOS). +- to provide a simple-to-use coding techniques for hierarchical state machines, with which to implement the behavior of active objects. - to provide efficient and thread-safe asynchronous mechanisms for active objects to communicate, such as direct event passing and publish-subscribe. - to provide event-driven timing services (time events). - to provide a selection of built-in real-time kernels to run the QP applications, such as the cooperative @ref qv "QV kernel", the preemptive non-blocking @ref qk "QK kernel", and the preemptive blocking @ref qxk "QXK kernel". -- to provide **unit testing** support for applications based on software tracing (QUTest™). +- to provide **unit testing** support for applications based on software tracing (QUTest™). - to provide portability layer and ready-to-use ports to @ref ports_rtos "3rd-party RTOSes" and desktop operating systems such as @ref posix "Linux" and @ref win32 "Windows". -- to provide a target for modeling and automatic code generation from the QM™ modeling tool. +- to provide a target for modeling and automatic code generation from the QM™ modeling tool. ------------------------------------------------------------------------------ @section ab_special What's special about it? -The QP/C™ framework is a unique offering on the embedded software market. It provides a modern, reusable **architecture** of embedded applications, which combines object-orientation with the particular model of concurrency, known as active objects (actors). This architecture is generally **safer**, more responsive and easier to understand than "free threading" with a traditional Real-Time Operating System (RTOS). It also provides higher level of abstraction and the right abstractions to effectively apply modeling and code generation to deeply embedded systems. +The QP/C™ framework is a unique offering on the embedded software market. It provides a modern, reusable **architecture** of embedded applications, which combines object-orientation with the particular model of concurrency, known as active objects (actors). This architecture is generally **safer**, more responsive and easier to understand than "free threading" with a traditional Real-Time Operating System (RTOS). It also provides higher level of abstraction and the right abstractions to effectively apply modeling and code generation to deeply embedded systems.
      @@ -42,11 +42,11 @@ The QP/C™ framework is a unique offering on the embedded software market. Even though it is written in @ref misra "MISRA-compliant" ANSI-C, QP/C™ is fundamentally an **object-oriented** framework, which means that the framework itself and your applications derived from the framework are fundamentally composed of classes and only classes can have @ref sm "state machines" associated with them.
      @note -If you program in C and object-oriented programming is new to you, please refer to the Application Note "Object-Oriented Programming in C", which describes how you can implement the concepts of _classes_, _inheritance_, and _polymorphism_ to portable ANSI-C. +If you program in C and object-oriented programming is new to you, please refer to the Application Note "Object-Oriented Programming in C", which describes how you can implement the concepts of _classes_, _inheritance_, and _polymorphism_ to portable ANSI-C.
      @htmlonly
      - +
      Application Note: Object-Oriented Programming in C
      @@ -62,10 +62,10 @@ The most unique characteristic of the QP/C™ framework is its very small fo
      @subsection hsms Hierarchical State Machines The behavior of active objects is specified in QP by means of -hierarchical state machines (UML statecharts). The frameworks support manual coding of UML state machines in C or C++ as well as fully automatic code generation by means of the free graphical QM™ modeling tool. +hierarchical state machines (UML statecharts). The frameworks support manual coding of UML state machines in C or C++ as well as fully automatic code generation by means of the free graphical QM™ modeling tool. @remarks -State machines can be an incredibly powerful technique, but they require an event-driven **infrastructure** (framework) that provides, at a minimum: a run-to-completion (RTC) execution context for each state machine, queuing of events, and event-based timing services. This is really the pivotal point. Without an event-driven framewok (like QP/C), state machines are like cars without an infrastructure of roads. +State machines can be an incredibly powerful technique, but they require an event-driven **infrastructure** (framework) that provides, at a minimum: a run-to-completion (RTC) execution context for each state machine, queuing of events, and event-based timing services. This is really the pivotal point. Without an event-driven framewok (like QP/C), state machines are like cars without an infrastructure of roads.
      @@ -82,12 +82,12 @@ QP/C can also work with many traditional @ref exa_rtos "RTOSes" and @ref exa_rto @subsection popular Popularity & Maturity With over 15 years of continuous development and 60,000 downloads a year, the QP™ framework family is the most mature and popular such solution on the embedded software market. -The QP™ frameworks are used in millions of products worldwide in aerospace, medical devices, consumer electronics, wired and wireless telecommunications, industrial automation, transportation, robotics, and many more. +The QP™ frameworks are used in millions of products worldwide in aerospace, medical devices, consumer electronics, wired and wireless telecommunications, industrial automation, transportation, robotics, and many more.
      @subsection psicc2 Book -The book, Practical UML Statecharts in C/C++, 2nd Edition provides a detailed design study of the QP frameworks and explains all the related concepts. +The book, Practical UML Statecharts in C/C++, 2nd Edition provides a detailed design study of the QP frameworks and explains all the related concepts. @image html PSiCC2-3D.jpg "Practical UML Statecharts in C/C++, 2nd Edition" @@ -95,7 +95,7 @@ The book, dual licensing model, in which both the open source software distribution mechanism and traditional closed source software distribution models are combined. +QP/C is licensed under the increasingly popular dual licensing model, in which both the open source software distribution mechanism and traditional closed source software distribution models are combined. @note If your company has a policy forbidding open source in your product, all QP frameworks can be licensed commercially, in which case you don't use any open source license and you do not violate your policy. @@ -107,7 +107,7 @@ If you are developing and distributing open source applications under the GNU Ge
      @subsection closed-source Closed Source Projects -If you are developing and distributing traditional closed source applications, you can purchase one of Quantum Leaps commercial licenses, which are specifically designed for users interested in retaining the proprietary status of their code. All Quantum Leaps commercial licenses expressly supersede the GPL open source license. This means that when you license Quantum Leaps software under a commercial license, you specifically do not use the software under the open source license and therefore you are not subject to any of its terms. +If you are developing and distributing traditional closed source applications, you can purchase one of Quantum Leaps commercial licenses, which are specifically designed for users interested in retaining the proprietary status of their code. All Quantum Leaps commercial licenses expressly supersede the GPL open source license. This means that when you license Quantum Leaps software under a commercial license, you specifically do not use the software under the open source license and therefore you are not subject to any of its terms. ------------------------------------------------------------------------------ @@ -116,7 +116,7 @@ Please post any **technical questions** to the Contact web-page for more information. +Training and consulting services are also available from Quantum Leaps. Please refer to the Contact web-page for more information. ------------------------------------------------------------------------------ @@ -125,7 +125,7 @@ Training and consulting services are also available from Quantum Leaps. Please r - Free Support Forum - Bug Reports - Feature Requests -- Quantum Leaps website +- Quantum Leaps website - info@state-machine.com@n @image html logo_ql_TM.jpg diff --git a/doxygen/make.bat b/doxygen/make.bat index 54d5b702..47f8f205 100644 --- a/doxygen/make.bat +++ b/doxygen/make.bat @@ -1,12 +1,12 @@ @echo off :: ========================================================================== :: Product: QP/C script for generating Doxygen documentation -:: Last Updated for Version: 6.3.4 -:: Date of the Last Update: 2018-08-08 +:: Last Updated for Version: 6.3.6 +:: Date of the Last Update: 2018-10-03 :: -:: 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. :: @@ -38,7 +38,7 @@ echo usage: echo make echo make -CHM -set VERSION=6.3.4 +set VERSION=6.3.6 :: Generate Resource Standard Metrics for QP/C ............................... set DOXHOME="C:\tools\doxygen\bin" diff --git a/doxygen/metrics.dox b/doxygen/metrics.dox index cf0d4b9c..679c1d77 100644 --- a/doxygen/metrics.dox +++ b/doxygen/metrics.dox @@ -1,7 +1,7 @@ /** @page metrics Code Metrics @code - Standard Code Metrics for QP/C 6.3.4 + Standard Code Metrics for QP/C 6.3.6 Resource Standard Metrics (TM) for C, C++, C# and Java Version 7.75 - mSquaredTechnologies.com @@ -9,7 +9,7 @@ License Type: Windows Single User License Licensed To : Quantum Leaps, LLC License No. : WS2975 License Date: Dec 15, 2013 - Build Date : Sep 2 2009 Run Date: Aug 13, 2018 + Build Date : Sep 2 2009 Run Date: Oct 25, 2018 (C)1996-2009 M Squared Technologies LLC ________________________________________________________________________ @@ -131,14 +131,14 @@ NOTICE: The end of the source file has been reached where the - open brace count { 29 != 27 } close brace count + open brace count { 31 != 29 } close brace count This is an indication of non-compilable code within the source file. RSM processes all source code including code wrapped with preprocessor directives. Accurate metrics requires that all code present in this file must be compilable. ~~ Total File Summary ~~ - LOC 507 eLOC 498 lLOC 124 Comment 719 Lines 1239 + LOC 514 eLOC 504 lLOC 130 Comment 743 Lines 1274 ________________________________________________________________________ End of File: ..\include\qs.h @@ -148,7 +148,7 @@ ~~ Total File Summary ~~ - LOC 72 eLOC 72 lLOC 0 Comment 43 Lines 124 + LOC 76 eLOC 76 lLOC 0 Comment 44 Lines 129 ________________________________________________________________________ End of File: ..\include\qs_dummy.h @@ -486,19 +486,19 @@ st margin) Cyclomatic Complexity Vg Detail Function Base : 1 - Conditional if / else if: 9 - Logical or ( || ) : 3 - Logical and ( && ) : 1 - Complexity Param 3 Return 1 Cyclo Vg 14 Total 18 - LOC 85 eLOC 68 lLOC 38 Comment 76 Lines 110 + Conditional if / else if: 10 + Logical or ( || ) : 2 + Complexity Param 3 Return 1 Cyclo Vg 13 Total 17 + LOC 88 eLOC 69 lLOC 40 Comment 81 Lines 122 Function: QActive_postLIFO_ Parameters: (QActive * const me, QEvt const * const e) Cyclomatic Complexity Vg Detail Function Base : 1 - Conditional if / else if: 4 - Complexity Param 2 Return 1 Cyclo Vg 5 Total 8 - LOC 41 eLOC 34 lLOC 23 Comment 41 Lines 56 + Conditional if / else if: 5 + Logical or ( || ) : 1 + Complexity Param 2 Return 1 Cyclo Vg 7 Total 10 + LOC 48 eLOC 39 lLOC 24 Comment 46 Lines 69 Function: QActive_get_ Parameters: (QActive * const me) @@ -552,27 +552,27 @@ ~~ Total File Summary ~~ - LOC 267 eLOC 229 lLOC 130 Comment 266 Lines 495 + LOC 277 eLOC 235 lLOC 133 Comment 276 Lines 520 ------------------------------------------------------------------------ ~~ File Functional Summary ~~ File Function Count....: 9 - Total Function LOC.....: 231 Total Function Pts LOC : 2.1 - Total Function eLOC....: 193 Total Function Pts eLOC: 1.8 - Total Function lLOC....: 125 Total Function Pts lLOC: 1.0 + Total Function LOC.....: 241 Total Function Pts LOC : 2.2 + Total Function eLOC....: 199 Total Function Pts eLOC: 1.8 + Total Function lLOC....: 128 Total Function Pts lLOC: 1.0 Total Function Params .: 18 Total Function Return .: 9 - Total Cyclo Complexity : 31 Total Function Complex.: 58 + Total Cyclo Complexity : 32 Total Function Complex.: 59 ------ ----- ----- ------ ------ ----- - Max Function LOC ......: 85 Average Function LOC ..: 25.67 - Max Function eLOC .....: 68 Average Function eLOC .: 21.44 - Max Function lLOC .....: 38 Average Function lLOC .: 13.89 + Max Function LOC ......: 88 Average Function LOC ..: 26.78 + Max Function eLOC .....: 69 Average Function eLOC .: 22.11 + Max Function lLOC .....: 40 Average Function lLOC .: 14.22 ------ ----- ----- ------ ------ ----- Max Function Parameters: 3 Avg Function Parameters: 2.00 Max Function Returns ..: 1 Avg Function Returns ..: 1.00 Max Interface Complex. : 4 Avg Interface Complex. : 3.00 - Max Cyclomatic Complex.: 14 Avg Cyclomatic Complex.: 3.44 - Max Total Complexity ..: 18 Avg Total Complexity ..: 6.44 + Max Cyclomatic Complex.: 13 Avg Cyclomatic Complex.: 3.56 + Max Total Complexity ..: 17 Avg Total Complexity ..: 6.56 ________________________________________________________________________ End of File: ..\src\qf\qf_actq.c @@ -646,7 +646,7 @@ Function Base : 1 Logical or ( || ) : 1 Complexity Param 3 Return 1 Cyclo Vg 2 Total 6 - LOC 8 eLOC 6 lLOC 4 Comment 38 Lines 12 + LOC 15 eLOC 11 lLOC 7 Comment 40 Lines 21 Function: QF_newX_ Parameters: (uint_fast16_t const evtSize, uint_fast16_t const margin, en @@ -689,21 +689,21 @@ ~~ Total File Summary ~~ - LOC 114 eLOC 98 lLOC 50 Comment 216 Lines 331 + LOC 121 eLOC 103 lLOC 53 Comment 218 Lines 340 ------------------------------------------------------------------------ ~~ File Functional Summary ~~ File Function Count....: 7 - Total Function LOC.....: 96 Total Function Pts LOC : 0.9 - Total Function eLOC....: 80 Total Function Pts eLOC: 0.8 - Total Function lLOC....: 48 Total Function Pts lLOC: 0.4 + Total Function LOC.....: 103 Total Function Pts LOC : 0.9 + Total Function eLOC....: 85 Total Function Pts eLOC: 0.8 + Total Function lLOC....: 51 Total Function Pts lLOC: 0.4 Total Function Params .: 12 Total Function Return .: 7 Total Cyclo Complexity : 15 Total Function Complex.: 34 ------ ----- ----- ------ ------ ----- - Max Function LOC ......: 29 Average Function LOC ..: 13.71 - Max Function eLOC .....: 23 Average Function eLOC .: 11.43 - Max Function lLOC .....: 14 Average Function lLOC .: 6.86 + Max Function LOC ......: 29 Average Function LOC ..: 14.71 + Max Function eLOC .....: 23 Average Function eLOC .: 12.14 + Max Function lLOC .....: 14 Average Function lLOC .: 7.29 ------ ----- ----- ------ ------ ----- Max Function Parameters: 3 Avg Function Parameters: 1.71 Max Function Returns ..: 1 Avg Function Returns ..: 1.00 @@ -918,7 +918,7 @@ Function Base : 1 Conditional if / else if: 4 Complexity Param 2 Return 1 Cyclo Vg 5 Total 8 - LOC 34 eLOC 29 lLOC 21 Comment 44 Lines 44 + LOC 34 eLOC 29 lLOC 21 Comment 44 Lines 45 Function: QEQueue_get Parameters: (QEQueue * const me) @@ -932,7 +932,7 @@ ~~ Total File Summary ~~ - LOC 151 eLOC 128 lLOC 79 Comment 210 Lines 325 + LOC 151 eLOC 128 lLOC 79 Comment 210 Lines 326 ------------------------------------------------------------------------ ~~ File Functional Summary ~~ @@ -1678,9 +1678,9 @@ ~~ Total Project Summary ~~ - LOC 4603 eLOC 4161 lLOC 1881 Comment 7347 Lines 12164 + LOC 4631 eLOC 4182 lLOC 1893 Comment 7384 Lines 12239 Average per File, metric/35 files - LOC 131 eLOC 118 lLOC 53 Comment 209 Lines 347 + LOC 132 eLOC 119 lLOC 54 Comment 210 Lines 349 ------------------------------------------------------------------------ @@ -1789,13 +1789,13 @@ Function: QActive_post_ Parameters: (QActive * const me, QEvt const * const e, uint_fast16_t con st margin) - Complexity Param 3 Return 1 Cyclo Vg 14 Total 18 - LOC 85 eLOC 68 lLOC 38 Comment 76 Lines 110 + Complexity Param 3 Return 1 Cyclo Vg 13 Total 17 + LOC 88 eLOC 69 lLOC 40 Comment 81 Lines 122 Function: QActive_postLIFO_ Parameters: (QActive * const me, QEvt const * const e) - Complexity Param 2 Return 1 Cyclo Vg 5 Total 8 - LOC 41 eLOC 34 lLOC 23 Comment 41 Lines 56 + Complexity Param 2 Return 1 Cyclo Vg 7 Total 10 + LOC 48 eLOC 39 lLOC 24 Comment 46 Lines 69 Function: QActive_get_ Parameters: (QActive * const me) @@ -1858,7 +1858,7 @@ Parameters: (void * const poolSto, uint_fast32_t const poolSize, uint_fa st16_t const evtSize) Complexity Param 3 Return 1 Cyclo Vg 2 Total 6 - LOC 8 eLOC 6 lLOC 4 Comment 38 Lines 12 + LOC 15 eLOC 11 lLOC 7 Comment 40 Lines 21 Function: QF_newX_ Parameters: (uint_fast16_t const evtSize, uint_fast16_t const margin, en @@ -1952,7 +1952,7 @@ Function: QEQueue_postLIFO Parameters: (QEQueue * const me, QEvt const * const e) Complexity Param 2 Return 1 Cyclo Vg 5 Total 8 - LOC 34 eLOC 29 lLOC 21 Comment 44 Lines 44 + LOC 34 eLOC 29 lLOC 21 Comment 44 Lines 45 Function: QEQueue_get Parameters: (QEQueue * const me) @@ -2259,26 +2259,26 @@ LOC 16 eLOC 15 lLOC 10 Comment 22 Lines 27 Total: Functions - LOC 2688 eLOC 2269 lLOC 1427 InCmp 297 CycloCmp 436 - Function Points FP(LOC) 20.8 FP(eLOC) 17.6 FP(lLOC) 11.1 + LOC 2705 eLOC 2280 lLOC 1433 InCmp 297 CycloCmp 437 + Function Points FP(LOC) 20.9 FP(eLOC) 17.7 FP(lLOC) 11.1 ------------------------------------------------------------------------ ~~ Project Functional Analysis ~~ - Total Functions .......: 110 Total Physical Lines ..: 3817 - Total LOC .............: 2688 Total Function Pts LOC : 20.8 - Total eLOC ............: 2269 Total Function Pts eLOC: 17.6 - Total lLOC.............: 1427 Total Function Pts lLOC: 11.1 - Total Cyclomatic Comp. : 436 Total Interface Comp. .: 297 + Total Functions .......: 110 Total Physical Lines ..: 3852 + Total LOC .............: 2705 Total Function Pts LOC : 20.9 + Total eLOC ............: 2280 Total Function Pts eLOC: 17.7 + Total lLOC.............: 1433 Total Function Pts lLOC: 11.1 + Total Cyclomatic Comp. : 437 Total Interface Comp. .: 297 Total Parameters ......: 187 Total Return Points ...: 110 - Total Comment Lines ...: 3081 Total Blank Lines .....: 566 + Total Comment Lines ...: 3093 Total Blank Lines .....: 573 ------ ----- ----- ------ ------ ----- - Avg Physical Lines ....: 34.70 - Avg LOC ...............: 24.44 Avg eLOC ..............: 20.63 - Avg lLOC ..............: 12.97 Avg Cyclomatic Comp. ..: 3.96 + Avg Physical Lines ....: 35.02 + Avg LOC ...............: 24.59 Avg eLOC ..............: 20.73 + Avg lLOC ..............: 13.03 Avg Cyclomatic Comp. ..: 3.97 Avg Interface Comp. ...: 2.70 Avg Parameters ........: 1.70 - Avg Return Points .....: 1.00 Avg Comment Lines .....: 28.01 + Avg Return Points .....: 1.00 Avg Comment Lines .....: 28.12 ------ ----- ----- ------ ------ ----- Max LOC ...............: 124 Max eLOC ..............: 107 Max lLOC ..............: 65 diff --git a/doxygen/modules.dox b/doxygen/modules.dox index a698478b..90b54dbb 100644 --- a/doxygen/modules.dox +++ b/doxygen/modules.dox @@ -21,7 +21,7 @@ QF is a portable, event-driven, real-time framework for execution of active obje @brief Software Tracing Instrumentation -QS is software tracing system that enables developers to monitor live QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. Please see QS Manual inside the QTools collection for more information. +QS is software tracing system that enables developers to monitor live QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. Please see QS Manual inside the QTools collection for more information. */ /*##########################################################################*/ diff --git a/doxygen/ports_native.dox b/doxygen/ports_native.dox index 95ac39b6..03c66113 100644 --- a/doxygen/ports_native.dox +++ b/doxygen/ports_native.dox @@ -85,7 +85,7 @@ The QP/C baseline code contains an example of MISRA-C compliance checking with P In order to execute the **lin.bat** file on your system, you might need to adjust the symbol `PC_LINT_DIR` at the top of the batch file, to the PC-Lint installation directory on your computer. You The `lint` subdirectory in each of the application folders contains also the `options.lnt` with the PC-Lint options specific to linting the application. There is also a choice of the compiler, whereas `options_gcc.lnt` are for the GCC-ARM and `options_iar.lnt` are for `IAR-ARM` compilers, respectively. These files specify the include directory for the specific embedded compiler used to compile the application, and you most likely need to adjust it for your system. -Running PC-Lint on embedded projects (such as the DPP example for ARM Cortex-M) requires option files for the specific compilers (`co-iar-arm.lnt` file for IAR ARM and `co-gnu-arm.lnt` file GNU ARM, respectively). These option files are provided in the QTools collection. The location of the QTools directory in your system is specified in the `options.lnt` file, and you most likely need to adjust it for your system. +Running PC-Lint on embedded projects (such as the DPP example for ARM Cortex-M) requires option files for the specific compilers (`co-iar-arm.lnt` file for IAR ARM and `co-gnu-arm.lnt` file GNU ARM, respectively). These option files are provided in the QTools collection. The location of the QTools directory in your system is specified in the `options.lnt` file, and you most likely need to adjust it for your system. @note The QTools collection is available for a separate download from https://sourceforge.net/projects/qpc/files/QTools. Quantum Leaps is committed to keep adding more and more PC-Lint option files for various embedded C/C++ cross-compilers in the QTools collection. @@ -124,7 +124,7 @@ The most important file for "linting" QP/C applications is the **qpc.lnt** optio At the same time, the **qpc.lnt** option file has been very carefully designed not to suppress any MISRA-C:2004 rule checking outside the very specific context of the QP/C API. In other words, the qpc.lnt option file still supports 100% of the MISRA-C:2004 rule checks that PC-Lint is capable of performing. @remarks -For example, for reasons explained in Section 5.10 of the "QP/C MISRA Compliance Matrix", QP/C extensively uses function-like macros, which deviates from the MISRA-C:2004 advisory rule 19.7 and which PC-Lint checks with the warning 961. However, instead of suppressing this warning globally (with the -e961 directive), the qpc.lnt option file suppresses warning 961 only for the specific QP function-like macros that are visible to the application level. So specifically, the qpc.lnt file contains directives `-estring(961, Q_TRAN, Q_SUPER, ...)`, which suppresses the warning only for the specified macros, but does not disable checking of any other macros in the application-level code. +For example, for reasons explained in Section 5.10 of the "QP/C MISRA Compliance Matrix", QP/C extensively uses function-like macros, which deviates from the MISRA-C:2004 advisory rule 19.7 and which PC-Lint checks with the warning 961. However, instead of suppressing this warning globally (with the -e961 directive), the qpc.lnt option file suppresses warning 961 only for the specific QP function-like macros that are visible to the application level. So specifically, the qpc.lnt file contains directives `-estring(961, Q_TRAN, Q_SUPER, ...)`, which suppresses the warning only for the specified macros, but does not disable checking of any other macros in the application-level code. @next{arm-cm} */ diff --git a/doxygen/ports_os.dox b/doxygen/ports_os.dox index fab72744..10aa7be0 100644 --- a/doxygen/ports_os.dox +++ b/doxygen/ports_os.dox @@ -1,62 +1,84 @@ /*##########################################################################*/ /*! @page ports_os Ports to Third-Party OS -- @subpage posix (Linux, embedded-Linux, BSD, etc.) -- @subpage win32 API (Windows) -- @subpage win32-qv (Windows with QV) +- @subpage posix-qv (single-threadedLinux, embedded-Linux, BSD, etc.) +- @subpage posix (multi-threaded Linux, embedded-Linux, BSD, etc.) +- @subpage win32-qv (single-threaded Windows, like the QV kernel) +- @subpage win32 API (multi-threaded Windows, Windows embedded) */ -/*##########################################################################*/ -/*! @page posix POSIX -

      The QP/C/C++ ports and examples for POSIX (e.g., Embedded Linux, BSD, VxWorks, QNX, etc.) are described in the Quantum Leaps Application Note QP and POSIX. +/*##########################################################################*/ +/*! @page posix-qv POSIX-QV + +

      The QP/C/C++ ports and examples for POSIX-QV (e.g., Embedded Linux, BSD, VxWorks, QNX, etc.) are described in the Quantum Leaps Application Note QP and POSIX.

      @htmlonly
      - +
      Application Note: QP and POSIX
      @endhtmlonly -The standard QP/C distribution contains the POSIX port and @ref exa_posix "Example Projects for POSIX". +The standard QP/C distribution contains the POSIX-QV port and @ref exa_os. + +*/ + +/*##########################################################################*/ +/*! @page posix POSIX + +

      The QP/C/C++ ports and examples for POSIX (e.g., Embedded Linux, BSD, VxWorks, QNX, etc.) are described in the Quantum Leaps Application Note QP and POSIX. +

      + +@htmlonly +
      + +
      +Application Note: QP and POSIX +
      +
      +@endhtmlonly + +The standard QP/C distribution contains the POSIX port and @ref exa_os. + +*/ + +/*##########################################################################*/ +/*! @page win32-qv Win32-QV (Windows with QV) + +

      The QP/C/C++ ports and examples for Windows with single-thread (like the @ref qv "QV cooperative kernel") are described in the Quantum Leaps Application Note QP and Win32 (Windows). +

      + +@htmlonly +
      + +
      +Application Note: QP and Win32 (Windows) +
      +
      +@endhtmlonly + +The standard QP/C distribution contains the Win32-QV port and @ref exa_os. */ /*##########################################################################*/ /*! @page win32 Win32 API (Windows) -

      The QP/C/C++ ports and examples for Windows (e.g., Windows Embedded, WindowsCE etc.) are described in the Quantum Leaps Application Note QP and Win32 (Windows). +

      The QP/C/C++ ports and examples for Windows (e.g., Windows Embedded, WindowsCE etc.) are described in the Quantum Leaps Application Note QP and Win32 (Windows).

      @htmlonly
      - +
      Application Note: QP and Win32 (Windows)
      @endhtmlonly -The standard QP/C distribution contains the Win32 (Windows) port and @ref exa_win32 "Example Projects for Win32 (Windows)". - -*/ -/*##########################################################################*/ -/*! @page win32-qv Win32-QV (Windows with QV) - -

      The QP/C/C++ ports and examples for Windows with single-thread (like the @ref qv "QV cooperative kernel") are described in the Quantum Leaps Application Note QP and Win32 (Windows). -

      - -@htmlonly -
      - -
      -Application Note: QP and Win32 (Windows) -
      -
      -@endhtmlonly - -The standard QP/C distribution contains the Win32-QV port and @ref exa_win32-qv "Example Projects for Win32-QV". +The standard QP/C distribution contains the Win32 (Windows) port and @ref exa_os. */ diff --git a/doxygen/ports_rtos.dox b/doxygen/ports_rtos.dox index f3b6aa21..e8b5db87 100644 --- a/doxygen/ports_rtos.dox +++ b/doxygen/ports_rtos.dox @@ -159,12 +159,12 @@ int main() { /*##########################################################################*/ /*! @page embos embOS -

      The QP/C/C++ ports and examples for embOS are described in the Quantum Leaps Application Note QP and embOS. +

      The QP/C/C++ ports and examples for embOS are described in the Quantum Leaps Application Note QP and embOS.

      @htmlonly
      - +
      Application Note: QP and embOS
      @@ -176,12 +176,12 @@ Application Note: QP and embOS /*##########################################################################*/ /*! @page threadx ThreadX -

      The QP/C/C++ ports and examples for ThreadX are described in the Quantum Leaps Application Note QP and ThreadX. +

      The QP/C/C++ ports and examples for ThreadX are described in the Quantum Leaps Application Note QP and ThreadX.

      @htmlonly
      - +
      Application Note: QP and ThreadX
      @@ -497,12 +497,12 @@ qpc @note Specifically, the QP source files qf_actq.c and qf_mem.c must **NOT** be included in the build, because this functionality is taken from uC/OS-II. -

      The QP/C/C++ ports and examples for uC/OS-II are described in the Quantum Leaps Application Note QP and uC/OS-II. +

      The QP/C/C++ ports and examples for uC/OS-II are described in the Quantum Leaps Application Note QP and uC/OS-II.

      @htmlonly
      - +
      Application Note: QP and uC/OS-II
      diff --git a/doxygen/struct.dox b/doxygen/struct.dox index 48256a14..b07d7094 100644 --- a/doxygen/struct.dox +++ b/doxygen/struct.dox @@ -29,7 +29,7 @@ The standard QP/C distribution contains many @ref exa "Example Projects", which ------------------------------------------------------------------------------ @section comp Components of QP/C -

      As shown in the diagram below, the QP/C framework has a layered structure. The Target hardware sits at the bottom. The Board Support Package (BSP) above it provides access to the board-specific features, such as the peripherals. The real-time kernel (@ref comp_qv "QV", @ref comp_qk "QK", @ref comp_qxk "QXK", or a conventional @ref ports_rtos "3rd-party RTOS") provides the foundation for multitasking, such as task scheduling, context-switching, and inter-task communication. Based on these services, the active object framework (@ref comp_qf "QF") supplies the event-driven infrastructure for executing active objects and ensuring thread-safe event-driven exchanges among them. Finally, the event-processor (@ref comp_qep "QEP") implements the [hierarchical state machine](https://state-machine.com/doc/concepts#HSM) semantics (based on UML statecharts). The top layer is the application-level code consisting of loosely-coupled [active objects](https://state-machine.com/doc/concepts#Active). +

      As shown in the diagram below, the QP/C framework has a layered structure. The Target hardware sits at the bottom. The Board Support Package (BSP) above it provides access to the board-specific features, such as the peripherals. The real-time kernel (@ref comp_qv "QV", @ref comp_qk "QK", @ref comp_qxk "QXK", or a conventional @ref ports_rtos "3rd-party RTOS") provides the foundation for multitasking, such as task scheduling, context-switching, and inter-task communication. Based on these services, the active object framework (@ref comp_qf "QF") supplies the event-driven infrastructure for executing active objects and ensuring thread-safe event-driven exchanges among them. Finally, the event-processor (@ref comp_qep "QEP") implements the [hierarchical state machine](https://www.state-machine.com/doc/concepts#HSM) semantics (based on UML statecharts). The top layer is the application-level code consisting of loosely-coupled [active objects](https://www.state-machine.com/doc/concepts#Active).

      @image html qp_components.jpg "Components of the QP Framework" diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/README.txt index b9e31e61..e3735312 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/README.txt +++ b/examples/arm-cm/blinky_efm32-slstk3401a/README.txt @@ -34,17 +34,3 @@ qspy -cCOM1 The actual COM port number might be different on your Windows machine. Please check the Device Manager to find the COM port number. - - -Win32 Emulations -================ -The sub-directorie win32 and win32-qv provide the emulations of the example -on Windows GUI (with regular Win32 threads and with cooperative QV scheduler, -respectively. These sub-directories contain the Makefiles for the MinGW -toolset and Visual Studio solution files (game-gui.sln) for Visual C++. - -The Win32 emulations use exactly the same code as the embedded board and -differ only in the Board Support Package (bsp.c). This example demonstrates -the "dual targeting" development approach, where most of the embedded code -is developed on the desktop machine (Windows), but is intended for a deeply -embedded target (EFM32-SLSTK3401A here). diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/Makefile b/examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/Makefile deleted file mode 100644 index 9d94515e..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/Makefile +++ /dev/null @@ -1,262 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Blinky console, Win32-QV, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := blinky - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qv - -# list of all source directories used by this project -VPATH = \ - . \ - .. - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - blinky.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/bsp.c b/examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/bsp.c deleted file mode 100644 index bc5e2749..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/win32-qv/bsp.c +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example, Win32 API -* Last updated for version 5.6.4 -* Last updated on 2016-05-08 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -/*..........................................................................*/ -void BSP_init() { - printf("Simple Blinky example\nQP version: %s\n" - "Press ESC to quit...\n", - QP_VERSION_STR); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - printf("LED OFF\n"); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - printf("LED ON\n"); -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - switch (_getch()) { - case '\033': { /* ESC pressed? */ - QF_stop(); - break; - } - } - } -} - -/*--------------------------------------------------------------------------*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} - diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/win32/Makefile b/examples/arm-cm/blinky_efm32-slstk3401a/win32/Makefile deleted file mode 100644 index bb06f900..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/win32/Makefile +++ /dev/null @@ -1,253 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Blinky console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := blinky - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - .. - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - blinky.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/win32/bsp.c b/examples/arm-cm/blinky_efm32-slstk3401a/win32/bsp.c deleted file mode 100644 index 1732b4a4..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/win32/bsp.c +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example, Win32 API -* Last updated for version 5.6.5 -* Last updated on 2016-05-08 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -/*..........................................................................*/ -void BSP_init() { - printf("Simple Blinky example\nQP version: %s\n" - "Press ESC to quit...\n", - QP_VERSION_STR); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - printf("LED OFF\n"); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - printf("LED ON\n"); -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - switch (_getch()) { - case '\033': { /* ESC pressed? */ - QF_stop(); - break; - } - } - } -} - -/*--------------------------------------------------------------------------*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} - diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/README.txt b/examples/arm-cm/blinky_ek-tm4c123gxl/README.txt index a6c95b99..edceefd3 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/README.txt +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/README.txt @@ -35,16 +35,3 @@ qspy -cCOM1 The actual COM port number might be different on your Windows machine. Please check the Device Manager to find the COM port number. - -Win32 Emulations -================ -The sub-directorie win32 and win32-qv provide the emulations of the example -on Windows GUI (with regular Win32 threads and with cooperative QV scheduler, -respectively. These sub-directories contain the Makefiles for the MinGW -toolset and Visual Studio solution files (game-gui.sln) for Visual C++. - -The Win32 emulations use exactly the same code as the embedded board and -differ only in the Board Support Package (bsp.c). This example demonstrates -the "dual targeting" development approach, where most of the embedded code -is developed on the desktop machine (Windows), but is intended for a deeply -embedded target (EK-TM4C123GXL here). diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/Makefile b/examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/Makefile deleted file mode 100644 index 9d94515e..00000000 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/Makefile +++ /dev/null @@ -1,262 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Blinky console, Win32-QV, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := blinky - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qv - -# list of all source directories used by this project -VPATH = \ - . \ - .. - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - blinky.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/bsp.c b/examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/bsp.c deleted file mode 100644 index 378c31e6..00000000 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/win32-qv/bsp.c +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example, Win32 API -* Last updated for version 5.6.5 -* Last updated on 2016-06-05 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -/*..........................................................................*/ -void BSP_init() { - printf("Simple Blinky example\nQP version: %s\n" - "Press ESC to quit...\n", - QP_VERSION_STR); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - printf("LED OFF\n"); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - printf("LED ON\n"); -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - switch (_getch()) { - case '\33': { /* ESC pressed? */ - QF_stop(); - break; - } - } - } -} - -/*--------------------------------------------------------------------------*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} - diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/win32/Makefile b/examples/arm-cm/blinky_ek-tm4c123gxl/win32/Makefile deleted file mode 100644 index bb06f900..00000000 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/win32/Makefile +++ /dev/null @@ -1,253 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Blinky console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := blinky - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - .. - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - blinky.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/win32/bsp.c b/examples/arm-cm/blinky_ek-tm4c123gxl/win32/bsp.c deleted file mode 100644 index acd7584a..00000000 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/win32/bsp.c +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example, Win32 API -* Last updated for version 5.6.5 -* Last updated on 2016-06-05 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -/*..........................................................................*/ -void BSP_init() { - printf("Simple Blinky example\nQP version: %s\n" - "Press ESC to quit...\n", - QP_VERSION_STR); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - printf("LED OFF\n"); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - printf("LED ON\n"); -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - switch (_getch()) { - case '\033': { /* ESC pressed? */ - QF_stop(); - break; - } - } - } -} - -/*--------------------------------------------------------------------------*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} - diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/README.txt b/examples/arm-cm/dpp_efm32-slstk3401a/README.txt index 6273f564..d9b68f62 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/README.txt +++ b/examples/arm-cm/dpp_efm32-slstk3401a/README.txt @@ -30,21 +30,49 @@ The output is generated at 115200 baud rate. Here is an example invocation of the QSPY host application to receive the QS data from EFM32-SLSTK3401A: -qspy -cCOM1 +qspy -u -c COM1 (Windows) -The actual COM port number might be different on your Windows machine. +qspy -u -c /dev/ttyS1 (POSIX) + +The actual serial-port number might be different on your workstation. Please check the Device Manager to find the COM port number. -Win32 Emulations -================ -The sub-directorie win32 and win32-qv provide the emulations of the example -on Windows GUI (with regular Win32 threads and with cooperative QV scheduler, -respectively. These sub-directories contain the Makefiles for the MinGW -toolset and Visual Studio solution files (game-gui.sln) for Visual C++. +Win32-GUI Emulation +=================== +The sub-directory "win32-gui" provides the emulation of the example +on Windows GUI, either single-threaded (win32-qv) or multithreded (win32). +This sub-directory contains the Makefile for the GNU-GCC toolset (MinGW) +and Visual Studio solution file (dpp-gui.sln) for Visual C++. -The Win32 emulations use exactly the same code as the embedded board and -differ only in the Board Support Package (bsp.c). This example demonstrates -the "dual targeting" development approach, where most of the embedded code -is developed on the desktop machine (Windows), but is intended for a deeply +The Win32-GUI emulation is based on the QWin™ GUI Prototyping Toolkit, see: + +https://www.state-machine.com/qtools/qwin.html + +The emulation uses exactly the same code as the embedded board and differs +only in the Board Support Package (bsp.c). This example demonstrates the +"dual targeting" development approach, where most of the embedded code is +developed on the workstation (Windows), but is intended for a deeply embedded target (EFM32-SLSTK3401A here). + + +QS Software Tracing Instrumentation +----------------------------------- +The "win32-gui" emulation also supports the "Spy" build configuration, +in which case it attempts to connect to the QSPY host application via +a TCP/IP socket. This requires launching the QSPY host application with +the command-line parameter -t + +qspy -u -t + + +QSpyView Visualization +====================== +The sub-directory "qspyview" provides the QSpyView Visualization +example for the DPP application, see: + +https://www.state-machine.com/qtools/qspyview.html + +This QSpyView Visualization works with all versions of the software +running in the Spy build configuration, including the code for the +EFM32-SLSTK3401A board and the Win32-GUI emulation. diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c index fccdf53d..7c071ba3 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c @@ -60,16 +60,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c index fccdf53d..7c071ba3 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c @@ -60,16 +60,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c index a05aed1c..06604e7b 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c @@ -69,16 +69,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Makefile b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Makefile similarity index 59% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Makefile rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Makefile index 55b0facf..77a688bc 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Makefile +++ b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C, DPP-GUI, Win32-QV, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 +# Product: Makefile for QP/C, Win32-GUI, GNU GCC +# Last updated for version 6.3.6 +# Last updated on 2018-10-15 # -# 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 ############################################################################## # examples of invoking this Makefile: @@ -44,45 +44,38 @@ # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ # #----------------------------------------------------------------------------- # project name # -PROJECT := dpp-gui +PROJECT := dpp-gui #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qv - # list of all source directories used by this project -VPATH = \ - . \ +VPATH := . \ .. # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include +INCLUDES := -I. \ + -I.. # list of resource include directories needed by this project RCINCLUDES = \ -IRes +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif #----------------------------------------------------------------------------- -# files +# project files: # # C source files... @@ -93,7 +86,7 @@ C_SRCS := \ table.c # C++ source files... -CPP_SRCS := +CPP_SRCS := # Resource files... RC_SRCS := \ @@ -106,68 +99,111 @@ LIBS := # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API DEFINES := -DQP_API_VERSION=9999 +ifeq (,$(CONF)) + CONF := dbg +endif + #----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp + +else + +$(error GUI build currently not supported on POSIX) + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: # # NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH # CC := gcc CPP := g++ LINK := gcc # for C programs #LINK := g++ # for C++ programs + +# NOTE: +# This Makefile assumes that the windres utility is available on the PATH +# (windres is available in the QTools collection for Windows) +# RC := windres -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif #----------------------------------------------------------------------------- -# build options for various configurations -# +# build configurations... ifeq (rel, $(CONF)) # Release configuration .................................. -BIN_DIR := rel +BIN_DIR := build_rel -CFLAGS = -ffunction-sections -fdata-sections \ +CFLAGS = -c -ffunction-sections -fdata-sections \ -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG -CPPFLAGS = -ffunction-sections -fdata-sections \ +CPPFLAGS = -c -ffunction-sections -fdata-sections \ -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ -BIN_DIR := spy +BIN_DIR := build_spy LIBS += -lwsock32 -CFLAGS = -g -ffunction-sections -fdata-sections \ +CFLAGS = -c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY -CPPFLAGS = -g -ffunction-sections -fdata-sections \ +CPPFLAGS =-c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... -BIN_DIR := dbg +BIN_DIR := build -CFLAGS = -g -ffunction-sections -fdata-sections \ +CFLAGS = -c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) -CPPFLAGS = -g -ffunction-sections -fdata-sections \ +CPPFLAGS = -c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) endif # ..................................................................... -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections +LINKFLAGS := # is it a GUI application (any GUI resources provided?) ... ifneq (,$(RC_SRCS)) @@ -176,22 +212,15 @@ DEFINES += -DQWIN_GUI endif #----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) # create $(BIN_DIR) if it does not exist @@ -204,13 +233,9 @@ endif # all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.cpp @@ -220,10 +245,10 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.rc $(RC) $(RCINCLUDES) -i $< -o $@ @@ -235,23 +260,26 @@ ifneq ($(MAKECMDGOALS),clean) endif endif -.PHONY : clean -clean: +.PHONY : clean show + +clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo RC_SRCS = $(RC_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/BTN_DWN.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/BTN_DWN.bmp rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/BTN_UP.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/BTN_UP.bmp rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/eating.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/eating.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/eating.bmp rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/eating.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/hungry.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/hungry.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/hungry.bmp rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/hungry.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/qp.ico b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/qp.ico similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/qp.ico rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/qp.ico diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/thinking.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/thinking.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/Res/thinking.bmp rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/thinking.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/bsp.c b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/bsp.c similarity index 59% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/bsp.c rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/bsp.c index 927bab77..19186a55 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/bsp.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: DPP example, Win32-GUI -* Last updated for version 5.9.0 -* Last updated on 2017-04-14 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 "qpc.h" @@ -41,13 +41,6 @@ #include /* for _snprintf_s() */ #include -#ifdef Q_SPY - #define WIN32_LEAN_AND_MEAN - #include /* Win32 API for multithreading */ - #include /* for Windows network facilities */ -#endif - - Q_DEFINE_THIS_FILE /* local variables ---------------------------------------------------------*/ @@ -62,10 +55,8 @@ static unsigned l_rnd; /* random seed */ #ifdef Q_SPY enum { - PHILO_STAT = QS_USER, - COMMAND_STAT + PHILO_STAT = QS_USER }; - static SOCKET l_sock = INVALID_SOCKET; static uint8_t const l_clock_tick = 0U; #endif @@ -217,26 +208,29 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ } /*..........................................................................*/ void QF_onCleanup(void) { } /*..........................................................................*/ void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ + + QS_RX_INPUT(); /* handle the QS-RX input */ + QS_OUTPUT(); /* handle the QS output */ } /*..........................................................................*/ void Q_onAssert(char const * const module, int_t loc) { char message[80]; QF_stop(); /* stop ticking */ + QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ SNPRINTF_S(message, Q_DIM(message) - 1, "Assertion failed in module %s location %d", module, loc); MessageBox(l_hWnd, message, "!!! ASSERTION !!!", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - PostQuitMessage(-1); } @@ -249,20 +243,18 @@ void BSP_init(void) { "QS_INIT() Error", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); } - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ + + /* send the QS dictionaries... */ + QS_OBJ_DICTIONARY(&l_clock_tick); QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + + /* setup the QS filters... */ + QS_FILTER_ON(QS_ALL_RECORDS); + QS_FILTER_OFF(QS_QF_TICK); } /*..........................................................................*/ void BSP_terminate(int16_t result) { - (void)result; -#ifdef Q_SPY - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } -#endif - QF_stop(); /* stop the main QF application and the ticker thread */ + QF_stop(); /* stop the main QF application */ /* cleanup all QWIN resources... */ OwnerDrawnButton_xtor(&l_pauseBtn); /* cleanup the l_pauseBtn resources */ @@ -315,201 +307,22 @@ void BSP_randomSeed(uint32_t seed) { /*--------------------------------------------------------------------------*/ #ifdef Q_SPY /* define QS callbacks */ -#include - -/* -* In this demo, the QS software tracing output is sent out of the application -* through a TCP/IP socket. This requires the QSPY host application to -* be started first to open a server socket (qspy -t ...) to wait for the -* incoming TCP/IP connection from the DPP demo. -* -* In an embedded target, the QS software tracing output can be sent out -* using any method available, such as a UART. This would require changing -* the implementation of the functions in this section, but the rest of the -* application code does not "know" (and should not care) how the QS ouptut -* is actually performed. In other words, the rest of the application does NOT -* need to change in any way to produce QS output. -*/ - -/*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; - while (l_sock != INVALID_SOCKET) { - uint16_t nBytes; - uint8_t const *block; - - /* try to receive bytes from the QS socket... */ - nBytes = QS_rxGetNfree(); - if (nBytes > 0U) { - uint8_t buf[64]; - int status; - - if (nBytes > sizeof(buf)) { - nBytes = sizeof(buf); - } - status = recv(l_sock, (char *)buf, (int)nBytes, 0); - if (status != SOCKET_ERROR) { - uint16_t i; - nBytes = (uint16_t)status; - for (i = 0U; i < nBytes; ++i) { - QS_RX_PUT(buf[i]); - } - } - } - QS_rxParse(); /* parse all the received bytes */ - - nBytes = 1024U; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - } - Sleep(20); /* sleep for xx milliseconds */ - } - return (DWORD)0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[1024]; /* buffer for QS output */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static WSADATA wsaData; - char hostName[64]; - char const *src; - char *dst; - USHORT port = 6601; /* default QSPY server port */ - ULONG ioctl_opt = 1; - struct sockaddr_in sockAddr; - struct hostent *server; - - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets */ - if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { - printf("Windows Sockets cannot be initialized."); - return (uint8_t)0; - } - - src = (arg != (void const *)0) - ? (char const *)arg - : "localhost"; - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName)])) - { - *dst++ = *src++; - } - *dst = '\0'; - if (*src == ':') { - port = (USHORT)strtoul(src + 1, NULL, 10); - } - - l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ - if (l_sock == INVALID_SOCKET){ - printf("Socket cannot be created; error 0x%08X\n", - WSAGetLastError()); - return (uint8_t)0; /* failure */ - } - - server = gethostbyname(hostName); - if (server == NULL) { - printf("QSpy host name %s cannot be resolved; error 0x%08X\n", - hostName, WSAGetLastError()); - return (uint8_t)0; - } - - memset(&sockAddr, 0, sizeof(sockAddr)); - sockAddr.sin_family = AF_INET; - memcpy(&sockAddr.sin_addr, server->h_addr, server->h_length); - sockAddr.sin_port = htons(port); - if (connect(l_sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) - == SOCKET_ERROR) - { - printf("Cannot connect to the QSPY server; error 0x%08X\n", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* Set the socket to non-blocking mode. */ - if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { - printf("Socket configuration failed.\n" - "Windows socket error 0x%08X.", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* set up 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PHILO_STAT); - QS_FILTER_ON(COMMAND_STAT); - - /* return the status of creating the idle thread */ - return (CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0) ? (uint8_t)1 : (uint8_t)0; -} -/*..........................................................................*/ -void QS_onCleanup(void) { - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - WSACleanup(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes = 1000; - uint8_t const *block; - while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - nBytes = 1000; - } -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ -void QS_onReset(void) { - //TBD -} -/*..........................................................................*/ -/*! callback function to execute a uesr command (to be implemented in BSP) */ +/*! callback function to execute user commands */ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + /* unused parameters */ (void)param1; (void)param2; (void)param3; - QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_onAssert("command", 10); - } } #endif /* Q_SPY */ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.rc b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.rc similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.rc rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.rc diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.sln b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.sln similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.sln rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.sln diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.vcxproj b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj similarity index 87% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.vcxproj rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj index b5b0f94f..f11ac07c 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.vcxproj +++ b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj @@ -102,10 +102,10 @@ 0x0409 - %(AdditionalDependencies) + qp.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe true - %(AdditionalLibraryDirectories) + ../../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) Windows false @@ -155,10 +155,10 @@ 0x0409 - wsock32.lib;%(AdditionalDependencies) + qp.lib;wsock32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe true - %(AdditionalLibraryDirectories) + ../../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true false @@ -214,10 +214,10 @@ 0x0409 - %(AdditionalDependencies) + qp.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe true - %(AdditionalLibraryDirectories) + ../../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true false @@ -267,22 +267,6 @@ - - - false - true - true - - - true - true - - - true - true - false - - diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.vcxproj.filters b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj.filters similarity index 76% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.vcxproj.filters rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj.filters index c559571c..ba96a142 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/dpp-gui.vcxproj.filters +++ b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj.filters @@ -39,18 +39,10 @@ {c8d4d732-dcf8-4466-ad8e-3f15ab6fe204} - - {fc58f96a-b3df-47d3-9a58-3283c0cf1a5c} - Res - - - - - \ No newline at end of file diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/main.c similarity index 93% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/main.c rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/main.c index e580e69a..e3df66dc 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/main.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/main.c @@ -59,16 +59,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/resource.h b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/resource.h similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-qv/resource.h rename to examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/resource.h diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Makefile b/examples/arm-cm/dpp_efm32-slstk3401a/win32/Makefile deleted file mode 100644 index 49f3ff02..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Makefile +++ /dev/null @@ -1,257 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, DPP-GUI, Win32, MinGW -# Last updated for version 5.6.4 -# Last updated on 2016-05-03 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := dpp-gui - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - .. - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := \ - dpp-gui.rc - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -LIBS += -lwsock32 - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/BTN_DWN.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/BTN_DWN.bmp deleted file mode 100644 index 029e063b654a9315835e5090a91cbbcdc80cd6a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5994 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 Hz%l#}`#dmn diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/BTN_UP.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/BTN_UP.bmp deleted file mode 100644 index 28faefc9a7e374861477162e091e7a9d1071103b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5994 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 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/eating.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/eating.bmp deleted file mode 100644 index d32ce36dadc0437ca26c35c8536ba65fb1988c34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17814 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 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/thinking.bmp b/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/thinking.bmp deleted file mode 100644 index a1dc4bc15e1f073a7fa0fe35b7e64af15365f3a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17814 zcmdVh+pir}9S89G4;Y?Isd&L#3nspZyy=5Uyc?$GrJ|=gs@N`%k?y{$&Gx&R71s?FV;! zaH4tH3+EO+f2P$M%@6N6e#!cuTz24m9MO62*uxi(jJ|){Gm9EcmtlUR`H@5CFJ8HB z&-i%78~*wCzy5g3mQRe_e9=9Re&}y+PI*y!qmE?{pTBs^lb2sNvUm5dD;9KX?C!g_ zZQf8lr`z4fxBln@yACF30U*5lUIAp$#AImka%2<{Y$=Si_i6JBb{)E9?7nV`r}2Lu zJMz8Nt3P_j{pN>7+AD<4#3Z`CXWy$x`i+}!L7((gw+;%gU$d&)-Rkj)XT~uu;7vd# zCIJcD{NWS!rrAmCPuXX-XDl=Gx7#1BeoMUj^v+)_9=Y+7ho1m2zAnlMwtntgqbUF8 zx&PH!=k)8Zue#}mIy1|2&YnJX_2N$kvgbrvAJgYAS^Dk=evZ*vxSI%);|@a2-~KGV zyz#~x<;BY*4?XnY(xul?mLS{IWbexsxB1sj94}9<7$GeccdKtt9JZMZPl*X2LrdsKZxp`hFde#$v)>ZPI)0{NT|S2iD)T_|^?$K~D?DGbiB*V7Y_E3-8%dN2I+D zWGucA$Q;~*V}t8&giP2TSig?(8~`%BG`*&k_PXOQy+n}*hD?|b{^<{iQv-L{YI4Fm z^b0wN^v=fTzjhs>)qFcHvpIFNzOW!#;Y(p~;LHD`uqp_4r88>r8h!K*JCxLfK)iz7lZ*O zGr3p>1##`5w(vHZ!Z4B$#6aME;5@@67_P|$(2g8An%|g95)OX8v4m`Ce%j3Skynr( zA%}pZ&C^yVOCF^RDdwaCdEdkUR-`;YVPenCb3py7NzXMaCUACN`Q}o2K?hyVG?&=R z7F%~4%?0Dfgj*K$AYPMjEbF*_O}ylJ7KAy!!xc-H6w}7YXxZy?Ck1ASzxd9u3%3|j zV1=6Om}lu`e!Q>(n#q7KVv+drs>YRKz53R>3JD_=tkb1C{`{`bTnlf+m9#s; zH%`=ptz*g#hfG;k!WzeSvCP%}8gURrDdWt4d&@w@{`Gxm!yKc75H z%&B2Zo+l<5YC0Q=JO|DP&Q45{UeH)(=mP3YyYUnqLfn$EIEn;05s5Kk_#1Iuf9FQ@ zG=dZ+%UL)zlwkyB*-RzWR4<<$vr#QvS&=9DAR#Ec#5+L-(;&*A339R9oHZ&T0@+Zp z1e`&8-yctDCJ-Ui2*k-&EaGh`^~!ZF zgM@$lN{E&$TfS=ZuWsLcbluY@?tJoCzTLL%S$CtF=OKq2bNrZEqH1KfUCrD$B4aUv z2P>V)aMaKiqZ>`sh&-i$(G#&Y;y`@7eaC(PgXLy??Dzjd4FbU0$51>jOTsO} zj?Emdij_r%s2!ymqwyj(q8NCJ`$n7*jEoA0a4o{b%C)~cREAj?K@gMyxkbRXxwGtS zMv?{i95Gj7SGK{5l3^VHbub-REM~9BC$P9y2WbKhGL1&MB-J|1!d#i?gkAivTm~1& zf-C%Gm*U=FCzCcAbry4>?k33zY3!IrDhP1Ui*|y^)K|wOX;(AdksWi&TqJZ_G*dwV zvm+S(1$K-!hoIJEG!_e7L(MQcf=1IiDJ+?3L_OD6nvfLmKETQsY_he_%$u-m442b1 zTr04$+a(q=Txgi^GFh_GSxbIr)6@S8;6-=zQY{^wp zLb3Fm_~J4Vu$Zc@-**x>2_%?Wa7kT!ZW(DDi6&a0(&BIC=-C9}G~r<-lpW^E9p_Qg zFI8*OsKFS+r_aeWeA>kAMGjCCYS~(ofT8zY(SdSHgmo)cfeV9={2u3`?Z~FyzUCEK^8VAF$OKQ zWW9MVt`<^2q?sacK1d7l40TSVqh(h5NXHi3-(1x_%J5~%DvE4%%#VmGM@+~y0F4Vv z#9a~!aihcvSREV;u}YS9akaq*Whq1OM?6vXB?*z{^?)VP>fv)z_bB5vVm~6x=$`Nz z5QtKP(at3T7j1gXEhRgK4vJKqT($mQIxEJAye7}lXyZPDeD;ckCUbv&JHCDP2OXzk zgm_YNXNRnifFa6iU|beIK&>p$?c^F9G7umi4kd2zLu8&+JK@D#^t|v-IHrp-$^v1x z$K#d!1~_yIt11g-EQQ7DAMB_hmcHgoUl@|S$u`t)L%DTi6kA*N zCySbx9qL(gtBxkE5amG zj}mk9PR*e6_c=U$$nO?klEhNvj^9a=0fwtvvZLlK;EaLg6qs%P8YI%(Q~htB@;jW~ zJ{DsuJ*8jejE3~00CUZ`_{C^OJKuOQNkr90P#J2v%zTMGrg!s$t;W>w9e5NEKpob{ z2A7CBl&p6)xE0|OCYGBtKbWQ*H#_tjO^-V?A8d!y`xJ9Tx$NhyFhisfp=GDup>UB! zTtPiMwra5MW~UD-meafQ!B!*2tQHfBiEL>BQF1FCxYiS9nlMawQAspN6Pc8d&Gi({ zgra^YlV?V6FpkW`Q%sYno)%9JL#L9$n(S3izcv%Ns@LRP;_wlQ;|^WdUz2ceLs=(*cR@7T z`4>r6RbUCLUpEYQMIZ`{A?V6ZvFo5_kWD7W9(0PNas~3x8s{>RWfKZ|Ld}+JPdzYt zivn3f0V$nzJfY@;p^9UWs<#ibaV|qPLIG)_7)cH#p%5>HGl=Zlp7?7}V8+jKJt@y+ zmK`w+PjRv%v~Gh8EFfZjF}Czyl@-%bK*wb~k@4ApZ#ERcC<4yH`!)reCqje+5yiy5 zSkd)88_ADf_=8My$wQ&~mtW*<+81xDE#o`*@X}cfb*bd_wlK&8kR42nX442Wp0ZBx I);#e2KXW%voB#j- diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/bsp.c b/examples/arm-cm/dpp_efm32-slstk3401a/win32/bsp.c deleted file mode 100644 index eb21c17c..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/bsp.c +++ /dev/null @@ -1,516 +0,0 @@ -/***************************************************************************** -* Product: DPP example, Win32-GUI -* Last updated for version 5.9.0 -* Last updated on 2017-04-15 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include "qwin_gui.h" /* QWIN GUI */ -#include "resource.h" /* GUI resource IDs generated by the resource editior */ - -#include /* for _snprintf_s() */ -#include - -#ifdef Q_SPY - #define WIN32_LEAN_AND_MEAN - #include /* Win32 API for multithreading */ - #include /* for Windows network facilities */ -#endif - - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static HINSTANCE l_hInst; /* this application instance */ -static HWND l_hWnd; /* main window handle */ -static LPSTR l_cmdLine; /* the command line string */ - -static SegmentDisplay l_philos; /* SegmentDisplay to show Philo status */ -static OwnerDrawnButton l_pauseBtn; /* owner-drawn button */ - -static unsigned l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER, - COMMAND_STAT - }; - static SOCKET l_sock = INVALID_SOCKET; - static uint8_t const l_clock_tick = 0U; -#endif - -/* Local functions ---------------------------------------------------------*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam); - -/*..........................................................................*/ -/* thread function for running the application main_gui() */ -static DWORD WINAPI appThread(LPVOID par) { - (void)par; /* unused parameter */ - return (DWORD)main_gui(); /* run the QF application */ -} - -/*--------------------------------------------------------------------------*/ -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, - LPSTR cmdLine, int iCmdShow) -{ - HWND hWnd; - MSG msg; - - (void)hPrevInst; /* unused parameter */ - - l_hInst = hInst; /* save the application instance */ - l_cmdLine = cmdLine; /* save the command line string */ - - //AllocConsole(); - - /* create the main custom dialog window */ - hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL, - &WndProc, "QP_APP"); - ShowWindow(hWnd, iCmdShow); /* show the main window */ - - /* enter the message loop... */ - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - //FreeConsole(); - BSP_terminate(0); - - return msg.wParam; -} - -/*..........................................................................*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam) -{ - switch (iMsg) { - - /* Perform initialization upon cration of the main dialog window - * NOTE: Any child-windows are NOT created yet at this time, so - * the GetDlgItem() function can't be used (it will return NULL). - */ - case WM_CREATE: { - l_hWnd = hWnd; /* save the window handle */ - - /* initialize the owner-drawn buttons... - * NOTE: must be done *before* the first drawing of the buttons, - * so WM_INITDIALOG is too late. - */ - OwnerDrawnButton_init(&l_pauseBtn, IDC_PAUSE, - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), - LoadCursor(NULL, IDC_HAND)); - return 0; - } - - /* Perform initialization after all child windows have been created */ - case WM_INITDIALOG: { - - SegmentDisplay_init(&l_philos, - N_PHILO, /* N_PHILO "segments" for the Philos */ - 3U); /* 3 bitmaps (for thinking/hungry/eating) */ - SegmentDisplay_initSegment(&l_philos, 0U, IDC_PHILO_0); - SegmentDisplay_initSegment(&l_philos, 1U, IDC_PHILO_1); - SegmentDisplay_initSegment(&l_philos, 2U, IDC_PHILO_2); - SegmentDisplay_initSegment(&l_philos, 3U, IDC_PHILO_3); - SegmentDisplay_initSegment(&l_philos, 4U, IDC_PHILO_4); - SegmentDisplay_initBitmap(&l_philos, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_THINKING))); - SegmentDisplay_initBitmap(&l_philos, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_HUNGRY))); - SegmentDisplay_initBitmap(&l_philos, - 2U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_EATING))); - - /* --> QP: spawn the application thread to run main_gui() */ - Q_ALLEGE(CreateThread(NULL, 0, &appThread, NULL, 0, NULL) - != (HANDLE)0); - return 0; - } - - case WM_DESTROY: { - PostQuitMessage(0); - return 0; - } - - /* commands from regular buttons and menus... */ - case WM_COMMAND: { - SetFocus(hWnd); - switch (wParam) { - case IDOK: - case IDCANCEL: { - PostQuitMessage(0); - break; - } - } - return 0; - } - - /* owner-drawn buttons... */ - case WM_DRAWITEM: { - LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam; - switch (pdis->CtlID) { - case IDC_PAUSE: { /* PAUSE owner-drawn button */ - switch (OwnerDrawnButton_draw(&l_pauseBtn,pdis)) { - case BTN_DEPRESSED: { - static QEvt const pe = { PAUSE_SIG, 0U, 0U }; - QACTIVE_POST(AO_Table, &pe, (void *)0); - break; - } - case BTN_RELEASED: { - static QEvt const se = { SERVE_SIG, 0U, 0U }; - QACTIVE_POST(AO_Table, &se, (void *)0); - break; - } - default: { - break; - } - } - break; - } - } - return 0; - } - - /* mouse input... */ - case WM_MOUSEWHEEL: { - return 0; - } - - /* keyboard input... */ - case WM_KEYDOWN: { - return 0; - } - } - return DefWindowProc(hWnd, iMsg, wParam, lParam) ; -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ -} - -/*..........................................................................*/ -void Q_onAssert(char const * const module, int_t loc) { - char message[80]; - QF_stop(); /* stop ticking */ - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - SNPRINTF_S(message, Q_DIM(message) - 1, - "Assertion failed in module %s location %d", module, loc); - MessageBox(l_hWnd, message, "!!! ASSERTION !!!", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - - PostQuitMessage(-1); -} - -/*..........................................................................*/ -void BSP_init(void) { - if (QS_INIT(l_cmdLine) == (uint8_t)0) { /* QS initialization failed? */ - MessageBox(l_hWnd, - "Cannot connect to QSPY via TCP/IP\n" - "Please make sure that 'qspy -t' is running", - "QS_INIT() Error", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - } - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -#ifdef Q_SPY - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } -#endif - QF_stop(); /* stop the main QF application and the ticker thread */ - - /* cleanup all QWIN resources... */ - OwnerDrawnButton_xtor(&l_pauseBtn); /* cleanup the l_pauseBtn resources */ - SegmentDisplay_xtor(&l_philos); /* cleanup the l_philos resources */ - - /* end the main dialog */ - EndDialog(l_hWnd, result); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - UINT bitmapNum = 0; - - Q_REQUIRE(n < N_PHILO); - - switch (stat[0]) { - case 't': bitmapNum = 0U; break; - case 'h': bitmapNum = 1U; break; - case 'e': bitmapNum = 2U; break; - default: Q_ERROR(); break; - } - /* set the "segment" # n to the bitmap # 'bitmapNum' */ - SegmentDisplay_setSegment(&l_philos, (UINT)n, bitmapNum); - - 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) { - char buf[16]; - LoadString(l_hInst, - (paused != 0U) ? IDS_PAUSED : IDS_RUNNING, buf, Q_DIM(buf)); - SetDlgItemText(l_hWnd, IDC_PAUSED, buf); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -#include - -/* -* In this demo, the QS software tracing output is sent out of the application -* through a TCP/IP socket. This requires the QSPY host application to -* be started first to open a server socket (qspy -t ...) to wait for the -* incoming TCP/IP connection from the DPP demo. -* -* In an embedded target, the QS software tracing output can be sent out -* using any method available, such as a UART. This would require changing -* the implementation of the functions in this section, but the rest of the -* application code does not "know" (and should not care) how the QS ouptut -* is actually performed. In other words, the rest of the application does NOT -* need to change in any way to produce QS output. -*/ - -/*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; - while (l_sock != INVALID_SOCKET) { - uint16_t nBytes; - uint8_t const *block; - - /* try to receive bytes from the QS socket... */ - nBytes = QS_rxGetNfree(); - if (nBytes > 0U) { - uint8_t buf[64]; - int status; - - if (nBytes > sizeof(buf)) { - nBytes = sizeof(buf); - } - status = recv(l_sock, (char *)buf, (int)nBytes, 0); - if (status != SOCKET_ERROR) { - uint16_t i; - nBytes = (uint16_t)status; - for (i = 0U; i < nBytes; ++i) { - QS_RX_PUT(buf[i]); - } - } - } - QS_rxParse(); /* parse all the received bytes */ - - nBytes = 1024U; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - } - Sleep(20); /* sleep for xx milliseconds */ - } - return (DWORD)0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[1024]; /* buffer for QS output */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static WSADATA wsaData; - char hostName[64]; - char const *src; - char *dst; - USHORT port = 6601; /* default QSPY server port */ - ULONG ioctl_opt = 1; - struct sockaddr_in sockAddr; - struct hostent *server; - - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets */ - if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { - printf("Windows Sockets cannot be initialized."); - return (uint8_t)0; - } - - src = (arg != (void const *)0) - ? (char const *)arg - : "localhost"; - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName)])) - { - *dst++ = *src++; - } - *dst = '\0'; - if (*src == ':') { - port = (USHORT)strtoul(src + 1, NULL, 10); - } - - l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ - if (l_sock == INVALID_SOCKET){ - printf("Socket cannot be created; error 0x%08X\n", - WSAGetLastError()); - return (uint8_t)0; /* failure */ - } - - server = gethostbyname(hostName); - if (server == NULL) { - printf("QSpy host name %s cannot be resolved; error 0x%08X\n", - hostName, WSAGetLastError()); - return (uint8_t)0; - } - - memset(&sockAddr, 0, sizeof(sockAddr)); - sockAddr.sin_family = AF_INET; - memcpy(&sockAddr.sin_addr, server->h_addr, server->h_length); - sockAddr.sin_port = htons(port); - if (connect(l_sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) - == SOCKET_ERROR) - { - printf("Cannot connect to the QSPY server; error 0x%08X\n", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* Set the socket to non-blocking mode. */ - if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { - printf("Socket configuration failed.\n" - "Windows socket error 0x%08X.", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* set up 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PHILO_STAT); - QS_FILTER_ON(COMMAND_STAT); - - /* return the status of creating the idle thread */ - return (CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0) ? (uint8_t)1 : (uint8_t)0; -} -/*..........................................................................*/ -void QS_onCleanup(void) { - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - WSACleanup(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes = 1000; - uint8_t const *block; - while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - nBytes = 1000; - } -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ -void QS_onReset(void) { - //TBD -} -/*..........................................................................*/ -/*! callback function to execute a uesr command (to be implemented in BSP) */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_onAssert("command", 10); - } -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.rc b/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.rc deleted file mode 100644 index a45ad534..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.rc +++ /dev/null @@ -1,77 +0,0 @@ -// Generated by ResEdit 1.6.6 -// Copyright (C) 2006-2015 -// http://www.resedit.net - -#include -#include -#include -#include "resource.h" - - - - -// -// Bitmap resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_BTN_DWN BITMAP "Res\\BTN_DWN.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_BTN_UP BITMAP "Res\\BTN_UP.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_EATING BITMAP "Res\\eating.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_HUNGRY BITMAP "Res\\hungry.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_THINKING BITMAP "Res\\thinking.bmp" - - - -// -// Dialog resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_APPLICATION DIALOGEX 0, 0, 230, 205 -STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU -CAPTION "DPP Example" -CLASS "QP_APP" -FONT 8, "MS Shell Dlg", 0, 0, 1 -{ - CTEXT "www.state-machine.com", IDC_STATIC, 64, 190, 103, 8, SS_CENTER, WS_EX_TRANSPARENT - CONTROL IDB_THINKING, IDC_PHILO_0, WC_STATIC, SS_BITMAP, 90, 7, 53, 46, WS_EX_LEFT - CONTROL IDB_THINKING, IDC_PHILO_1, WC_STATIC, SS_BITMAP, 170, 58, 53, 46, WS_EX_TRANSPARENT - CONTROL IDB_THINKING, IDC_PHILO_4, WC_STATIC, SS_BITMAP, 7, 55, 53, 46, WS_EX_LEFT - DEFPUSHBUTTON "Quit", IDOK, 173, 7, 50, 14, WS_GROUP, WS_EX_LEFT - CONTROL IDB_THINKING, IDC_PHILO_2, WC_STATIC, SS_BITMAP, 137, 135, 53, 46, WS_EX_LEFT - CONTROL IDB_THINKING, IDC_PHILO_3, WC_STATIC, SS_BITMAP, 46, 134, 53, 46, WS_EX_LEFT - CONTROL "", IDC_PAUSE, WC_BUTTON, WS_TABSTOP | WS_TABSTOP | BS_OWNERDRAW | BS_BITMAP, 103, 73, 31, 27, WS_EX_LEFT - LTEXT "RUNNING...", IDC_PAUSED, 103, 102, 41, 8, SS_LEFT, WS_EX_LEFT -} - - - -// -// String Table resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE -{ - IDS_APP_TITLE "DPP" - IDS_PAUSED "PAUSED" - IDS_RUNNING "RUNNING..." -} - - - -// -// Icon resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDI_QP ICON "Res\\qp.ico" diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.sln b/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.sln deleted file mode 100644 index 3c880063..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.sln +++ /dev/null @@ -1,23 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dpp-gui", "dpp-gui.vcxproj", "{79027B25-0949-4F66-9765-4EFBCBBEFB94}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - QSpy|Win32 = QSpy|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.ActiveCfg = Debug|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.Build.0 = Debug|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.ActiveCfg = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.Build.0 = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.ActiveCfg = QSpy|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.Build.0 = QSpy|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj b/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj deleted file mode 100644 index 3e8b8639..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - QSpy - Win32 - - - - {79027B25-0949-4F66-9765-4EFBCBBEFB94} - dpp-gui - - - - Application - false - NotSet - v120 - - - Application - false - NotSet - v120 - - - Application - false - NotSet - v120 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(Configuration)\ - $(Configuration)\ - false - false - $(Configuration)\ - $(Configuration)\ - false - false - $(Configuration)\ - $(Configuration)\ - false - false - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/dpp-gui.tlb - - - - - MaxSpeed - OnlyExplicitInline - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) - NDEBUG;QWIN_GUI;_WINDOWS;%(PreprocessorDefinitions) - false - - - MultiThreaded - true - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - %(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - %(AdditionalLibraryDirectories) - Windows - false - - - MachineX86 - - - true - .\Release/dpp-gui.bsc - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\QSpy/dpp-gui.tlb - - - - - Disabled - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) - Q_SPY;QWIN_GUI;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - - - $(IntDir) - $(IntDir) - $(IntDir) - true - Level3 - true - ProgramDatabase - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - %(AdditionalLibraryDirectories) - true - false - - - Windows - false - - - MachineX86 - - - true - .\QSpy/dpp-gui.bsc - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/dpp-gui.tlb - - - - - Disabled - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) - QWIN_GUI;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - - - $(IntDir) - $(IntDir) - $(IntDir) - true - Level3 - true - ProgramDatabase - Default - - - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - %(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - %(AdditionalLibraryDirectories) - true - false - - - Windows - false - - - MachineX86 - - - true - .\Debug/dpp-gui.bsc - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - false - true - true - - - true - true - - - true - true - false - - - - - - \ No newline at end of file diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj.filters b/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj.filters deleted file mode 100644 index 2fab3aff..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/dpp-gui.vcxproj.filters +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - Res - - - Res - - - Res - - - Res - - - Res - - - Res - - - Res - - - - - {c8d4d732-dcf8-4466-ad8e-3f15ab6fe204} - - - {fc58f96a-b3df-47d3-9a58-3283c0cf1a5c} - - - - - Res - - - - - QP - - - QP - - - QP - - - \ No newline at end of file diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/win32/main.c deleted file mode 100644 index e580e69a..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/main.c +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************** -* Product: DPP example for Windows -* Last Updated for Version: 6.3.3 -* Date of the Last Update: 2018-06-22 -* -* 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://www.state-machine.com -* mailto:info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO*WIN_FUDGE_FACTOR]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ - diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/resource.h b/examples/arm-cm/dpp_efm32-slstk3401a/win32/resource.h deleted file mode 100644 index 36badf15..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32/resource.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef IDC_STATIC -#define IDC_STATIC (-1) -#endif - -#define IDI_QP 2 -#define IDD_APPLICATION 101 -#define IDB_THINKING 134 -#define IDB_EATING 135 -#define IDB_HUNGRY 136 -#define IDB_BTN_UP 137 -#define IDB_BTN_DWN 138 -#define IDC_PHILO_0 1000 -#define IDC_PHILO_1 1001 -#define IDC_PHILO_2 1002 -#define IDC_PHILO_3 1003 -#define IDC_PHILO_4 1004 -#define IDC_PAUSE 1006 -#define IDC_PAUSED 1009 -#define IDS_APP_TITLE 40000 -#define IDS_PAUSED 40001 -#define IDS_RUNNING 40002 diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c index d84515f1..e6e64093 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c @@ -56,16 +56,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c index 04d8d2bb..a1d621b8 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c @@ -49,14 +49,7 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); + /* dictionaries... */ /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c index 04dce99f..3bee325f 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c @@ -62,15 +62,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_mbed-lpc1768/main.c b/examples/arm-cm/dpp_mbed-lpc1768/main.c index d84515f1..e6e64093 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/main.c +++ b/examples/arm-cm/dpp_mbed-lpc1768/main.c @@ -56,16 +56,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/main.c b/examples/arm-cm/dpp_nucleo-h743zi/qk/main.c index 8438dea1..67ecf028 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qk/main.c +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/main.c @@ -69,16 +69,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qv/main.c b/examples/arm-cm/dpp_nucleo-h743zi/qv/main.c index 8438dea1..67ecf028 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qv/main.c +++ b/examples/arm-cm/dpp_nucleo-h743zi/qv/main.c @@ -69,16 +69,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qxk/main.c b/examples/arm-cm/dpp_nucleo-h743zi/qxk/main.c index 25bbd94b..aa8ec2e1 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qxk/main.c +++ b/examples/arm-cm/dpp_nucleo-h743zi/qxk/main.c @@ -82,16 +82,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); QS_OBJ_DICTIONARY(&l_ticker0); /* start the extended thread */ diff --git a/examples/arm-cm/dpp_nucleo-l053r8/main.c b/examples/arm-cm/dpp_nucleo-l053r8/main.c index d84515f1..e6e64093 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/main.c +++ b/examples/arm-cm/dpp_nucleo-l053r8/main.c @@ -56,16 +56,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c b/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c index 990b055a..d38d864c 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c @@ -76,13 +76,6 @@ int main() { BSP_init(); /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); QS_OBJ_DICTIONARY(&l_ticker0); /* start the extended thread */ diff --git a/examples/arm-cm/dpp_nucleo-l152re/main.c b/examples/arm-cm/dpp_nucleo-l152re/main.c index d84515f1..e6e64093 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/main.c +++ b/examples/arm-cm/dpp_nucleo-l152re/main.c @@ -56,16 +56,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c b/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c index 3c0d00c9..38f18d2f 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c +++ b/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c @@ -66,15 +66,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0); /* start the active objects... */ diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c b/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c index 3c0d00c9..38f18d2f 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c @@ -66,15 +66,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0); /* start the active objects... */ diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c b/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c index 4f8c211e..1bf34489 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c @@ -75,15 +75,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the extended thread */ QXTHREAD_START(XT_Test1, /* Thread to start */ (uint_fast8_t)1, /* QP priority of the thread */ diff --git a/examples/arm-cm/dpp_stm32f746g-discovery/qk/main.c b/examples/arm-cm/dpp_stm32f746g-discovery/qk/main.c index 7d36680b..ad7b70df 100644 --- a/examples/arm-cm/dpp_stm32f746g-discovery/qk/main.c +++ b/examples/arm-cm/dpp_stm32f746g-discovery/qk/main.c @@ -62,15 +62,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { QACTIVE_START(AO_Philo[n], /* AO to start */ diff --git a/examples/arm-cm/dpp_stm32f746g-discovery/qv/main.c b/examples/arm-cm/dpp_stm32f746g-discovery/qv/main.c index 9fa34604..55abb212 100644 --- a/examples/arm-cm/dpp_stm32f746g-discovery/qv/main.c +++ b/examples/arm-cm/dpp_stm32f746g-discovery/qv/main.c @@ -62,15 +62,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { QACTIVE_START(AO_Philo[n], /* AO to start */ diff --git a/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvoptx b/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvoptx index 2a5e1bf7..e6acbe4b 100644 --- a/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvoptx +++ b/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvoptx @@ -101,6 +101,8 @@ 0 0 1 + 0 + 0 5 @@ -212,6 +214,7 @@ 1 + 0 0 2 10000000 @@ -371,6 +374,8 @@ 0 0 1 + 0 + 0 5 @@ -482,6 +487,7 @@ 1 + 0 0 2 10000000 @@ -546,78 +552,6 @@ 0 18 - - - 0 - STM32F746G-Discovery Quick Start Guide (STM32F746G-Discovery) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\Documentation\32F746GDISCOVERY_QSG.pdf - - - 1 - STM32F756G-Eval Quick Start Guide (STM32756G-EVAL) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\Documentation\STM32F756G-EVAL_QSG.pdf - - - 2 - BSP User Manual (STM32F746G-Discovery) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\Drivers\BSP\STM32746G-Discovery\STM32746G-Discovery_BSP_User_Manual.chm - - - 3 - BSP User Manual (STM32756G-EVAL) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\Drivers\BSP\STM32756G_EVAL\STM32756G_EVAL_BSP_User_Manual.chm - - - 4 - User Manual (STM32756G-EVAL) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32756G_EVAL\Documentation\DM00188617.pdf - - - 5 - Bill of Materials (STM32756G-EVAL) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32756G_EVAL\Documentation\stm327x6g-eval_bom.zip - - - 6 - Gerber Files (STM32756G-EVAL) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32756G_EVAL\Documentation\stm327x6g-eval_gerber.zip - - - 7 - Schematics (STM32756G-EVAL) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32756G_EVAL\Documentation\stm327x6g-eval_sch.zip - - - 8 - User Manual (STM32F746G-Discovery) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32F746G_Discovery\Documentation\DM00190424.pdf - - - 9 - Bill of Materials (STM32F746G-Discovery) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32F746G_Discovery\Documentation\stm32f746g-disco_bom.zip - - - 10 - Gerber Files (STM32F746G-Discovery) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32F746G_Discovery\Documentation\stm32f746g-disco_gerber.zip - - - 11 - Schematics (STM32F746G-Discovery) - C:\tools\Keil_v5\ARM\PACK\Keil\STM32F7xx_DFP\2.6.0\MDK\Boards\ST\STM32F746G_Discovery\Documentation\stm32f746g-disco_sch.zip - - - 12 - STM32756G_EVAL Evaluation Board Web Page (STM32756G-EVAL) - http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261640 - - - 13 - STM32F746G_Discovery Web Page (STM32F746G-Discovery) - http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF261641 - - 0 1 @@ -641,6 +575,8 @@ 0 0 1 + 0 + 0 5 @@ -752,6 +688,7 @@ 1 + 0 0 2 10000000 diff --git a/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvprojx b/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvprojx index 7aef3911..0818b3eb 100644 --- a/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvprojx +++ b/examples/arm-cm/dpp_stm32f746g-discovery/qxk/arm/dpp-qxk.uvprojx @@ -10,7 +10,7 @@ dpp-dbg 0x4 ARM-ADS - 5060528::V5.06 update 5 (build 528)::ARMCC + 5060750::V5.06 update 6 (build 750)::ARMCC 0 @@ -184,6 +184,7 @@ 0 0 2 + 0 1 1 8 @@ -324,6 +325,7 @@ 0 1 0 + 0 0 0 0 @@ -652,6 +654,7 @@ 2 2 2 + 2 2 0 0 @@ -890,6 +893,7 @@ 0 0 2 + 0 1 1 8 @@ -1030,6 +1034,7 @@ 0 1 0 + 0 0 0 0 @@ -1358,6 +1363,7 @@ 2 2 2 + 2 2 0 0 @@ -1422,7 +1428,7 @@ dbg-spy 0x4 ARM-ADS - 5060183::V5.06 update 2 (build 183)::ARMCC + 5060750::V5.06 update 6 (build 750)::ARMCC 0 @@ -1596,6 +1602,7 @@ 0 0 2 + 0 1 1 8 @@ -1736,6 +1743,7 @@ 0 1 0 + 0 0 0 0 @@ -2064,6 +2072,7 @@ 2 2 2 + 2 2 0 0 diff --git a/examples/arm-cm/dpp_stm32f746g-discovery/qxk/main.c b/examples/arm-cm/dpp_stm32f746g-discovery/qxk/main.c index 4f8c211e..1bf34489 100644 --- a/examples/arm-cm/dpp_stm32f746g-discovery/qxk/main.c +++ b/examples/arm-cm/dpp_stm32f746g-discovery/qxk/main.c @@ -75,15 +75,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the extended thread */ QXTHREAD_START(XT_Test1, /* Thread to start */ (uint_fast8_t)1, /* QP priority of the thread */ diff --git a/examples/arm-cm/game_efm32-slstk3401a/.game b/examples/arm-cm/game_efm32-slstk3401a/.game deleted file mode 100644 index f62bffdd..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/.game +++ /dev/null @@ -1,65 +0,0 @@ - - - GPL - - - 1 - 0 - 3 - 0 - - - 0,0,474,431,* - 0,131,596,300 - 0,0,596,300 - -122,131,596,300 - -122,0,596,300 - - - 2032128 - 0 - - - - - 0 - - - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - 0 - - - diff --git a/examples/arm-cm/game_efm32-slstk3401a/README.txt b/examples/arm-cm/game_efm32-slstk3401a/README.txt index 7489cf78..41b6ecdd 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/README.txt +++ b/examples/arm-cm/game_efm32-slstk3401a/README.txt @@ -30,21 +30,37 @@ The output is generated at 115200 baud rate. Here is an example invocation of the QSPY host application to receive the QS data from EFM32-SLSTK3401A: -qspy -cCOM1 +qspy -u -c COM1 (Windows) -The actual COM port number might be different on your Windows machine. +qspy -u -c /dev/ttyS1 (POSIX) + +The actual serial-port number might be different on your workstation. Please check the Device Manager to find the COM port number. -Win32 Emulations -================ -The sub-directorie win32 and win32-qv provide the emulations of the example -on Windows GUI (with regular Win32 threads and with cooperative QV scheduler, -respectively. These sub-directories contain the Makefiles for the MinGW -toolset and Visual Studio solution files (game-gui.sln) for Visual C++. +Win32-GUI Emulation +=================== +The sub-directory "win32-gui" provides the emulation of the example +on Windows GUI, either single-threaded (win32-qv) or multithreded (win32). +This sub-directory contains the Makefile for the GNU-GCC toolset (MinGW) +and Visual Studio solution file (game-gui.sln) for Visual C++. -The Win32 emulations use exactly the same code as the embedded board and -differ only in the Board Support Package (bsp.c). This examples demonstrate -the "dual targeting" development approach, where most of the embedded code -is developed on the desktop machine (Windows), but is intended for a deeply +The Win32-GUI emulation is based on the QWin™ GUI Prototyping Toolkit, see: + +https://www.state-machine.com/qtools/qwin.html + +The emulation uses exactly the same code as the embedded board and differs +only in the Board Support Package (bsp.c). This example demonstrates the +"dual targeting" development approach, where most of the embedded code is +developed on the workstation (Windows), but is intended for a deeply embedded target (EFM32-SLSTK3401A here). + + +QS Software Tracing Instrumentation +----------------------------------- +The "win32-gui" emulation also supports the "Spy" build configuration, +in which case it attempts to connect to the QSPY host application via +a TCP/IP socket. This requires launching the QSPY host application with +the command-line parameter -t + +qspy -u -t \ No newline at end of file diff --git a/examples/arm-cm/game_efm32-slstk3401a/game.h b/examples/arm-cm/game_efm32-slstk3401a/game.h index 267c2ebf..1e427cb2 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/game.h +++ b/examples/arm-cm/game_efm32-slstk3401a/game.h @@ -3,7 +3,7 @@ * Model: game.qm * File: ${.::game.h} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/game.qm b/examples/arm-cm/game_efm32-slstk3401a/game.qm index c9267b61..35bb59ab 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/game.qm +++ b/examples/arm-cm/game_efm32-slstk3401a/game.qm @@ -1,5 +1,5 @@ - + "Fly 'n' Shoot" game model from Chapters 1 & 9 of PSiCC2 NOTE: Requries QP6. diff --git a/examples/arm-cm/game_efm32-slstk3401a/main.c b/examples/arm-cm/game_efm32-slstk3401a/main.c index a8e2a812..260e8c09 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/main.c +++ b/examples/arm-cm/game_efm32-slstk3401a/main.c @@ -61,24 +61,11 @@ int main() { /* init publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); - /* initialize the event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - QF_poolInit(medPoolSto, sizeof(medPoolSto), sizeof(medPoolSto[0])); - /* object dictionaries for AOs... */ QS_OBJ_DICTIONARY(AO_Missile); QS_OBJ_DICTIONARY(AO_Ship); QS_OBJ_DICTIONARY(AO_Tunnel); - /* object dictionaries for event queues... */ - QS_OBJ_DICTIONARY(missileQueueSto); - QS_OBJ_DICTIONARY(shipQueueSto); - QS_OBJ_DICTIONARY(tunnelQueueSto); - - /* object dictionaries for event pools... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(medPoolSto); - /* signal dictionaries for globally published events... */ QS_SIG_DICTIONARY(TIME_TICK_SIG, (void *)0); QS_SIG_DICTIONARY(PLAYER_TRIGGER_SIG, (void *)0); diff --git a/examples/arm-cm/game_efm32-slstk3401a/mine1.c b/examples/arm-cm/game_efm32-slstk3401a/mine1.c index bcba5a88..2ea86437 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/mine1.c +++ b/examples/arm-cm/game_efm32-slstk3401a/mine1.c @@ -3,7 +3,7 @@ * Model: game.qm * File: ${.::mine1.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/mine2.c b/examples/arm-cm/game_efm32-slstk3401a/mine2.c index 29a3da9b..89b55e84 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/mine2.c +++ b/examples/arm-cm/game_efm32-slstk3401a/mine2.c @@ -3,7 +3,7 @@ * Model: game.qm * File: ${.::mine2.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/missile.c b/examples/arm-cm/game_efm32-slstk3401a/missile.c index 809c5829..d93bd8af 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/missile.c +++ b/examples/arm-cm/game_efm32-slstk3401a/missile.c @@ -3,7 +3,7 @@ * Model: game.qm * File: ${.::missile.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/ship.c b/examples/arm-cm/game_efm32-slstk3401a/ship.c index 533f909c..acd95a15 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/ship.c +++ b/examples/arm-cm/game_efm32-slstk3401a/ship.c @@ -3,7 +3,7 @@ * Model: game.qm * File: ${.::ship.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/tunnel.c b/examples/arm-cm/game_efm32-slstk3401a/tunnel.c index 74451759..c91ab57b 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/tunnel.c +++ b/examples/arm-cm/game_efm32-slstk3401a/tunnel.c @@ -3,7 +3,7 @@ * Model: game.qm * File: ${.::tunnel.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Makefile b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Makefile similarity index 59% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Makefile rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Makefile index fe69c67b..41ff2f48 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Makefile +++ b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C, Game-GUI, Win32-QV, MinGW -# Last updated for version 5.6.5 -# Last updated on 2016-06-02 +# Product: Makefile for QP/C, Win32-GUI, GNU GCC +# Last updated for version 6.3.6 +# Last updated on 2018-10-15 # -# 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 ############################################################################## # examples of invoking this Makefile: @@ -44,45 +44,38 @@ # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ # #----------------------------------------------------------------------------- # project name # -PROJECT := game-gui +PROJECT := game-gui #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qv - # list of all source directories used by this project -VPATH = \ - . \ +VPATH := . \ .. # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include +INCLUDES := -I. \ + -I.. # list of resource include directories needed by this project RCINCLUDES = \ -IRes +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif #----------------------------------------------------------------------------- -# files +# project files: # # C source files... @@ -96,7 +89,7 @@ C_SRCS := \ tunnel.c # C++ source files... -CPP_SRCS := +CPP_SRCS := # Resource files... RC_SRCS := \ @@ -109,68 +102,111 @@ LIBS := # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API DEFINES := -DQP_API_VERSION=9999 +ifeq (,$(CONF)) + CONF := dbg +endif + #----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp + +else + +$(error GUI build currently not supported on POSIX) + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: # # NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH # CC := gcc CPP := g++ LINK := gcc # for C programs #LINK := g++ # for C++ programs + +# NOTE: +# This Makefile assumes that the windres utility is available on the PATH +# (windres is available in the QTools collection for Windows) +# RC := windres -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif #----------------------------------------------------------------------------- -# build options for various configurations -# +# build configurations... ifeq (rel, $(CONF)) # Release configuration .................................. -BIN_DIR := rel +BIN_DIR := build_rel -CFLAGS = -ffunction-sections -fdata-sections \ +CFLAGS = -c -ffunction-sections -fdata-sections \ -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG -CPPFLAGS = -ffunction-sections -fdata-sections \ +CPPFLAGS = -c -ffunction-sections -fdata-sections \ -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ -BIN_DIR := spy +BIN_DIR := build_spy LIBS += -lwsock32 -CFLAGS = -g -ffunction-sections -fdata-sections \ +CFLAGS = -c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY -CPPFLAGS = -g -ffunction-sections -fdata-sections \ +CPPFLAGS =-c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... -BIN_DIR := dbg +BIN_DIR := build -CFLAGS = -g -ffunction-sections -fdata-sections \ +CFLAGS = -c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) -CPPFLAGS = -g -ffunction-sections -fdata-sections \ +CPPFLAGS = -c -g -ffunction-sections -fdata-sections \ -O -Wall -W $(INCLUDES) $(DEFINES) endif # ..................................................................... -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections +LINKFLAGS := # is it a GUI application (any GUI resources provided?) ... ifneq (,$(RC_SRCS)) @@ -179,22 +215,15 @@ DEFINES += -DQWIN_GUI endif #----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) # create $(BIN_DIR) if it does not exist @@ -207,13 +236,9 @@ endif # all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.cpp @@ -223,10 +248,10 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.rc $(RC) $(RCINCLUDES) -i $< -o $@ @@ -238,23 +263,26 @@ ifneq ($(MAKECMDGOALS),clean) endif endif -.PHONY : clean -clean: +.PHONY : clean show + +clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo RC_SRCS = $(RC_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo C_OBJS_EXT = $(C_OBJS_EXT) @echo C_DEPS_EXT = $(C_DEPS_EXT) @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/BOARD.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BOARD.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/BOARD.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BOARD.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/BTN_DWN.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/BTN_DWN.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/BTN_UP.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/BTN_UP.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/LCD.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LCD.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/LCD.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LCD.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/LED_OFF.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_OFF.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/LED_OFF.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_OFF.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/LED_ON.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_ON.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/LED_ON.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_ON.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/qp.ico b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/qp.ico similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32/Res/qp.ico rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/qp.ico diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg0.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg0.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg0.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg0.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg1.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg1.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg1.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg1.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg2.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg2.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg2.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg2.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg3.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg3.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg3.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg3.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg4.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg4.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg4.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg4.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg5.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg5.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg5.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg5.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg6.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg6.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg6.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg6.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg7.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg7.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg7.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg7.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg8.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg8.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg8.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg8.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg9.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg9.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/seg9.bmp rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg9.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/bsp.c b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/bsp.c similarity index 81% rename from examples/arm-cm/game_efm32-slstk3401a/win32/bsp.c rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/bsp.c index df064061..3d94fea5 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/bsp.c +++ b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A, Win32-GUI -* Last updated for version 5.9.0 -* Last updated on 2017-04-14 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 "qpc.h" @@ -41,12 +41,6 @@ #include /* for _snprintf_s() */ #include -#ifdef Q_SPY - #define WIN32_LEAN_AND_MEAN - #include /* Win32 API for multithreading */ - #include /* for Windows network facilities */ -#endif - Q_DEFINE_THIS_FILE /* local variables ---------------------------------------------------------*/ @@ -81,9 +75,7 @@ static void paintBitsClear(uint8_t x, uint8_t y, PLAYER_TRIGGER = QS_USER, COMMAND_STAT }; - static SOCKET l_sock = INVALID_SOCKET; static uint8_t const l_clock_tick = 0U; - static uint8_t const l_mouse = 0U; #endif /* Local functions ---------------------------------------------------------*/ @@ -98,7 +90,7 @@ static void playerTrigger(void) { /*--------------------------------------------------------------------------*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ } /*..........................................................................*/ void QF_onCleanup(void) { @@ -108,12 +100,16 @@ void QF_onClockTick(void) { static QEvt const tickEvt = { TIME_TICK_SIG, 0U, 0U }; QF_TICK_X(0U, &l_clock_tick); /* process time events for rate 0 */ QF_PUBLISH(&tickEvt, &l_clock_tick); /* publish the tick event */ + + QS_RX_INPUT(); /* handle the QS-RX input */ + QS_OUTPUT(); /* handle the QS output */ } /*..........................................................................*/ void Q_onAssert(char const * const module, int_t loc) { char message[80]; QF_stop(); /* stop ticking */ + QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ SNPRINTF_S(message, Q_DIM(message) - 1, "Assertion failed in module %s location %d", module, loc); @@ -131,18 +127,17 @@ void BSP_init(void) { "QS_INIT() Error", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); } - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ + + /* send the QS dictionaries... */ + QS_OBJ_DICTIONARY(&l_clock_tick); QS_USR_DICTIONARY(PLAYER_TRIGGER); - QS_USR_DICTIONARY(COMMAND_STAT); + + /* setup the QS filters... */ + QS_FILTER_ON(QS_ALL_RECORDS); + QS_FILTER_OFF(QS_QF_TICK); } /*..........................................................................*/ void BSP_terminate(int16_t result) { -#ifdef Q_SPY - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } -#endif QF_stop(); /* stop the main QF application and the ticker thread */ /* cleanup all QWIN resources... */ @@ -841,202 +836,22 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, /*--------------------------------------------------------------------------*/ #ifdef Q_SPY /* define QS callbacks */ -#include - -/* -* In this demo, the QS software tracing output is sent out of the application -* through a TCP/IP socket. This requires the QSPY host application to -* be started first to open a server socket (qspy -t ...) to wait for the -* incoming TCP/IP connection from the DPP demo. -* -* In an embedded target, the QS software tracing output can be sent out -* using any method available, such as a UART. This would require changing -* the implementation of the functions in this section, but the rest of the -* application code does not "know" (and should not care) how the QS ouptut -* is actually performed. In other words, the rest of the application does NOT -* need to change in any way to produce QS output. -*/ - -/*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; - while (l_sock != INVALID_SOCKET) { - uint16_t nBytes; - uint8_t const *block; - - /* try to receive bytes from the QS socket... */ - nBytes = QS_rxGetNfree(); - if (nBytes > 0U) { - uint8_t buf[64]; - int status; - - if (nBytes > sizeof(buf)) { - nBytes = sizeof(buf); - } - status = recv(l_sock, (char *)buf, (int)nBytes, 0); - if (status != SOCKET_ERROR) { - uint16_t i; - nBytes = (uint16_t)status; - for (i = 0U; i < nBytes; ++i) { - QS_RX_PUT(buf[i]); - } - } - } - QS_rxParse(); /* parse all the received bytes */ - - nBytes = 1024U; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - } - Sleep(20); /* sleep for xx milliseconds */ - } - return (DWORD)0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[1024]; /* buffer for QS output */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static WSADATA wsaData; - char hostName[64]; - char const *src; - char *dst; - USHORT port = 6601; /* default QSPY server port */ - ULONG ioctl_opt = 1; - struct sockaddr_in sockAddr; - struct hostent *server; - - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets */ - if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { - printf("Windows Sockets cannot be initialized."); - return (uint8_t)0; - } - - src = (arg != (void const *)0) - ? (char const *)arg - : "localhost"; - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName)])) - { - *dst++ = *src++; - } - *dst = '\0'; - if (*src == ':') { - port = (USHORT)strtoul(src + 1, NULL, 10); - } - - l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ - if (l_sock == INVALID_SOCKET){ - printf("Socket cannot be created; error 0x%08X\n", - WSAGetLastError()); - return (uint8_t)0; /* failure */ - } - - server = gethostbyname(hostName); - if (server == NULL) { - printf("QSpy host name %s cannot be resolved; error 0x%08X\n", - hostName, WSAGetLastError()); - return (uint8_t)0; - } - - memset(&sockAddr, 0, sizeof(sockAddr)); - sockAddr.sin_family = AF_INET; - memcpy(&sockAddr.sin_addr, server->h_addr, server->h_length); - sockAddr.sin_port = htons(port); - if (connect(l_sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) - == SOCKET_ERROR) - { - printf("Cannot connect to the QSPY server; error 0x%08X\n", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* Set the socket to non-blocking mode. */ - if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { - printf("Socket configuration failed.\n" - "Windows socket error 0x%08X.", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* set up 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PLAYER_TRIGGER); - QS_FILTER_ON(COMMAND_STAT); - - /* return the status of creating the idle thread */ - return (CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0) ? (uint8_t)1 : (uint8_t)0; -} -/*..........................................................................*/ -void QS_onCleanup(void) { - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - WSACleanup(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes = 1000; - uint8_t const *block; - while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - nBytes = 1000; - } -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ -void QS_onReset(void) { - //TBD -} -/*..........................................................................*/ -/*! callback function to execute a uesr command (to be implemented in BSP) */ +/*! callback function to execute user commands */ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + /* unused parameters */ (void)param1; (void)param2; (void)param3; - - QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_onAssert("command", 10); - } } #endif /* Q_SPY */ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.rc b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.rc similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.rc rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.rc diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.sln b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.sln similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.sln rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.sln diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.vcxproj b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj similarity index 86% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.vcxproj rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj index a6fd8fbf..3d07dfff 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.vcxproj +++ b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj @@ -1,4 +1,4 @@ - + @@ -81,7 +81,7 @@ MaxSpeed OnlyExplicitInline - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) + .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) NDEBUG;QWIN_GUI;_WINDOWS;%(PreprocessorDefinitions) false @@ -102,10 +102,10 @@ 0x0409 - %(AdditionalDependencies) + qp.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe true - %(AdditionalLibraryDirectories) + ../../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) Windows false @@ -132,7 +132,7 @@ Disabled - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) + .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) Q_SPY;QWIN_GUI;snprintf=_snprintf;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) false @@ -155,10 +155,10 @@ 0x0409 - wsock32.lib;%(AdditionalDependencies) + qp.lib;wsock32.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe true - %(AdditionalLibraryDirectories) + ../../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true false @@ -189,7 +189,7 @@ Disabled - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) + .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) QWIN_GUI;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) false @@ -214,10 +214,10 @@ 0x0409 - %(AdditionalDependencies) + qp.lib;%(AdditionalDependencies) $(OutDir)$(ProjectName).exe true - %(AdditionalLibraryDirectories) + ../../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true false @@ -270,21 +270,6 @@ - - - false - true - - - true - true - - - true - true - true - - diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.vcxproj.filters b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj.filters similarity index 73% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.vcxproj.filters rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj.filters index dd56f78e..db4f1504 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/game-gui.vcxproj.filters +++ b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj.filters @@ -42,24 +42,10 @@ {c8d4d732-dcf8-4466-ad8e-3f15ab6fe204} - - {22663e12-dd09-49e8-b222-67a2f17d770d} - Res - - - QP - - - QP - - - QP - - \ No newline at end of file diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/main.c b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/main.c similarity index 94% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/main.c rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/main.c index e645385e..0ab9a385 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/main.c +++ b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/main.c @@ -69,15 +69,6 @@ int main() { QS_OBJ_DICTIONARY(AO_Ship); QS_OBJ_DICTIONARY(AO_Tunnel); - /* object dictionaries for event queues... */ - QS_OBJ_DICTIONARY(missileQueueSto); - QS_OBJ_DICTIONARY(shipQueueSto); - QS_OBJ_DICTIONARY(tunnelQueueSto); - - /* object dictionaries for event pools... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(medPoolSto); - /* signal dictionaries for globally published events... */ QS_SIG_DICTIONARY(TIME_TICK_SIG, (void *)0); QS_SIG_DICTIONARY(PLAYER_TRIGGER_SIG, (void *)0); diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/resource.h b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/resource.h similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-qv/resource.h rename to examples/arm-cm/game_efm32-slstk3401a/win32-gui/resource.h diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/qp.ico b/examples/arm-cm/game_efm32-slstk3401a/win32-qv/Res/qp.ico deleted file mode 100644 index 032e1307b5a64fadaea08a03d24c25171a25ee32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10134 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. -* -* Contact information: -* https://state-machine.com -* mailto:info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "game.h" -#include "bsp.h" - -#include "qwin_gui.h" /* QWIN GUI */ -#include "resource.h" /* GUI resource IDs generated by the resource editior */ - -#include /* for _snprintf_s() */ -#include - -#ifdef Q_SPY - #define WIN32_LEAN_AND_MEAN - #include /* Win32 API for multithreading */ - #include /* for Windows network facilities */ -#endif - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static HINSTANCE l_hInst; /* this application instance */ -static HWND l_hWnd; /* main window handle */ -static LPSTR l_cmdLine; /* the command line string */ - -static GraphicDisplay l_lcd; /* LCD display on EFM32-SLSTK3401A */ -static SegmentDisplay l_userLED0; /* USER LED0 on EFM32-SLSTK3401A */ -static SegmentDisplay l_userLED1; /* USER LED1 on EFM32-SLSTK3401A */ -static SegmentDisplay l_scoreBoard; /* segment display for the score */ -static OwnerDrawnButton l_userBtn0; /* USER Button0 on EFM32-SLSTK3401A */ -static OwnerDrawnButton l_userBtn1; /* USER Button1 on EFM32-SLSTK3401A */ - -/* (R,G,B) colors for the LCD display */ -static BYTE const c_onColor[3] = { 0x07U, 0x07U, 0x07U }; /* dark grey */ -static BYTE const c_offColor[3] = { 0xA0U, 0xA0U, 0xA0U }; /* light grey */ - -/* LCD geometry and frame buffer */ -static uint32_t l_fb[BSP_SCREEN_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; - -/* the walls buffer */ -static uint32_t l_walls[GAME_TUNNEL_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; - -static unsigned l_rnd; /* random seed */ - -static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h); -static void paintBitsClear(uint8_t x, uint8_t y, - uint8_t const *bits, uint8_t h); -#ifdef Q_SPY - enum QSUserRecords { - PLAYER_TRIGGER = QS_USER, - COMMAND_STAT - }; - static SOCKET l_sock = INVALID_SOCKET; - static uint8_t const l_clock_tick = 0U; - static uint8_t const l_mouse = 0U; -#endif - -/* Local functions ---------------------------------------------------------*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam); - -/*..........................................................................*/ -static void playerTrigger(void) { - static QEvt const fireEvt = { PLAYER_TRIGGER_SIG, 0U, 0U }; - QF_PUBLISH(&fireEvt, (void*)0); -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QF_onClockTick(void) { - static QEvt const tickEvt = { TIME_TICK_SIG, 0U, 0U }; - QF_TICK_X(0U, &l_clock_tick); /* process time events for rate 0 */ - QF_PUBLISH(&tickEvt, &l_clock_tick); /* publish the tick event */ -} - -/*..........................................................................*/ -void Q_onAssert(char const * const module, int_t loc) { - char message[80]; - QF_stop(); /* stop ticking */ - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - SNPRINTF_S(message, Q_DIM(message) - 1, - "Assertion failed in module %s location %d", module, loc); - MessageBox(l_hWnd, message, "!!! ASSERTION !!!", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - PostQuitMessage(-1); -} - -/*..........................................................................*/ -void BSP_init(void) { - if (QS_INIT(l_cmdLine) == (uint8_t)0) { /* QS initialization failed? */ - MessageBox(l_hWnd, - "Cannot connect to QSPY via TCP/IP\n" - "Please make sure that 'qspy -t' is running", - "QS_INIT() Error", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - } - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PLAYER_TRIGGER); - QS_USR_DICTIONARY(COMMAND_STAT); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { -#ifdef Q_SPY - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } -#endif - QF_stop(); /* stop the main QF application and the ticker thread */ - - /* cleanup all QWIN resources... */ - OwnerDrawnButton_xtor(&l_userBtn0); /* cleanup the l_userBtn0 resources */ - OwnerDrawnButton_xtor(&l_userBtn1); /* cleanup the l_userBtn1 resources */ - SegmentDisplay_xtor(&l_userLED0); /* cleanup the l_userLED0 resources */ - SegmentDisplay_xtor(&l_userLED1); /* cleanup the l_userLED1 resources */ - SegmentDisplay_xtor(&l_scoreBoard); /* cleanup the scoreBoard resources */ - GraphicDisplay_xtor(&l_lcd); /* cleanup the l_lcd resources */ - - /* end the main dialog */ - EndDialog(l_hWnd, result); -} -/*..........................................................................*/ -void BSP_updateScreen(void) { - UINT x, y; - - /* turn LED1 on */ - SegmentDisplay_setSegment(&l_userLED1, 0U, 1U); - - /* map the LCD pixels to the GraphicDisplay pixels... */ - for (y = 0; y < BSP_SCREEN_HEIGHT; ++y) { - for (x = 0; x < BSP_SCREEN_WIDTH; ++x) { - uint32_t bits = l_fb[y][x >> 5]; - if ((bits & (1U << (x & 0x1FU))) != 0U) { - GraphicDisplay_setPixel(&l_lcd, x, y, c_onColor); - } - else { - GraphicDisplay_clearPixel(&l_lcd, x, y); - } - } - } - - GraphicDisplay_redraw(&l_lcd); /* redraw the updated display */ - - /* turn LED1 off */ - SegmentDisplay_setSegment(&l_userLED1, 0U, 0U); -} -/*..........................................................................*/ -void BSP_clearFB() { - uint_fast8_t y; - for (y = 0U; y < BSP_SCREEN_HEIGHT; ++y) { - l_fb[y][0] = 0U; - l_fb[y][1] = 0U; - l_fb[y][2] = 0U; - l_fb[y][3] = 0U; - } -} -/*..........................................................................*/ -void BSP_clearWalls() { - uint_fast8_t y; - for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { - l_walls[y][0] = 0U; - l_walls[y][1] = 0U; - l_walls[y][2] = 0U; - l_walls[y][3] = 0U; - } -} -/*..........................................................................*/ -bool BSP_isThrottle(void) { /* is the throttle button depressed? */ - return OwnerDrawnButton_isDepressed(&l_userBtn1) != 0; -} -/*..........................................................................*/ -void BSP_paintString(uint8_t x, uint8_t y, char const *str) { - static uint8_t const font5x7[95][7] = { - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, /* */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, /* ! */ - { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, /* " */ - { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, /* # */ - { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, /* $ */ - { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, /* % */ - { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, /* & */ - { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ' */ - { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, /* ( */ - { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, /* ) */ - { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, /* * */ - { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, /* + */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, /* , */ - { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, /* - */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, /* . */ - { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, /* / */ - { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, /* 0 */ - { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* 1 */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, /* 2 */ - { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, /* 3 */ - { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, /* 4 */ - { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, /* 5 */ - { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, /* 6 */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, /* 7 */ - { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, /* 8 */ - { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, /* 9 */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, /* : */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, /* ; */ - { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, /* < */ - { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, /* = */ - { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, /* > */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, /* ? */ - { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, /* @ */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, /* A */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, /* B */ - { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, /* C */ - { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, /* D */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, /* E */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* F */ - { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, /* G */ - { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, /* H */ - { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* I */ - { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, /* J */ - { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, /* K */ - { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, /* L */ - { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, /* M */ - { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, /* N */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* O */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* P */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, /* Q */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, /* R */ - { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, /* S */ - { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* T */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* U */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* V */ - { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, /* W */ - { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, /* X */ - { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, /* Y */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, /* Z */ - { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, /* [ */ - { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, /* \ */ - { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, /* ] */ - { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ^ */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, /* _ */ - { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ` */ - { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, /* a */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, /* b */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, /* c */ - { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, /* d */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, /* e */ - { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, /* f */ - { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* g */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* h */ - { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* i */ - { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, /* j */ - { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, /* k */ - { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* l */ - { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, /* m */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* n */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, /* o */ - { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, /* p */ - { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, /* q */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, /* r */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, /* s */ - { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, /* t */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, /* u */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* v */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, /* w */ - { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, /* x */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* y */ - { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, /* z */ - { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, /* { */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* | */ - { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, /* } */ - { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ~ */ - }; - - for (; *str != '\0'; ++str, x += 6) { - uint8_t const *ch = &font5x7[*str - ' '][0]; - paintBitsClear(x, y, ch, 7); - } -} - -/*==========================================================================*/ -typedef struct { /* the auxiliary structure to hold const bitmaps */ - uint8_t const *bits; /* the bits in the bitmap */ - uint8_t height; /* the height of the bitmap */ -} Bitmap; - -/* bitmap of the Ship: -* -* x.... -* xxx.. -* xxxxx -*/ -static uint8_t const ship_bits[] = { - 0x01U, 0x07U, 0x1FU -}; - -/* bitmap of the Missile: -* -* xxxx -*/ -static uint8_t const missile_bits[] = { - 0x0FU -}; - -/* bitmap of the Mine type-1: -* -* .x. -* xxx -* .x. -*/ -static uint8_t const mine1_bits[] = { - 0x02U, 0x07U, 0x02U -}; - -/* bitmap of the Mine type-2: -* -* x..x -* .xx. -* .xx. -* x..x -*/ -static uint8_t const mine2_bits[] = { - 0x09U, 0x06U, 0x06U, 0x09U -}; - -/* Mine type-2 is nastier than Mine type-1. The type-2 mine can -* hit the Ship with any of its "tentacles". However, it can be -* destroyed by the Missile only by hitting its center, defined as -* the following bitmap: -* -* .... -* .xx. -* .xx. -*/ -static uint8_t const mine2_missile_bits[] = { - 0x00U, 0x06U, 0x06U -}; - -/* -* The bitmap of the explosion stage 0: -* -* ....... -* ...x... -* ..x.x.. -* ...x... -*/ -static uint8_t const explosion0_bits[] = { - 0x00U, 0x08U, 0x14U, 0x08U -}; - -/* -* The bitmap of the explosion stage 1: -* -* ....... -* ..x.x.. -* ...x... -* ..x.x.. -*/ -static uint8_t const explosion1_bits[] = { - 0x00U, 0x14U, 0x08U, 0x14U -}; - -/* -* The bitmap of the explosion stage 2: -* -* .x...x. -* ..x.x.. -* ...x... -* ..x.x.. -* .x...x. -*/ -static uint8_t const explosion2_bits[] = { - 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U -}; - -/* -* The bitmap of the explosion stage 3: -* -* x..x..x -* .x.x.x. -* ..x.x.. -* xx.x.xx -* ..x.x.. -* .x.x.x. -* x..x..x -*/ -static uint8_t const explosion3_bits[] = { - 0x49, 0x2A, 0x14, 0x6B, 0x14, 0x2A, 0x49 -}; - -static Bitmap const l_bitmap[MAX_BMP] = { - { ship_bits, Q_DIM(ship_bits) }, - { missile_bits, Q_DIM(missile_bits) }, - { mine1_bits, Q_DIM(mine1_bits) }, - { mine2_bits, Q_DIM(mine2_bits) }, - { mine2_missile_bits, Q_DIM(mine2_missile_bits) }, - { explosion0_bits, Q_DIM(explosion0_bits) }, - { explosion1_bits, Q_DIM(explosion1_bits) }, - { explosion2_bits, Q_DIM(explosion2_bits) }, - { explosion3_bits, Q_DIM(explosion3_bits) } -}; - -/*..........................................................................*/ -void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id) { - Bitmap const *bmp = &l_bitmap[bmp_id]; - paintBits(x, y, bmp->bits, bmp->height); -} -/*..........................................................................*/ -void BSP_advanceWalls(uint8_t top, uint8_t bottom) { - uint_fast8_t y; - for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { - /* shift the walls one pixel to the left */ - l_walls[y][0] = (l_walls[y][0] >> 1) | (l_walls[y][1] << 31); - l_walls[y][1] = (l_walls[y][1] >> 1) | (l_walls[y][2] << 31); - l_walls[y][2] = (l_walls[y][2] >> 1) | (l_walls[y][3] << 31); - l_walls[y][3] = (l_walls[y][3] >> 1); - - /* add new column of walls at the end */ - if (y <= top) { - l_walls[y][3] |= (1U << 31); - } - if (y >= (GAME_TUNNEL_HEIGHT - bottom)) { - l_walls[y][3] |= (1U << 31); - } - - /* copy the walls to the frame buffer */ - l_fb[y][0] = l_walls[y][0]; - l_fb[y][1] = l_walls[y][1]; - l_fb[y][2] = l_walls[y][2]; - l_fb[y][3] = l_walls[y][3]; - } -} -/*..........................................................................*/ -bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, - uint8_t bmp_id2, uint8_t x2, uint8_t y2) -{ - uint8_t y; - uint8_t y0; - uint8_t h; - uint32_t bits1; - uint32_t bits2; - Bitmap const *bmp1; - Bitmap const *bmp2; - - Q_REQUIRE((bmp_id1 < Q_DIM(l_bitmap)) && (bmp_id2 < Q_DIM(l_bitmap))); - - /* are the bitmaps close enough in x? */ - if (x1 >= x2) { - if (x1 > x2 + 8U) { - return false; - } - x1 -= x2; - x2 = 0U; - } - else { - if (x2 > x1 + 8U) { - return false; - } - x2 -= x1; - x1 = 0U; - } - - bmp1 = &l_bitmap[bmp_id1]; - bmp2 = &l_bitmap[bmp_id2]; - if ((y1 <= y2) && (y1 + bmp1->height > y2)) { - y0 = y2 - y1; - h = y1 + bmp1->height - y2; - if (h > bmp2->height) { - h = bmp2->height; - } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ - bits1 = ((uint32_t)bmp1->bits[y + y0] << x1); - bits2 = ((uint32_t)bmp2->bits[y] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ - } - } - } - else { - if ((y1 > y2) && (y2 + bmp2->height > y1)) { - y0 = y1 - y2; - h = y2 + bmp2->height - y1; - if (h > bmp1->height) { - h = bmp1->height; - } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ - bits1 = ((uint32_t)bmp1->bits[y] << x1); - bits2 = ((uint32_t)bmp2->bits[y + y0] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ - } - } - } - } - return false; /* the bitmaps do not overlap */ -} -/*..........................................................................*/ -bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { - Bitmap const *bmp = &l_bitmap[bmp_id]; - uint32_t shft = (x & 0x1FU); - uint32_t *walls = &l_walls[y][x >> 5]; - for (y = 0; y < bmp->height; ++y, walls += (BSP_SCREEN_WIDTH >> 5)) { - if (*walls & ((uint32_t)bmp->bits[y] << shft)) { - return true; - } - if (shft > 24U) { - if (*(walls + 1) & ((uint32_t)bmp->bits[y] >> (32U - shft))) { - return true; - } - } - } - return false; -} - -/*..........................................................................*/ -void BSP_updateScore(uint16_t score) { - uint8_t seg[5]; - char str[5]; - - if (score == 0U) { - BSP_paintString(1U, BSP_SCREEN_HEIGHT - 8U, "SCORE:"); - } - - seg[0] = score % 10U; score /= 10U; - seg[1] = score % 10U; score /= 10U; - seg[2] = score % 10U; score /= 10U; - seg[3] = score % 10U; - - /* update the SCORE area on the screeen */ - str[0] = seg[3] + '0'; - str[1] = seg[2] + '0'; - str[2] = seg[1] + '0'; - str[3] = seg[0] + '0'; - str[4] = '\0'; - BSP_paintString(6U*6U, BSP_SCREEN_HEIGHT - 8U, str); - - /* update the score in the l_scoreBoard SegmentDisplay */ - SegmentDisplay_setSegment(&l_scoreBoard, 0U, (UINT)seg[0]); - SegmentDisplay_setSegment(&l_scoreBoard, 1U, (UINT)seg[1]); - SegmentDisplay_setSegment(&l_scoreBoard, 2U, (UINT)seg[2]); - SegmentDisplay_setSegment(&l_scoreBoard, 3U, (UINT)seg[3]); -} -/*..........................................................................*/ -void BSP_displayOn(void) { - SegmentDisplay_setSegment(&l_userLED0, 0U, 1U); -} -/*..........................................................................*/ -void BSP_displayOff(void) { - SegmentDisplay_setSegment(&l_userLED0, 0U, 0U); - GraphicDisplay_clear(&l_lcd); - GraphicDisplay_redraw(&l_lcd); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - -/*--------------------------------------------------------------------------*/ -/*..........................................................................*/ -static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { - uint32_t *fb = &l_fb[y][x >> 5]; - uint32_t shft = (x & 0x1FU); - for (y = 0; y < h; ++y, fb += (BSP_SCREEN_WIDTH >> 5)) { - *fb |= ((uint32_t)bits[y] << shft); - if (shft > 24U) { - *(fb + 1) |= ((uint32_t)bits[y] >> (32U - shft)); - } - } -} -/*..........................................................................*/ -static void paintBitsClear(uint8_t x, uint8_t y, - uint8_t const *bits, uint8_t h) -{ - uint32_t *fb = &l_fb[y][x >> 5]; - uint32_t shft = (x & 0x1FU); - uint32_t mask1 = ~((uint32_t)0xFFU << shft); - uint32_t mask2; - if (shft > 24U) { - mask2 = ~(0xFFU >> (32U - shft)); - } - for (y = 0; y < h; ++y, fb += (BSP_SCREEN_WIDTH >> 5)) { - *fb = ((*fb & mask1) | ((uint32_t)bits[y] << shft)); - if (shft > 24U) { - *(fb + 1) = ((*(fb + 1) & mask2) - | ((uint32_t)bits[y] >> (32U - shft))); - } - } -} - -/*..........................................................................*/ -/* thread function for running the application main_gui() */ -static DWORD WINAPI appThread(LPVOID par) { - (void)par; /* unused parameter */ - return (DWORD)main_gui(); /* run the QF application */ -} - -/*--------------------------------------------------------------------------*/ -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, - LPSTR cmdLine, int iCmdShow) -{ - HWND hWnd; - MSG msg; - - (void)hPrevInst; /* unused parameter */ - - l_hInst = hInst; /* save the application instance */ - l_cmdLine = cmdLine; /* save the command line string */ - - //AllocConsole(); - - /* create the main custom dialog window */ - hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL, - &WndProc, "QP_APP"); - ShowWindow(hWnd, iCmdShow); /* show the main window */ - - /* enter the message loop... */ - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - //FreeConsole(); - BSP_terminate(0); - - return msg.wParam; -} - -/*..........................................................................*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam) -{ - switch (iMsg) { - - /* Perform initialization upon cration of the main dialog window - * NOTE: Any child-windows are NOT created yet at this time, so - * the GetDlgItem() function can't be used (it will return NULL). - */ - case WM_CREATE: { - l_hWnd = hWnd; /* save the window handle */ - - /* initialize the owner-drawn buttons... - * NOTE: must be done *before* the first drawing of the buttons, - * so WM_INITDIALOG is too late. - */ - OwnerDrawnButton_init(&l_userBtn0, IDC_USER0, - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), - LoadCursor(NULL, IDC_HAND)); - OwnerDrawnButton_init(&l_userBtn1, IDC_USER1, - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), - LoadCursor(NULL, IDC_HAND)); - return 0; - } - - /* Perform initialization after all child windows have been created */ - case WM_INITDIALOG: { - GraphicDisplay_init(&l_lcd, 128, 128, IDC_LCD, c_offColor); - - SegmentDisplay_init(&l_userLED0, - 1U, /* 1 "segment" (the LED0 itself) */ - 2U); /* 2 bitmaps (for LED0 OFF/ON states) */ - SegmentDisplay_initSegment(&l_userLED0, 0U, IDC_LED0); - SegmentDisplay_initBitmap(&l_userLED0, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_OFF))); - SegmentDisplay_initBitmap(&l_userLED0, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_ON))); - - SegmentDisplay_init(&l_userLED1, - 1U, /* 1 "segment" (the LED1 itself) */ - 2U); /* 2 bitmaps (for LED1 OFF/ON states) */ - SegmentDisplay_initSegment(&l_userLED1, 0U, IDC_LED1); - SegmentDisplay_initBitmap(&l_userLED1, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_OFF))); - SegmentDisplay_initBitmap(&l_userLED1, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_ON))); - - SegmentDisplay_init(&l_scoreBoard, - 4U, /* 4 "segments" (digits 0-3) */ - 10U); /* 10 bitmaps (for 0-9 states) */ - SegmentDisplay_initSegment(&l_scoreBoard, 0U, IDC_SEG0); - SegmentDisplay_initSegment(&l_scoreBoard, 1U, IDC_SEG1); - SegmentDisplay_initSegment(&l_scoreBoard, 2U, IDC_SEG2); - SegmentDisplay_initSegment(&l_scoreBoard, 3U, IDC_SEG3); - SegmentDisplay_initBitmap(&l_scoreBoard, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG0))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG1))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 2U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG2))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 3U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG3))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 4U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG4))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 5U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG5))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 6U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG6))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 7U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG7))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 8U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG8))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 9U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG9))); - - BSP_updateScore(0U); - - /* --> QP: spawn the application thread to run main_gui() */ - Q_ALLEGE(CreateThread(NULL, 0, &appThread, NULL, 0, NULL) - != (HANDLE)0); - return 0; - } - - case WM_DESTROY: { - OutputDebugString("DESTROY\n"); - PostQuitMessage(0); - return 0; - } - - /* commands from regular buttons and menus... */ - case WM_COMMAND: { - SetFocus(hWnd); - switch (wParam) { - case IDOK: - case IDCANCEL: { - OutputDebugString("QUIT\n"); - PostQuitMessage(0); - break; - } - } - return 0; - } - - /* owner-drawn buttons... */ - case WM_DRAWITEM: { - LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam; - switch (pdis->CtlID) { - case IDC_USER0: { /* USER owner-drawn Button0 */ - OutputDebugString("USER0\n"); - switch (OwnerDrawnButton_draw(&l_userBtn0, pdis)) { - case BTN_DEPRESSED: { - playerTrigger(); - SegmentDisplay_setSegment(&l_userLED0, 0U, 1U); - break; - } - case BTN_RELEASED: { - SegmentDisplay_setSegment(&l_userLED0, 0U, 0U); - break; - } - default: { - break; - } - } - break; - } - case IDC_USER1: { /* USER owner-drawn Button1 */ - OutputDebugString("USER1\n"); - switch (OwnerDrawnButton_draw(&l_userBtn1, pdis)) { - default: { - break; - } - } - break; - } - } - return 0; - } - - /* mouse wheel input... */ - case WM_MOUSEWHEEL: { - OutputDebugString("MOUSEWHEEL\n"); - return 0; - } - - /* keyboard input... */ - case WM_KEYDOWN: { - OutputDebugString("KEYDOWN\n"); - switch (wParam) { - case VK_SPACE: - playerTrigger(); - OwnerDrawnButton_set(&l_userBtn0, 1); - break; - } - return 0; - } - case WM_KEYUP: { - OutputDebugString("KEYUP\n"); - switch (wParam) { - case VK_SPACE: - OwnerDrawnButton_set(&l_userBtn0, 0); - break; - } - return 0; - } - } - return DefWindowProc(hWnd, iMsg, wParam, lParam); -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -#include - -/* -* In this demo, the QS software tracing output is sent out of the application -* through a TCP/IP socket. This requires the QSPY host application to -* be started first to open a server socket (qspy -t ...) to wait for the -* incoming TCP/IP connection from the DPP demo. -* -* In an embedded target, the QS software tracing output can be sent out -* using any method available, such as a UART. This would require changing -* the implementation of the functions in this section, but the rest of the -* application code does not "know" (and should not care) how the QS ouptut -* is actually performed. In other words, the rest of the application does NOT -* need to change in any way to produce QS output. -*/ - -/*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; - while (l_sock != INVALID_SOCKET) { - uint16_t nBytes; - uint8_t const *block; - - /* try to receive bytes from the QS socket... */ - nBytes = QS_rxGetNfree(); - if (nBytes > 0U) { - uint8_t buf[64]; - int status; - - if (nBytes > sizeof(buf)) { - nBytes = sizeof(buf); - } - status = recv(l_sock, (char *)buf, (int)nBytes, 0); - if (status != SOCKET_ERROR) { - uint16_t i; - nBytes = (uint16_t)status; - for (i = 0U; i < nBytes; ++i) { - QS_RX_PUT(buf[i]); - } - } - } - QS_rxParse(); /* parse all the received bytes */ - - nBytes = 1024U; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - } - Sleep(20); /* sleep for xx milliseconds */ - } - return (DWORD)0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[1024]; /* buffer for QS output */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static WSADATA wsaData; - char hostName[64]; - char const *src; - char *dst; - USHORT port = 6601; /* default QSPY server port */ - ULONG ioctl_opt = 1; - struct sockaddr_in sockAddr; - struct hostent *server; - - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets */ - if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { - printf("Windows Sockets cannot be initialized."); - return (uint8_t)0; - } - - src = (arg != (void const *)0) - ? (char const *)arg - : "localhost"; - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName)])) - { - *dst++ = *src++; - } - *dst = '\0'; - if (*src == ':') { - port = (USHORT)strtoul(src + 1, NULL, 10); - } - - l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ - if (l_sock == INVALID_SOCKET){ - printf("Socket cannot be created; error 0x%08X\n", - WSAGetLastError()); - return (uint8_t)0; /* failure */ - } - - server = gethostbyname(hostName); - if (server == NULL) { - printf("QSpy host name %s cannot be resolved; error 0x%08X\n", - hostName, WSAGetLastError()); - return (uint8_t)0; - } - - memset(&sockAddr, 0, sizeof(sockAddr)); - sockAddr.sin_family = AF_INET; - memcpy(&sockAddr.sin_addr, server->h_addr, server->h_length); - sockAddr.sin_port = htons(port); - if (connect(l_sock, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) - == SOCKET_ERROR) - { - printf("Cannot connect to the QSPY server; error 0x%08X\n", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* Set the socket to non-blocking mode. */ - if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { - printf("Socket configuration failed.\n" - "Windows socket error 0x%08X.", - WSAGetLastError()); - QS_EXIT(); - return (uint8_t)0; /* failure */ - } - - /* set up 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PLAYER_TRIGGER); - QS_FILTER_ON(COMMAND_STAT); - - /* return the status of creating the idle thread */ - return (CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0) ? (uint8_t)1 : (uint8_t)0; -} -/*..........................................................................*/ -void QS_onCleanup(void) { - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - WSACleanup(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes = 1000; - uint8_t const *block; - while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - nBytes = 1000; - } -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ -void QS_onReset(void) { - //TBD -} -/*..........................................................................*/ -/*! callback function to execute a uesr command (to be implemented in BSP) */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - - QS_BEGIN(COMMAND_STAT, (void *)1) /* application-specific record begin */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_onAssert("command", 10); - } -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Makefile b/examples/arm-cm/game_efm32-slstk3401a/win32/Makefile deleted file mode 100644 index c92e8a69..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/Makefile +++ /dev/null @@ -1,260 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Game-GUI, Win32, MinGW -# Last updated for version 5.6.4 -# Last updated on 2016-05-03 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := game-gui - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - .. - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I.. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - mine1.c \ - mine2.c \ - missile.c \ - ship.c \ - tunnel.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := \ - game-gui.rc - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -O1 -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -LIBS += -lwsock32 - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/BOARD.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/BOARD.bmp deleted file mode 100644 index 64875e3ca688d5504721f91bb12ffa1b1b7770d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1659366 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

      a|~)~NzoiGE!|&Gus1JnPj24c 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
      22zsN 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

      {XmF^)FmrQD!Cx=|VjvKLJ#?ZC#C=?@m9 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∨Tivqmj?sg6jUPKVbm&ym*1b(z_Kt&I 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
    2. nJ)-V+!HGn8NWDz#vE(%TD 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

      {BPaM#YA5ie{* zxPS;|mZk_IWEX;nUT7$2;?#kvjaPLteQRhc_4K^|qCe9%G&V-2tzPr-o&)=L@81Wr zoj7y))S1(}_UtCSYv_<6VWCY;46(Y9>!UWabxcfw*}^Y44n2Xg&_`aAH5I}qmM zVlOj)D6ttD8X23S_2D&#U$+jr8Ur1etuifbcv*Spj7)xaX1u8x=<);i@o=9wdi1il z-)>t`4sXPVhqXvd$V*Lu)_^w#62H-xW@lIB7lL7>Ezq{*0&jc;%;2|H*|{w5P|~Vf zW$Wj9_Ijajf0&KNHmn`mtIrGl2evLMhSpwwegyp1rLuKVMpkKdZmXQUwiRXjc5J_M z`$YuApFOi=*?aC@?re#Q67eXBO2$AK>4;RQCJi`S zNwk_88{#8}!!T?}FZrT?XZWZ{{Py2rHu9~#7Hzq8#tU_4TDyDq*K3D&?|XOFrvpmg zY2gZ+O?DRRQjuR5Jfp5?9k$o|neAa%1W$Xx*&gxiu3!D%yaP?Wo$F>cLn9Mxqr8TRKW#m2{Mqa* z%_`H=UZ|*OlbGagC2NBJM*{)ZL*WL$i3pcS z$@sL2+=ESeiv%Nw20g&$V}0>Y+3}~sWU*{(jY@=p-TL6MA0oxU)RoBMh;9&qKqX}1Kw)Vnlx4^*%=f_SUfHoRGcowrlU@?t!#yOzeCUwfmVZw4T}io6J#v)qm{{g!{TW$RFX)hK-ICilTlA z6_9}r%vO?+&@V5)A~ueky7*>EwX0A8ndoTKG#fXDMiL^zGvnhVU{f($ep)Jew#tHn zt`${%I&`XT*P&Ot4qeJCTNk#h$h&7S?cKg3tE7b(OrbTbqG;jJ#kFl&f=RS*=dM5+ zv<9a!z%YuEts=iLKPxjSCYlxz8cfM!f-=D>pa{W*_`+OE@-)73Zd}WV7l!ZLu?;mE z{kE-NV;jxO&1N}GvW+6>U^Wb+7cZPUe(cD}6UQPW!dQh2WCpGh+o&WSr6rIdldBp@ z#Buzfl-AAb*TJ^Zmc{O_ZvMW0)jfK$1Qc|2agrn|JqP7*%p(yRXN#hb6J}19umOz$ z%~o#Z=j};lF2GDuwTVckEIm^T+y0fzhI(yIQ{5e}j{E8RTMv6yU)b^0mt(rmPji~; zDi*7Hq&}?{s;R#IX=YO)oTPk%#G2|VI;AO=zN)zPUYb+L{SIxkn zp4lGuhyFJ$e=5v|TtZ^d5GImkfj3Y@hxi_9Z%fz(j)F@UE!(nb%krhmM?60wx_NW9 zBwriRPq-@^n_G12)%Vl&Uv1yBf77;|JN6z}w_)>!E!(&3+_N2%=l1O{3?FVSlM{(0 z#@}jbnV6ZyCM71NrKM(OX69rU;wD&H(yV#&q=dw{m{@P6yBfApH7#|0^(GHsHaBX- z*Hya;dC1Av`?LMECw%?h|F%02;pg^fX458IkqqPpm`Dwb^stQ<#>8|>OD~Fu^tX4Q zKop5S8mTohH#YKfbM<*tL6y(lYQ2D#Hvqq(?PtF^sadd+WCF8yYqm=25o~%*G@Vr!gS|2#xKTjm9b#N-|S9(7`1wylL36 zBS&Di-0U0&J9{q=&z{}8Q$GvMUSNP9hhQ&>C#5l8IR}7^Xb2l?8D~OcAx$JhU2Pkg zrN57tqn!=9H5IdgXDHliY1{sN%!Y>T%_Qd&pRIV)qhvf*Pk2w zb!JncmrC=NXeVabrAq0;J|E0i#M%DAy{(?v9(J$(P0ODOvmqi>%*OjEVg$J%2@vY{ zkv|Owzm9D?_3YL&Co9{_!^;vsHl@2SaY^RpCZ?8_>Q_@%@L7 z?b>&6$DaK=ckkV@aU;w|#w5|7jYg~#DR#;GK{ge0bN02ivvYKICd`RAFSfyoiY=5) z>-B8^HfX57p8x3`5dGQYb@{UqgK*EE4L2@a*^Tub<(4p8=j4>4@CaW!JA$||j5g6| z5)$Cosj9L=d6}<=I}8J}WyHlw(FgSSv!P@wZjnXS4gx}l_3DE@4W~6c)`s`)+qJTF zIeN4F!p>zC&|2S)ong5V{RXgV^uWOq&aoD~+_<5`XHS?!48m(ur$cV2+Q2qE-0*6H z*(Qz~J7@aT8B->We12F-Q6bK3FcqQ5;u$2w>*!;)J%1fn*z%*sKz9}F&hB_^AhCWT{!c=C-tc> zK3v&3eO7?_J;mB%XLYLs=bj?7so)KtH%eJWn~P;hcZ*dtAMn|=NfDy?yOFe>*&c9@ z{&kC<3bRQsl87c`1zLJkZIbk(huO%uLTHA+PXM%LEweT!OC_o6ly90CMu|%@HZv_Q zD_i#d2j?zcI)CZ%h06%OYiG`1V0`VyjkBjt&7D2l*%9jiQTK)hMn(jp8<>~`hKBeD z2Zcv9OH4_jJcpTuMdOBzc%7vYiKU^gPRXhV`?J-@ApB1s{q+a`hu(ouFDE-Iv$|st zq)=;sL0eBt-$;*KAI0%;UDML25g+L2q}iw;p7Vq!WTqxhpD=#<%P*(I$3i|enGGK{ zfKA10{kn94*?P8VhXWg0wV~C$yH~XV$g4hzizN*kSVh`g zXbp736%7PpIbhbKd)If~p8xiOw?10E^3ydRO`kd?FDIMjndzx0!H64ud;VMax#7%) zVH9;7=|12nM52Ukq8U_OjhIbx!C{J}M+rs)sFc0T$<995KcH=8)qp;ILj!}n+}u4} zT%*Dx#*P@-x4Ngdha0=FG4=lNPs2-%#*SbcEXRT95w;SxNx&v%UD45E8>z}OoQ8T$ z%Jm@;T21rlzl_<4>wKq$`>#LMj_JF3^6+PaDzKS8MOu?U?v)^6ux%m{oqw+8l#0`8 z4G36ZPFFz@q@kEPRB?Y1)Qe{nk$S%$w4T}ib%6GO3wkQdhFIfuQWAQS=s;*=Fr~M% zvnebrgxPYl@(S|`k`s~~?Hs8U589#Fx3DlFr-!krQHRbQzu54_H@Cj|?)&fV{CwxT z+uz>&?k4T_54TCv_rZ!4B(x-~fa>ogAT}{KPfSgHd(peoX3d;BbH?;pvqp{{ospG= zg%)6=a36X$@)|d+j~o4m!a@CM|G&HgkBmVOYgg$RU>gM+h;ziB%|T|Ntb>pavjsRh zl0z2#8#Usa1_ci5-*5EL=VBux;2B~N(qm(=iUMpX*)WVsJ-I%5weJ9rVE_f&U^BF8 zr1*f@a9tzrKr)811XnlAqv+ybHgFEFwqj*YkD4XU{o;ZGF*UoM0 z*L`~U(Eg1Z*6-W9>(IfyJGXDeSg`){&%Hgp#Kc0BAu}{2EHFg6L>$qxnt4d~9qDwY8)e1QM2MH)^EOpn-N1F|0B%G6H6kLPycC z;mHQGNx=wtDJjqwR7S&54NfCmw5p(puPD=iw^l83B*hv*2L-9=IJu#DV>w^jm9#3( z%FazrMakBtWeLni7y?U*GP4R=WaW}bq#!>#BP}G*AAJ;QJ%|+GWFRrsfH9&>qA$2h zl5D865Og9Jq0CYm7uY}=fO#zBtIG7iawb96VV#7RP?W)1G!$hnj`m;}hjy^F0n+T` z)-Dc?J|3QoZDn$2dk0TfHwHMQxjH$pi-dV>&%S8Sz&6aRIHE`~2w)rhCUGXG3S>%w zqUhEjX~<1dronp@>f$v1@yvE;=Q3p-g!}Wep=X2Heo>Ym`0=}McF&(YCqx&&HJsdj z2d$@sZOr*btl6a<>o4p-c4UuY_6RYL2l}x;jc0Z2h|Z1tY|YFR%U)Ofs4O^e{#0Ge zmiCXz&-O2-tfzZvPleeKN{A-Jlq8_&5q-!mL^S|-hptxN7Sy; z6VqrL5m!Xis6K%RCZ=*zqx_g=UDJ|Fn@0vX*l9OzsG-SkQeB;VWepo@Hf+?SVPh?A z-I&l2NzaC=O^QK~$W1H{nx9uyRMeww+ribDm32so zBrT}O&86>9TH3X;qHm|p1dVnouOyW&&TP;1>eIQRO475@qi2f<4hr=4a<;dHXMit> z#6)1D0D+bke*6SH;f}#TS&>kOdef$+CP+FeOL2+XNG=Tx6S0Vt2xz1>L6^n|-hyfoQBjGbU_6{c2v`8P05B&z8+S(sd%4WfT2B2eCwo!n28KD>iI&rQ%~}qgxjQ-9 zSeV<(tekADoo#I#lrawua+w?rn}r#UDBu|B0-y2Xz!7&;|vhFo1(fqLyGQuGqr}1QYT92v+=hQv4qYh?UnB(=+ z?OO+yzP2FU4c!_ZZcm-oqzOgexkTA7ckW0RyK;dT%lV9$O~N@JLCnuq5U5!7wu0hT zQHBrIv(+=()A|?q|7xDcWHzKwt%h)`+2FLAO_Uf)Z5zFfwS3%|(MJy*`}wDzfBET` zo7Zo?vtU75YBD8JDC>#jb9Hg<)w6p1OE2~7)92lH-dVA1S#eQOw=P}EN=rRlU3n$U zNKL_+7C|J1%)7Wa&6qv&#HkY(E?+uz?(F)nz8w7Ab1)kkwkC~5Y$M&criNx?lJTl( zYGLHK$85GeGP0;Q8d-OZ`1_g7(yX4@o+S&^&;8H117W^S4t2&LP`ZjVuSVj}nn*=s zBV!XAbCcr4nC_XWrBM-qj&_FlG|hJ4jMGPFEI#}uvukpZo8tQcEv5*wk%RLsT67ZlHzVvl_LfW zAeHWbZarYO-W@wLfZrtZD0b5F;-Vg%I`-|^qkHF0c`dTgJ`uZw1Vdiof<{guTU%Qy z70#M9i%L4w7NpX&NN-e}B6YBtSy)6w=Pq4(_39Pi=MS(E`h;4MUHK1!VjiR=5LH!K zK5gpcnKP!18u`Mwv6zAfQy&547$gR>!C-C<_VkWQYbhKBO#xSu{*3_&F(}T%$c?;IRh(S@#xrL&$PFe0+lWwTm!OC;_#F}J{n`Fs!PPT5nWxTdNUfR; zu0w6rJSuYCXY0?OJ-=(mEEstd*4o-hl{zm%3}j zi}^jo3?E|t9*S4#>gmI5WvL0>Gg3;UB7>bBU^ZPn62hvdB*c#%K5WEuLt~mno0?fj zxjv*Mx~jNQyxK~#TU1f-y{ND>Cwpk0J|hPW?Ay6hJIaaX=AvYywWcDxvTsxLf9#zF zcobLLhJ!|kL5RD%8w5!R#N8E0LIg+x2@b`z6fI71E5)HuT#J|D9=up__m=$k?7((O zfYN^D`=EdJI@k2KawxwEH{{y2H! z7;?M2c5X-5%~UX^8JUq&psQnVX@Tj?QetEyRt-W!cm$#o-Jp;p9S-9dPz_TX1~=?- zyan3?Q=6`KeV;mC4(yNaE>a|C&zwGf{OJ67b5m22xCTsWnA#vWoTR{;G`tORqy3AS z4ekQlC}HrIbaDSGt^HwV3;1s{n`m%@+{*Z2E12ygVbUix?LW?J;6ulRWqAtSqc;DM?AxpIWqF0oJzueftIn1Yp}| z%|Rgmw*ymgqP4Z<@UKT~+qr$+#tmyXZdkB*amUV`C54uiv9sYD1>O{@%i|kWuMWml zMf5{tHhiOPLc%JT?c@HmSIqt|y#qpxc%%1e>JlAfg zL}*jL2Hw_|%D6;pP@+yLHY#FB|NcEYcky)fsI93j)1l4VR7`JDQrBYHDigkTj*E zgQ+dQO`8pyHXS{BbjhMcUym3;LKV158UW0Og^fo`I{tnQXV01;mLJ`@V;eOTepvB6 zrR2>_jHECIvpHB<+FM)lSZZr&p|7p!;$UZOZpzk`5MCQ=PgiFQaTwV+%+uKkXD)Bu z9PBaBfo+<#YGP!YK6NtEaOlEay?W)!mCHYF+1$Qe5#NR9ToNCo!EB;L8we+%I6&@S zYiIj=^i}4p@sgsVe@cCS!_Ee4;ok(e-V?g^_l7E%?URD5k90Br6th87Fqmu;7eH}K z?v;z9tBH|`wx+hVrM0n<5fKqWCY3@}%wvRO)T`?g9un$Prw-LZog5rvqM{-~!&+o! zb?eeOCNlih;v)%=<3vkK^I;>0uidb2{pL-Zw{2a%awWb|auWzF5$$X>2%4!{t&02` z%;sop)Fv#VFgUb=+5V+WQSr4t?j88kcs8Lxu(GO#8j0Xqs3)R-O|W}@Qf!B~s0@F< zI@Xpos#L04trF#{Tpa9EeNe%NFTOf@_A3GZjs6(F(DP2@PCJrAt@QWUJNJ&Y+D=Jn)$V^Y2 zJ$1^~4eJl=`Dyd|b$xntm#j!aG#U~gjT$wYKYxDb&Yh`PO)crKzWU0^$qC1(mX;R4 zhB9R5Ze0%?I{53gUw3ZbPBS+(t09n@Q2L7KHL8oU9^#g35o2M%oBxN+T@H8djMTIc2B0$}kW7oSr&5oRNv?Z@p~SFc}7vG{N2eOJ(? z4Kg6;vsIR>gq@A@^2#-oMP?&=zbZPriq##A3=2cTDwyr#{;pTd{_nj5-i~G_`kL?2 zXG3_66iMRQV76MdG)WwFurzDmJgrx=l-3cU{%$ThBq!8Ttz4~A)k<>wVXDfLj8Gk? zBFrY$)P>wASw%1#*oK|0phZ?+BGdZy8!=$O*MkPN%gqsdpa}`Iyp)t~ZQ67xDCpF> zb;nk%+UMmF#sj(dcnw&s{iw!j^ftnavCGa@!RaP^qDRubzz?)CbsFG)vEFn#K^>6HSv6iF4D@ ztW8D&aEP)l^Yghx)3Hd3vB%_=0%;H$TONDaVqt^dq^3661cZN6Jew?i{hhv>;8#7l zeD>qp*H5mPy`^v7lI9I(G}f8mT3N_E^>`zl;ZK>(LsA&jqgrXOacN#q>5z7%Tb7qT zd0e`7z5s9kY_>uLvwc!<^^q>-zr$>J3O26Ybm8oUU(WrqaoxtOj0_euV$N_iKw9W> zc)GdA#l$4U#$`5Zo|lsYzqQEB{Bq#HS<|OuXJe5eFhfurl4RmjmlNR5D1wfG?MB|Hii#SVx-H|QIwizpH1_kbFhkq}I~%@HWrgZ$^71Ox zi8_@hZ&a)|N+g@upf#8ca)a3jX6w|ZaNN+LBL@x~*u8skPBs|_SlF7!#I#CFgVsPb zK#s-`>7r6*%SlNkn2nIOkpl)1$%bPTuPE3?Cq6VhCM*;jYSOTQgN+q1!y_S_1MmP> zq(zZ8N`g88Y!t_9(xeIZ)WN}lkhX}(NSMvo+&nBYvUw(D3Yx{o#M;~1@tkO=t7mU( zV{2oD+(wnkl@t}^k>Cgk4#dLd*RZ~utFuT}#PN!DHfMWV>}-iKQB$$r%^zvjopm(o^b-bIUBxg5o3f=YV*#m5&QmU)H9l~yWiixoy zD9A@pnt={q0d7S1Lu4}|*+hdI0l|c^dAhlfiBEzs42mWzpW4S2fAqCjj zbL8OBCl8-Iee|^Cc*!>tCWM6qQ?7s_2-L139n00pIVCYEH#?_ML*D`Y`T=jP^I8($ zo1Bn9nPZk6793Vnrs63QW}7m7>gKImR;^ouMB9|<(^}-@XlQDZeSmuuY$M5DzPfxl zX4B8FV78C=lU_0Pzx)pTX*}Dj90c5ls^k_4IS6Qdqy_n-^#QXraImW-C>kVX18_g*Vps)9XV!9 zbZl%LA0Pk5jh!8x2=M1QkrI4{dV1uFvewlijX_lzR3l?__pTk=wr=@;*^ym3 zHX@9YTbb!;@sSZ2*~mx0UPmHo=T04%|Hmzxc5L6ur*vpv?C$C;L>4M55eY1ko5-aw zTf=&FLxTb+tWd#hvgq|jU$nD*Kdbz2==PxgO* zV4IZO#6BjqGbLvc`heN)+`NOJM`T18*=4vI&;`&Ycizhz^V*QXgR!llpgUsNu(@;Q z^zPZy&Dn(%cvc?P9~MJaLa@!s(tOGHOOKs6cHqe2-FttgAVN-F9<{4TKp=sOoPBwO z+7uKkRhR$6&Zbb!&OkpuC?r2HxWdl%FK3I2ulI58z@NsmVP_+6v?it~^t}XCv)V9Q zQsah&;lbH~P5hi4YZ1Y!SWQJ;IXNM2(%3QIj2W90muP8a6YA#+u;CSz>a&UQY>-=8 zY)l5pp(!ckkmjbRlY`JSI=Wd*48Vq|tyyd=Z=1%%WW>iqYq(9>iunkInOVrP^=Q|D zO7RGNz-+ij$v(h6O8KgmEwc9Q`RUrFi?qZ0_f48G4)YWbdn_`#x;og_x_0dv5D+kR z>Qo$~ix)56uwlc>l`HSuy@QDN&j@usRwM4U)& zULJ1LM4)Q?-8;8#TqpMJ3QR>tr=__mtYxgPOO%?EjWsYPGFxI~M38SoS6dsfEfj^} zpulJhkD(z%yKy9jHG}-L0k8fRn z@$?xYZHuRtWj0iB`?Y+_Pw}V2Y`^_hI(_<(;%DK6vna)Tq_6qXPzT?wH-X4@tlC%a^}TpS~5CcNym@!8USAIwFn++R51r7j-}o_O<~%P~bnNu$3mrNP4hhM2caO2Q4zjfk zsZ%E*CZ=Hc@agcI^n=9C&6`g~3}4p2|5#=&|8*Wbcs6q6vi|+Xy>%3voI7_{zkZWt zzU+kl{U;0^I`!VYhs=NT=HvHFe(Tnw;lme~`RLxgN3UPMv&=>E_SC8Ky?Tub4bAcN zjI*{0=FZTGjBLf7|Ml0K<&T%{`A3*d44)A3OuA*!5F2|q;K0uZ?%ce6@+c*bf9%$| zv#YZs@f}FCQM5o`PcJ+yytt^iZ=b#k7cShodCTGj3zsfh+^(qD%*fbKN2iXvn}H4? zZOTMy@C0jTXS;6G2E^H}-n?<~>Xo${H%Y55QSa;Qw*{Z1_9;b$3&rlalUE5IKx*zA4uwvGV zJMekj0dGfy!roVJRKjd(>ipFR>{hFmhK7;0hM>hg-!n>6z6 z*1lbb!Zvli>R4D>he()Bw6h8D7A%CcC545hM@P46*0fc#W(lDoDUlIf3JZ%`w7`tk zoa}?-WS9-}8qyzmX=(Y*nzhZ$D$K~p!R$tEX+i?b)}>8R_jc`jw5NVmVasOCo5shd zL`A2?#AYTX=jUYa-m(3{=~L%RPVWC{_sl7iDUnKMx;kcjW8;+Mlrx+zIE%sZ1_e2Hh-VG4i@Hg z;)&&piB5})O^=U@4GZ;hc1n(o&dbaoj4eE%NpK^-x^Avc)>bA4`auDWCruo`W%H&V zH*eg(ch8}N`{&G>nHU$#vn?@fa2io1BE0dI#z&(cfhJXb3bT<|I?1c*!WgUJfqBvPr2+b7L)89<%oZNlA|@`P zNnoI>o}Q(goS~dt%ZLc+PrtPD{CR1^1~V&HN|uxJl#{cUG%Gndovf^G9P{A8Z{}uW zs#Q&tlXH_9)$Gw@G^3X5K1z4UkSXH)moMKCubp<)=_ere0@HTU)GANthfUo=MH$; z;g5S?4uZNQ>R$NEA@Ut|Q>|g7U8`AWlQxmTP5tV7TU*pr67<c$2Jk{_BH5dnR5$jzlSi;f1vdbexev#7XjW+r{yql~u8>B$ zb(hxpJ=zxaY2Tr1egVuTjsklf3ktqy-@ZqO4n=u++39J`5)(imp~b~!Bqt5%(S7{L z5tGM`>EE+QfL}xOxCz?Fp3gTVLZjyw-D9Joj~_jH?Z)*MfxB{dETN=Qiw3J(j8 z2%j})&dF0HsJERscI^JWd&NaXww6}tvtg_geF1DqmM7TE!QR#h)egy)U^D8F;u^(1 zhCUlIYf&M=_(mJoujlLS#Z73M5RX?hIXWt=vA>U-D}8phYuyT>t*gZ)Z#vtg3a zFLbn<0X%~SO=9%=^%sGGjQ(J5HqzL*r?K%D+FEHhQT`eqzTU$?YuwU%vy2i_MjibX7bF)!8I@wjLI#;f2GilNS@f5Zf&Oi0@ z-D_*J*v#xJF4)M33(nw@3JV2rx^d%0WBS8lkl(t*-fq2x#W*gB zW@y-6T|Hb+xADb`zrK5NuY!UvC8N(8HrQipv((IVFn7bqsH?Vi)5?|HyLKHRPA(jC z;Z_~*ek#h@dU~DB&4=39%y4r2-rH-vx7S+9ml~<3+frTuVl?gBcbxPr+0KVEn-s(T zYDcuTHLBmp#vDyf6Rn!H)oRpGR)nXj^SH-CLH*F2R;_2wnY-eLRcFqgzjWaeF>eR< z9{6$NmSqbTO&&9L>38$IUEOpf%tk^eZqUr!oXOLtP5*Yz_$iayb?)Tl<5P)bhN@Lj z)&=Ttk5;8Jj)d7N)sTnTl&V#=*Eh%t3y0bK9UR|dXL~!dIogHzRoK}+4hmGv`kCB; zx{lT+dfM;F8+{kEwT%qUY~okn!A^rC%PVftf>H8G zY1t{st(rIM(x%OqJ$sV8(5aw+VhZTI(J~SfQe$KM>UiUbv^6s|)Yjse4oX4Q5i((Q zBAvZnow}~hE(iAQ+q7kKVcWJmC*tzeH#SC}O_Sf7cI`I*_~Y4gXLs$`v2w+VhV>h0 z)~ux@FHaB%%cF>G*xYzrRgfofy(*SBQac$U2f+$*qws;D0kR&%stLj!)SkDp#3hPh z4S36>vP08!2s0@v5{D@}Nk%AYnK$ywFDH)~GiB`9qLwYmO(5FMlq7szZK6j|;$=?4 zZ%TNS8%IAT8 z4$StlTi0{ZQO6q8-{a!^BMq`rR&H9;bd#0U1O@r{!Gi@V zyLIb%Zf;3b)Uo>YICray^CnA+G0Ms*c8g$h`O?$O%#-0^N9%a+;)0!>H(6Uv zQm&EKR`PXj-+qyuT@o2_tZtn*M%%QJVAadge*G>)M<4U^-6vj^qr(q|hCNM8nq9hd zjrlKMe(U7vMMVN%UAg=$Gvj1L_%UxU$>dHOtgOZ>DJFl>{TuPx*cKJ7)zTU!LA4bw z&Re{^xE058bIx?^aK2T`a{)~bIy{LEH1V-o+xP8In=CGyGi|e*x5v8!z&se9Gn~;9vcvl92$ytZhq6I zBC~;Hyam`qBO84>2(__?t%z!{93Tg|QPxV7;U#&YV}5>dUM|c=F)Wy^c|ttaHgG7U zkzajJ52D2o9>D-ry-FnlFoXi|@(QFfQIv{sFhwP$qW10j4;qx0-}=_QyOy@LYc_01 zNKRrEa&mTt>ohfLSE*bX9S|YwRH(453ZbDK0;HuRCw@6_z}V5Fx_9du8%+#vh=ZLC zo=HlJLRskI5|c(wXlh(6HZ-n>)KN1%T`MC)V6v{O3;Y()puUHLJ$U9~W8Ju(58-WO zE0CCg#-)vkv5mQ@gRM1rpe=J+^yu29Tc?iA(^Knsx?@Iz)7{m$9&k@K(WW|G${6cdv8l>Bj&Dcei~W?)&U)7pSV{78gx~6JWNsZBC`9ANOx` zh*7x9#%7k1V)|EK&1Dp3D<~*QPdm=J9`5@++aw$by#u4ZzOs4qy^$j>x6C``*HHY>11`?%_4RtWx)zAc_Vmf`!9hFh zZ8y8S?dC&iZmzq1>h3RUdwS!>JJY6Kg)<|4tsiVD-O82 zY%w+-Y-*Y#Wwy6YUR*3t*_A8L7)?z%-mrl<`EKr&a*fRHJzjZ=SFOBiX|ck|aig2- zPIotM$Zl7c-Q1sL%Wke)cYDm}OL@5^4I3PCaoTKdK1^P|u9a2bg9kz!o$L!{V~KjJ z>8y-n^sUEy$WGDDHht2xpLhPWW6QSwz54prtH;uzBwvj7)B3nLK{+`02gtH#!%$Gt$+sNgkRq;UXyJDjJ!Z+Su9IJ3G@HU0fWT zoQzCNaE+p=i{ghw^g|wIgVy8}s#a4Xuub0C#3VN=8fI%?ZG)TjZLw^^K2@oa=oQINA1e>}pU4{lFoiElKZC@Q37 zSWpuWH`VIZ*j-aYtwr-@<3^4cF?eutLXw@mBg_^R7(nW%AkG#Zo)8j(oh?2vFeNN3 zEh0iJ2ai1s9^);XCLoz4o((+1+9sOa=+ihDmZN1SC+DQ4Vp449B4_wLyK-OL#Y(NV;D;TRP(g?PSoaY1VcQ(Iwver#OaH&Z5W*|u%nrcGCG zTpu-V+_93AZHtQ|qM|x?=|Z-YiIFj@hKf=RWOZ2&VK!Dgw2ayo7OYDlA0o%3xv44{$y=6MO8Ix{P-Wh4B#q0 z?r2=>kp}hm!ECNB+i+QWdj4?ZhLH97?YGy8i%;WPl_1$Z>`VH3J*3Qb^2Fo%_4oPI zJ>caDD1tXT9qd=w*)CtV?iT0n+7idSS-cKcXF?kYh*~7tz(B%jt;x)cteAG`BJVfo6XJUrKN7= z+!rriPM`iOL<;3{LmVBJ>+0kwDS2$zP&R)-WHu42$^)1zwv`|Kz&+yR#}6L6d*k-Q zJNF^CRyn!Y@L4wu^|V1ZV^h=iow{t_x%qBB^6PQiDN;Spm zD1f+_n&w8wz-;xctaWSGejl@`U|oC7Y-*~8dRm@N)*+3&K8N4cifgR610U-Sc-#LO zvw=NA5R^K>?=Tx;6UI6k&BFqUqeEMT!)&g~)hdg=(Tt{P<42Ah(tki$P^f{SF;Vw1 z!9keXU^aZC*x86@O9&2z(8LC((L{a&(f~HLBA%6DHqp+;PHI{;kB<{-T_q=FCXg-~ z*A!Zdk+j$tl+a2JAA0)W{_`h~j~_YQy>llak`3#Wl7harc63A}6{&Kwv#D{gZvDEM zvu918HEa2*l_+@6nfKk$kt6yI958w6)Qy`qZrQY{Q-=;(wKb_XYM`r&ur13SD-q<@ zG%aQ77Rux9*6iPX%V1 zI`wLPtCG;rS9ByYo11H)7|*tT{q2B&gMk4Dy}d-d*06`LKEtIo4{;gp(3*p&jzHWM@G`bN>!o{6duEj z2Ahc>C+&+aQPB!VA3YFcKv4f^)ifRT4^mAL25An+!G7#-n!aq_cRy}ezje#z#S7+B zdVpXyk=e90G(v-dVK!jw&aGQ_@826ec5GHoPW#TC+jZ)Qht#)8<56SB>_2$mmx~vF zxo}~{_um^C7-C}7)zX65NJAi!jW9NQTkFX1u-u#$?TXu?nbx*VL27c6hr27xhO?41 z1geN4xkinHuqKUTLV|JBLS>EW){&wb9mox4!wQ!Y6NB@V)B{pV)8pfb03-yCGVwS@ zyLRd@YueP=)2GduF`X^-?s1R8X81rc8-i^TXQ+@vN{8>r7Q>n>w*5b{v$@Hk&N0ST zs7OT{VJT`m5*@76H% z2{K!c9#gq6ES9-BCu5?IV6haL&B1=DMy;ZpTp@0d7ZBULIX47m+w1DQ+sbmHf_&`Y z!PCW2>9#zxy_MX`lh}vv5huKG>ipw-4{u((d1&9kw)q8AHzo&xoKCRK*1=)e*P||8 zzViIVZ%?1SK)~(Z?R!rjKLzkGwcWgayPpJwc%u6) zR6u~}5E8%_szUiH6~Xr^^^MBf*(AQv_uJW|%!a{D#ZX{2%MgF}&*68q;u5!-qG|%F4*j z2G}BFV}rxP#(y*Mr=RznK6~c!rAw$yT3J{U0$06i71lZ}&DyAZka-}83`w%-$wYwV zgu(>1YoP~D9R!|OF||?lJv5+kqk2C6^?U#}g4tSTGzVV^W&_nkQyZ>QJ2O-Kq$DO3 z=H%oxZ%)fdPA01qI~(zAqIQRetFyO0Y$isv5!fdBNyP{^SWW_O|L>TM zvQwjNgvy~)8)&TUob>a=K0icew-J`(U8*oN&gnI|{S{_|0A~g2zeM9q@>(^o zEM{L4Y>(XyWmyYUEn&4dORH>9n%4ejOC$~?H*|u-H+al{k zTIw;0n^N$8>gjfIb;*7DMBuKGBQ7yij@jCZ%(i&(jp(Q&5#fjMe!^_dPU{Q}2DrJt zBD#YI9(3+}rbGKP>8Zz~qmH_`tkKl`V%DrpOiP-;TiuucL*HnR9@Dt6$B%!PaOP3b z%M6&=+byc8-a0#b7^A%A&%cfvIyd)ZbkyPSup_Q6t5j9neKmN#I4a%3Y%D2a6X8mB z`{7{ro+HHxzhAiQ#NlHLzMYqwnQdief%GKa0rE!C`XDl`-@q>q96ECC`pv6XuTkIX z{MqwYFI~NT{nmrK_o>m0aHX-K5zGdqiNy}8${`n^i9jdf9zvli1U@QN#_k5KDJv){ zS65I*1&X6z=OCykRChKu$%z!=*&5o|{z*I=W<1f(M#XFO8ix8Bo-P(4{%#-Zx3FT~ ziaYQ*+<`yM8+{M63}{|CR*OuivCmBOk_ER#679u;hZioo8%bIMNb2p71pW-UY-P% zX$YwYHAK8oRZ_yyX=7^XDyCaO&)tv%g%p^y}4|ckk>!d}#2{p~FUw zSo;04X;Y@8rKGSr5znSdI(!YqYE`RXXG2z(98x@_&>Fd-pc*L&Vr@|3*@R3_J6r0F zVko1cK|K$5)I3No0L*X`*Y|L5;OU8<6mKbwI5*M_2x%iFfm~MvKzM6wYC^N7ezTDw zvx&}DYZ{%P&1KV>$2pcvDl>`Ev0FFn4$6ty(j*VD(P zyEl~%?^fDGPXcx2v_xdd?UP})SMh9ne||v3T5e8Blg0<#T;Z+_2KwDhP2>1Y=R1<2 zNwgc5G)ZumKy<{jxw*Y!wq;9iFd7+2E`Z2vYYh$hyT10EmXtjH=9?>IA`Bb$OaK04 z4U`buKV`BYfNJF6Y?Tg&*`J}|-hWZPJ z4;LK1vM*U?dn>uU2gW{dNMts5CwEf=W8K=?Dhf3)g0Y^kLXv}kM4M{Onie*;UUhxE z>-f~G-!Q02po^1BBi}}CS{IBTHD=`S;fDGKkQtF|WY3d^0F|+*;s8|=g4h(aP>3G7l_l%JjB=HzN-ZiyUOTxf`xI!fLsYPy)k zl0rjaGcmsaRD-*cLPA6sV+(h|U>qRY+1SG|9LyduLqRmhu?MpobjM)~k<`G6>>+Oy zeYSDKhYuS#fND^BwKXIpBgBBID=QNd%VQvGj)9&&OH2QO12%5iJZak0QRBugU9o)o z?p+blQDmtTM$5`$W@5^Nq!3G?DilP63>}fRE43&?Lg@qjo@<}EodJVjU-;mhtQdHEpTeo(t zTXXRk;z%zw($#6yp#E0_2W(ommNbNedw*WGXkp9j7Qh={2gfK)bAJ4w72Z z-e9)xm)%TAI2!d9W)qY^E?s)IdeyBpYi=!CbYtGU>tn}UZjn_2<}oB;wvtaO2SLhg zve_IWv#F_OWo7jj|G8JMzWvR_E7Pa_I%dq}(W5VQ>Ug$}_fO-;pAbi-+w#l?xyhQ^ z=zk!az3VV>HdRC#d7_ilGT`x(YEBL%uo{;#n|-4muz51h*+EDzl(gS5cIA zG&9MFjL3_K2(-4+e|HXo8rOwWhs#A%R|Q`Wi4s~KPL{!b74d8zjRqIhqi49r62(T3l+XgpE_Ql!GRHB zp=(yJ9QxJZ0sZ?;pEhN~hIMP#tlGSJW5@RGTDQy_Hgw2}72hvgx`g~tGBQCVfQ_|| zZztA4;FxVcZn=Hy294TPx36D2v~Mrj0RR=s8*FtoH5_eiTpa8I{r#v}kCPOe895Rx*!fR1bpf`Og;7uM-Tshkpced*?_ z_MX}A!?sU}*}ms1J%9dk?V8)OXI~pN>T-VmsqpZ__I8UkYGs+4hOAhzEx+|nC&z7m zz6Ye1G+8?v%trFUyO<484iYVCe1zDZKK&gDUq1A6VmA9Fs;U_|Ien%7{QMLD{(C8& zb{eJ7utz?AB`_>KM94w-!#4`8iA`E|3Sj$>nN3uf#B-p5S>*NiAm9cIksHrZzGW z#068b=4;?JRZ&qxxXIMi!rIbGM@yT>L?8`sCyOFDRYOV0N08(n2*3ua$u^Dy+mxyS zYxqj3afsGObq6!!X5nEU&TL@YAI#=x73}BvIsC3xTw}!@_*i$q+tI>E?|sasT2qDJ zdV$p>p#_+o^lH^iY~-6C8r(7@B-GnmS0FY;oQ5Dux8hQGyy9geJB!%m#zWHYuu!9fm|^<1Kv=+r-((LD;ix z>w_EDAKkunbpO5)UkwIq;2a>Qk#BHfnkOYTsbAmH&;Z}4rHN5s<3^)L3_o$?@P#v{&zwAQ>iDs_vuBb_3ZYR5o{t~| z1y19wB#cccXhq{0nU(gfP5c(J+gHpclAD@PO_rvnR^$EcV>8>Wl7oL*2Z1QHHSLpL zJb9(j`p3`Sdwb`%tQhYofBbDMRbEr~Z!_DfZ%fVPN|#Q1@1>L*UT} z46}s=wut?J+EtLxKbkix*xAO7TPj}r)2A_GHUPX zG2PJt{r~-M^^Lxt*~;CRKX!b|zR@yvHb=*mI@;~()M-k2Q|h07Ie6lbAv1;!oilXk zw`_+DnL2Rbm>oOz{qfx-J^r#-N5%FE*renpv26*=CTV4iZ?bRSWnp8#n0Cqv0JBj{ z1=%9{!m=hwViH#pF`z%670mXre)}ut{XFl07tHov zI~(?C>W~OBAJCh`Sgl)AJ;ASGen?Pma8QVsmwrukBJ)`moNcXry*%qUJDVFDY3pfY zSc?h_jtmIOPH#H6PhU!(jQVOwQC_Rmn7EWk!I)Nt*&s1-k1ViB`%++IkJx7`G8Dp!LxUthGP8is`S875$%toviE0VW|dtpKA@ngqK96yfo?lclVK{D1Z@(5VF z=ue$8iJI?sZr=pzXiXY7!cD-E$S5F0hjq-#(wzMWvPDINhXe=u`!*m)01F!l2%@Qt zAT(Pmi$)FWCsMC8EY!ovk;po+9K5%y3mq!RBL+eyDLzv)K&VDa0x2~SFtWjHqCOj7 z2B8%d=A)@g0%@mq#mVt;cGi|SFUUurvK3f}!Hw_57i0^t3E^$;05&dOme$1nr^#$L zPwZQoS@%8lMu|zA8)ft4w%{-OtFJxd`y81kC~lQ`{e#T5bb9HCu7Zf`UwuKK1O8XcmLb+b5Wm{*zrVbE`PsH@_rCk?`q;6TJ9oMe6@`MwIw!}qt}fe= zL6bBwo~@_b>v*lZp3~tIwlBYi*iAlS5P1a17 zyBZ2LhJ5+ef(46LtzP%zkK4Cy*)nP3M99s<&7GVl(b|To4VULDuc*W~Dr;vG`qir| zRF#*fA?H@Tsgn*+PP{0|Nrw+_AG^fWp#VQ%O;c=!Gg(2-zpTDk>ld zV2ch6E@+W6e)x!mv*t`0Gp=Jnn`ZHeX;DI%s`AYC3cY09pi*X&?Z`5l6xakeYeGC> z|HRSZd_;3YN23;YeoRuTHI#Iu9rtWZ_hezt{B-!Nr2O^t$DdP^A>BHpHE#ZY&3Ecs8@w;jeJt%KFB1M#Ip(b z2m7%F&*)%SV}5aI1qh{5x}t|vWH!O<_OE9)H#xkbr&fL^`(yXv{bvvEUO&30{PFK# zHvJb*UU{%q%=yr~(UOCukIO3Dm;b=G@7cM&)TwGI624Me6FdKVW^+SR7dzV<%qIN~ zSFZfFZr!~Z(|;X0EGy}r-z{8OYsFs4g$A9h=MM}vq1!6<~6?2B!9nx(BKw$7M)$Rm4(Xb!k@pAqLF58>NF7thF(}?1Yn;M&httFc+VK`IYEWPk+^OMVA)an7V3n1*DOd$cAu0~PL2j;24$gMA zSlFO7RCckpCB{Vg)vFui@0XL&tZ8y0*Ga}`LPR*&hV%z!H$vLrH;iw#7UobNGvFbO z3J(nn4h#uw;^Jt}7ePdqM_@YQy2=({1c1OdSMwx1VgR zXDCt!VeqTkRmi|nR-m!JP@RfV3A1I6AGeHi@7{fM^ys;xM@xRoW)onwZk_#Mp+{R}ooe0cw4|cePj0SMU)|#3yxGcff}&!|;4f$MrDR_po7s5w z6gkbSu9vNYt(~0>OB_3CtXg6<1Qb6gh+t}@PbEHNJ1osD2lXGcWBaaa*KXdw|LDr4 zOXts?oi$@dgL?H@;Dw9=AtzJ;)~lgJf~W$m47`cHQR3M|-zaZ!sS3;%90aq4+1phx z+h>js6_@`%xC7o!mhbnC!fZ7uUiqpHf?#SB?QlC3hkcm|+Civ!%EL1=w?^`um2T1s+b^4NVFP%yM% zeWcNxLxKXrLxVltT|qSvl)NXNOr;N`qD!%E9j|$F=ionm_~0JKx*J!oOc*m7F=0`h z4Q#_K)+WF8)Ndw^895>?F@aK67Dk2`)&}(M)wM&r)cCky|3)E={oCf{LTd=>iaNU3 z+$ds&=m+jm-P#&x>V7?JD3ky8^vP2`>DJ993+4lFtdc;Q*hGIQz(!*akIDFN#qU^t zD_*?pR$%Nu+NToF_8w+Kifu|gl?PYf(Dab~)syyLzWn{(FQ|_P-6{3gDl6Ldk1`tt zI>+%rZ)3KZii)X&zxU|})tdYp9dMUrw(-juU9j+|o?fw*R-i_0Z%xhmy1Ehi z`uT|o0?s{r_}jE;SKGBaEs+5cszfFwR|@nb=8mlB-ia}e;HK7K4%;ktHR z=HZ^_<(1&+87FD+_V(d(<_I79r<%HgNLsQe87EZylvK9*xV5WfnGH$0*ZOP}0^3C` zu$1KElO|ooaXk3Ti>WCmDAz@qREoE9VKr)G4<20BR{URJHXb}#&`M61T)c9zq~ye~ zAzwA9=OZi{l1D$}$E#PVoD?71v0dA`-kz)#I$Ank4f<-wj$NnEoWF44(zUBsQMMdB zXpo(aji9(DQT8CPO|Z|so7qS_P^Jwu!h-MLt;d)p|Qr6=rz>)8>$)W|19^QZYt8`!O!>mU#C}nx43D8$#s+`xK){4r^dWkmlFh;z4!HYW^ywDuLL3tE%#! zFq<%Waj{T<{&l_4qh;!iN|~*==v1?&$0asN!N}(9yxzq4+jhl!e*5j^wQJ9Z47r%m z{Dh=7t1xP7Gh0PDcgTDFd&$j{DoUD-Ib02XX z@v)JKanbs^+N=^}sQ3J$M~4obGBR2;YnIs}Gplu8%ap_)C==%loAmYkI+Y8 za6$-m5JFQUqlFd~lNK2zs2Ii`ts3zI}Ri>w-!fVRgi_A+(Eo zl%!GMjppI#fISTnT_8;iY@?JFk!)<)Z>*=|;$WZEtSPp&t(!NZ^09W+550SIC;LE} zD+-|rhBZkOACmz&meGGLv$@HQv6DNuQP7%r&+F8x@5Vb-rgjz1P3ljv#hpq`t3BiY z5MC&M`n#BIs;Ar+mZ4OhlJ$y;F=l_tY@@yqB-)VG6;EeN-%_r0U}5>se`C+B>!po# zC7Aa*ut+1W$*JeW;{9I9kWD#(k>me#ZT6h_fW%gQ=|6SI+@P!;{PZ!}x1 zH@bP#-RLL*=UiRZ+S@I)wwk0-E7RM%<+Eo3mEjw0-u$=>v#rwA=^oIy=d))o7+tyY z7I+gEcSNjRMYNlNeqW;9UfJ2YoF@>@#d(#D^>n5+H0-9P8vpIL8#wW8d84ycR5FT- z1q8i%^*IjNgm@`d?Y4#4RAIK!jFJ-a*K5R!lM6Pd8O

      1$9jnTPk?_D4|h*X zD_d)87C9?Q!#F!Sp=l)28Y?BiBeK5H^5h1yDNC4*cs6{aHRP*W>g&e)H_8YMtniI~ zQY27uF`vsFaJ4bk*P^bb@Oo zcq`(WEVE&tV^lQ0(UCG6N2bNaW~Zm+Wi-!j))e6pcu5rc5P1glqH(DJn+TcoX{=6M zya;Tf^@+noa$}T^*u*|d9GMGtHdZ!P79g0&X~eKe(-1JVxw|+Kf!4&YA)IDqVoW?6 z5^Y?J2yAp{*wbJ(8h4BcKnnwX_84nx32zPcvD!JMn;<72Z2CPx$?P>+2t9 zw(n<_Qdz#dbq;a^_P%@Pg}l1DUfBZgNiz}tA!gfWZ?{lYwONZ6g4XNp+rP!d9*qb; zEU7;w+JELKDJFF7B2>vdefmjc#9?t1kyw%0)YNh(j9xcjwbe{RgD&gW9pXdFFdLU-YxAwLa!P*wU`EfM zdlnsi1f@9Q=s+WUqjmzbWw&c5-0Q!}Y|_bFw)~RQ&z^l68*?-=;>hdCciP&_P*!fy zqx&>QiM9h%3ky!Y7M_I!nd@ptHEfU> z6eKd6_|x;&tx#l?2W82RjyjsUx?1iImchOi`fQ&ITvS}=N4W#;cBWE0oA`$#lAH98 zh`$)p4~S>OmL~l9sH&r>OAZ41Y|Z`r8aX*x>gn;v4ARxa#;&5Qg$}K%vVw|IP`w86 z!6CHd@CcF)5<|maHYhHg1cVp?+nNfBA8{Emh<<=xa9V6uTtaq2A|3WOj~4ceeGbly zqefL?W~@*aLA1Pyz{VC@6Z>fiah^_&CX!`E8!%HA3Rj7m7(6*bVz@+EnnW;z+*p^` z`KrU}1Hwt{X-Is)X&C*XAUYh+Vd7b=d(0qG96LD%>lU)%0;SecM^YC%8#xG=<5=UY zOpQq>Fg4J(ri7@GAw{XIpfw{y3yLO~n%J3}SsEFd>Fb$u0Q^RxYfW_%9c>c>JtpBA zNH-wbM0nWV6DZxh$$mqqr6=0EAbRa5s}@od=2_I~q9SpKaa`umF)3sc-UtPHS;ZvnY)yp(R8 zI`YA z`1-ZyK6Q6cu)wG8J{)!u_5S(FHIlNkdop_P;9Yk&ba4;X^I;Uy5ONSSYPFs*VwIz1X&8x!H7BPHdV1Y#tdrmuMkB&^)vdD+6cnd*gxR!uW@HG754?^XdD#7n zv#na5w{9J-mbS~zc8;n_Zujof82yXPCYc<*RY^@s>cHv8k3Xzi zXE({POfI<_FxyNO<(%HVW--cZ?%Zo#yPj>Dew;7P0S@*{)zw?X$9G|9`}W%|&f6vD zig$9Swbd*O^Zv(V4JQUS?pv%0a7H5VqT*| zbx}-h0>&riRJ(R)-8wm8VK5t7AJQM1vK@&j zfYk{_P!?wD(HQDzy4hQXH1zr?KZF&NR@{NlL4#^awbZMtCB#jV6XdL5*c64-_}8JincILvWKx0xFnu!!kuX~LHHaG6v}alCYL5lW?7_Lpz}6K2E9Inlk!wZpsr_=PLiyS!)9c$Z2P z6@4qSv6J#uKMrVJ?mS_~TbWJxP&>H}dj43(040i9Xw2C#SVqnuGiH6%2H|?%a7Xe*EQu1I{NUVQLfV zURhdxQ(GfBH>Y3Eo{Oxkrh!|WEAgD}GB=wW6g*3Gs=gV|CKv|EZZI(DYHS>XP;E~3 z99x_3U!N#4+jnZJZ3Ycm#D|K^#;u^D7AH#Vdz*}n2b!8@U%GUS1H{Qmjv!)9a<6_S z438qJ=H|&GMl8s0z0lTnh0NqI+iZ2UHX}!_5WZ4r>45_eh7Z5gt?OBglUN8*s53C= zVPoCw>#rANX3Vv+T;lDumv1B~46)nPWNuj4x6hvod@K8sWj4sFOk8L!H7-%`jKvat4^}2oR+nT1Ix5Pq3O8^KBC{c%E4J#CYL=^{B(GGdY9%sFRh8r| zbhX3l`G|R=?_)MI$ z7iJ^n5`DIGs#(NVPc(2%&0;DoSH`YBP7 z@gbqON;BgV*%ma<#B+-OG$tSjcWOkV#u;%5^qWS<=BA|OB&ViD#k5Lq#uhg#38&y+ zNP`A!b5m3D(o%C%QnC^ffVad@K^B8BS}Ii`@gW%eC7Kv?Krg`##)>0BHE@Uy&H}>N z*n&OKnsAJS)?hqVEv#gm$o?9N@*D%nfOeRt*m5p!Sx?w zq;JJf|8QpGSAgpjj|bi?(SI{GWT$i<*_r8=2R8QnPnZqo=JZAyPi|kA{f#Tr-#V}m z>9%(P8~evO%6%7YLmqCK6M0*n*#New4b)e)44l%uXUmAv2{UIuR~n@MM@ZX$!fdIj#{!yQ(Go0aSg!2tmY5iisjbo9&|o6f z3S3=wGeiR_2-d3SgRs~tQPFqZ35u?DV6F@yzw>U!4d(ZQOW=bNlr@PmY66 z-Mx0UD~*l5B;dbR&5qVqb6j0^`qbTzVTvJrz2&1v9~M8cJhQpEZnv|YYh>78O|`v_ z_6P_2HLfmu#0&Ot|H;m7slMKTl`93mD%vn&JR441QRx@W4L-CCvn3}T^=&9d_YqUa zz=Nzrlt-nnJTLu3m}#^jB?~4SeRLun3(D48fa?i;23qZcZiRP^=r_OV)3LN zU}rNjFcjk1sI!2(R1&d(A080x!jaQ-6 zvPOf~{Z~t$8V*?MXQ`?hXxDbNwFqud;T!#EG*B_|=WqwyZO!;wc>QN0{P!))hM`GP zyGrzpidrAUv%zfjY;1^U!+JxUDTJe`s!|)@sJd!3Wkv9VtjPx6UP#N5FX?P+gIJjl zA+63%es$}%Z(Xov+4sFVck!@yj0p~<|Mc#?{X2G2I>FMwsB_z*!+U;yc;n`}&iOlPb`G+<0< zuMK5@2UiQU;2Ff6B{WGi8iXeJ2n2(hO4Uko0)MKh0B;nD0(E#q1@J`Y0yBuH#w6n7 zu=pg)epm|-!pO!D6JlPAi;g^Y=-~0gheCq_U^cXNdvxo9hzC#qg)MV^>((Let{^YB zd1^AZi>J<-HAtEeT(OX$$X8`hO7?9TVB;-ky|ppKMFO03L{8&US)E)S?Y72`}yHfM_3o@v$c6s9Lat!U9vhl#Q8(EjY)xwnQ5yVCuO^SL=E zu{&WnijF#hdCJ;qeL%pnhYw!~r~LN&ONkoWjVY6__Uw5+J?(f<;4UAZHT8Vf`8V1X z9(IUx30jMdA=lvN(WA~lHPUZ;|Nd`8wJlh1WBj__3LeD()cG% z;X1)5JfuB)oVkBr$Xwu6j@iJopS(QxG;Hv5bku>=lp{$=M`NOoaKUT|inFuX8Xvd* z=~Ll!m~GNGSE%IGxzpL4>=S%7YRx-3tgy2kaOu)b4*2!gXZ`z~@6-DnVQJheT58I1 zG8%HSOUQvOEFgIA)!pD;1qB|mv)$}dci}I;+!d}&@*+RGer({P&+>w%6u3sa>vo=lRp;*DqeV`|I_cn>H2Z z=9uc~suRYhPNIN3zEPYLLZGY=ilKx+c)#BLCQX_$W9ICcGiFa5KYspq-_4yf=j#z8 zf&v0@k78k~Uagww8x{SbKpLp_iq;TH!gEnm-B5>65#8#FLYY#-v=|`*#0CUrkB5Q&I8WoxASey0vNTI!7Bj-P)SdCr`d``t;)m4>qh@8m6IGS95YClY$wU_<`I{oSiOeRDn54lc5DRuQP|eoH3WFH3y3h;001yk` zWq?02wqZ{8)K}35{Fubu)w!|1AL#}Fk4QVP8K}b~ENde0@bwvDKW{}A5|1%6G0Mwn zfg}i-^#!e4;z14#4xBlC>f=WbQ1Iy2tEWARyZU<0cquK-`4-w5wZKbq4Vdsln)sz; zx8n7b-*OCBC>ja5HX2ySPQHSa56gU_cvzY3|HRHll-lZ|s5gG$-h6ZOL%RN>uQnQdW;r&PR`NIKc1fcG%l)>Wm>mHr4tlX9ADhd?#ADy0W^ zmcNic_H@tq;}icjvn^bBeb%gBCw_Bf*szPVzJ1QOD?a`0x7QCIe6(ocjX86!jTv*f zU*8K|I-kkRJb}e*_pbX~!Qn#>moL9HXZEj{(Kw}Jhcl>iV60oW?#3V2C+VFkc}%hR z1@o_eGx5sMp_lvgxzwZkFYsQE?&rF6K3iCLs(G{H+8S9YzOxIym|GS?d#Wn{pFzWCjR<7$FX#4 zsHoOb*3{q$mqaIZVt`rVv}$X8J^brkyM8)#>TF5LnWKjfBcQx@&z=tL+9CIWfG(yr zd=4ZdC@KhYAJT@w4JWA@zZxvdnzi*Qy--`Ls=#tp6slG>sHGn0>4DZqgrfsmAF}3x zGJSDn6RZUlcDDZ>5mbEAr+x?i)HnJEvtfc#t4TCQPK_aARM;X_F`a za_-!|J$r(i1gI$0XkS#cZOfKxSFWu7;Rh1TwQFlGoHy_KwQCRV-&-($9%5_IAf_+i zMEHA_@REuodW{MKI3F=^VKl>52D1r|jToRLHYlJ4G7-%FwQHfw21Jn}z$C%}YATSP zw}+c={dzb?VJAc;**esuXowmz8fzTGLWVZ$fBCG&nV8*)n!Fh-?*-E-Tw%R z`+Lj=sNlgobVw*quxsbNUAyl6xaIE3A8!5pvk>in{rYqEuU>r{a{K0+D^sUl-M?Sh zFTN14{b~38<;!o*o^=h>nKt$6sgk$&lsWj`z26|WojdNWT6qi88PWJNXZ$*A=CA+9 z-dVs!vGsi%B^Fp%mhSHE21O7F0Xs2K?C!?yZbc-e1Ox;WK?NHN3mXeiK|#dMeSfnD z#}x^$*X!fGFFfZn_ss068J|7-oqs08R{+V1i(h{kvhIH&OMLqD!<8$qjvT2*&^COz z(F?Q_7h8^1-M>!-;N|_R!)!3IGc$!6H)YYHYgJVrK!Ar2Ri~spiHv*{rVFg)WwT0&zz~jvpRY5d466s!jcr8 ze}TvN;Qm`&!PAJ2F5kMP3_*i=pA|g|D(~KXMsN@K)gCzT42uCCM@2nGNldKB$$18- z<8550{@a*s@9y16QBiy2<0lOt=4xfB4tozaeCJs*^583&kx);=N7d}YTNct+I5hct<2m0V;HkhGE;f-0G-BO?>EU8wfWvAwR?BQG_+EBx-3mSk zh^Y%X8**3SCm!}}U^dvZvEbY-CdyzjaYa;IQ~;^wL>Z_>U7l!-fpWJ#YZ8b?`}t?F6=nEt@voy>qAN%4I}8 zgXR&hfhYtm2;Sfb$rudAkVy&}QZO4Z4AL_kfnH!d>_X56f~n9Fb%@&F3WXzx1v*gD z9^y5)2@u67mJf)6D*-I_3GAUe!5#n%H62&HhVBG=$VD7+om_+*Z^rbgQ~=($ucuC) zXlHBf<=J-2rj3Zl`{w0~VZnp-bhIcJEEwQ1MInI%b`pDF430vE!f2%6w9Xa6TD(WB zq@jWvC#Xr5M^5R%F$i7fosLXOAO8o;#?3K$X6w8c5cLHqHLZS~R59seswQb;&!vU&z-haT_StQPT0}nCZOoPu6SFrqHh0gSNyCP=vbNAsl2?!tmy{5ZmBZEns}kfJ6~lgr zms1$CjU6@S)X9Qp)iuwnUm*ToO?7ofdU{)T4`@ZfY;Zak;O9r3max$d2vC(0a)Vlf zDI|heACwOQH+Pk~jFhLf72>lsC1;~{B~I6wD?eLYXljxHghvLewP)NCUyK z#UV+@QAk)2Utnh^$K^|wAmi|`;9!ibqp7uU{`?b1kM4?!*4EI3;e(Ht*T(hhlM)iA zPn`~8}vm-6ifuKdDym*pdT27;29cVC^9CF zsN*46SRfhn!m6sLuV24HdU|*$*xFjJT(SK1>z6lgTm#XeCGFqH`5nvZ{4DaGUQG`BA!ak+J21H$ zZ%0!9h0L~MY}3pJ5(AGxBG<@YdgNDm-9N`{jV$0#`v}Z7bjS@Dh9MY;h50!P^HXr% zl#m!Ye*Cs3mkKPLHxEJ5cKP`&@bQ`K<1@wEdz`!b0Du4C6&00DcKCZZnWZXMqmh0UZOxU98q|E5QG^*i1mR`Z~Q|1@KX>MVW>*8 z+nAg6_3-ec@*sR;O8t#)^t)Ie&3>bQ9zHa$=zs78nzUzww}uxDGE+3-Dwy%%(&u%d^m54ut89sm+3B2iEw1+;^rAS-KQVF@)T#CM|bKVpj6 zT3U7O*eSrby{e)TPT}%kq^ECXX0EHL#bgNMR9#uc%*a?@TU(kfA=t7dAu;L&42Bax zFRqXcA~n>B-ze&^q5y-DmY^+yC7=|%LIT6EDG^B>1YCeRw4~6ETR|NW(rN>{alr|F z0c=E0Me0OMM+gwqM}JCy2W_AQ*3#9QFnPkWnrD};TypbpgQc3fmimxkLoOFxUb=V@ zq_abI=YiO+S5bTnWD}b$m#EAHuw&J z$BK4uZ{(-*a@-~=GF!ueK8TzRZ8Astem~AHWVXe_e~8%(_&8Bi$khh_&L913E%2Fy z`)Fo1JSHTN8aIye1wf?VHf|T;;Av{Qmn|`B+_;SmKEy8{K*8JYX?@{irWU;66Bi^~@;9zJ*wayFK0h3H0kWp30(VPVMGz-%oATf#O5c@UJ@EHE4VM!VWrtIElJ!)d%Hb(u|q z#AowuZT~;`nQWf2`3d|nPoT;8Y>-UX$82pTb?!LS+uP05Oi_Zu27E20C0Ou5fR81Z zjUQi6SfVniRHWE0z-ib?0B_g|AfXcEZ^;l4K)5#%K_MA7zW)-ahzX0JF2L6UkOo9# z!7mAEh{X^eP8=73cDODqD1bcaL?8xW!}}mXGO!j-iB6NC7bPO&T8QBk{03&Du?j1} zswnXq*D?*ugPaWo5;jsn7f}YhC>X#t5FL@T5!3qDV2yP0ugL@=*iYo+r2;NXi zS++PNeSP}(acS)WxP&MYN9sYzNux2w!TTw~QIgSc1uLP!i3~!H4Ph0QRHtC5dJAbr zR)_`|5X;6XZjA;}dTLVPT>xGG-!PjA->pn4cX>m9m*X}g8!3Dc0CwJpDDBpoE1zD)(53Of8%SKZPs_16*RzPC#Xoy~0Pj~v# zz3ZPG7@tWdg=S{MV}WDl`t_x7npn7yYt=vXPM0oMRg|MAO`;;OHU0-?+q9`{;>0^6 zhTjP6eJL>TQl}2*j0}_Ybm2Ez*Oj30q5io~e;c!<$3$kvMQ6rDP8~AH$=E=dEv70b zsU*iXHP&s{%EiXWPz9(@L|~&{%z5g{1%xv3iS|B(ZB5&NxifiQO5?SE4mRyLco zJhHGJ(mK9;{3hd;ynVM=2&D9N{PZQd2x5JhwB*^m=1q@=4ZY*-RZv#;vhlvZ?NfZSU`c$+&DX=z#LU9P*3R7C$;!^j&bhU3r!E2AdiZtfJaxv*$jHcbYgQpA6p-mJ z6@qQ(f?W={f(q28aBx5!n^i5;aTTUSc84P`xuH&?)MDczBY?XgE5j+Ujfr?iEMe$= z#aW^(3Q@&SSQ28Ca1aTwxMU0GTKK0@{trw_Cdn&jWwoS1#Da!KdckvR;MxV zX+z`VI!$Y&^4pj#p_5)zTiJ*s{|3}4SdoxAwAZP(6H zNlBNFPnC~vn7@Dhqx^@i!cXB@^#`O;sH}Yd^eI)!%ik3jzbz|kI5siQ?Z0^O5q$xE z=!g*z+@q|F>JCp&o>u?M>fdKJ!h0<2MGX}46;6)anH(OL6}M|#&;WZwMAsCP6cLgV z7scx_@mvvC(l|w}5R>k6?F#ZxrQU#$Z5=f{!Gi5aq_J#F*H)8fP{nK@ehy z2vQwtnXNUK*?deI%U#vXY<~_UG_T~3dIDAknvLg(XF`T1MKPNsUbomdVIxO;zjmI} zyLK7x@890aN*Q`KCOku#h@Y*cs-&f&D1$FL6H&6+nra#by1EE%=I-IKX!-KkJsA_{ zF77>iLgzuFIs^?1=sRe{r0J7p%;^=_f6L}=xw!`yFIfa9BnazFElv6l2^u(T2y$A- zM8)k+N*y(M=7^bdN6c9;Y{tBCA&Wv|cgLsf-4&O3?AXbY2PFjsr(9f}8UZ#MQR=iI zayGyTt`lu3j)YZ67XS|pZ1pl58e`YO-h~lx#G57|HxUs*ad8nO!D283sMMwK$&!HT zQ&f@-9Vi105eYa{$0$rXMjBbEG@`6 zW0-s9NYBiX?LbqvvSJ$fL9M)bDLuH=-eK+;!#x@-!#vUkyF55vn?#9sw99ep_Vl;s z?YMWSd-nK%bDJmTtd7_`n-kKXGsKNE+~aE*V9$wJ$vZ}E{aijLxD{uZ``4Ddy+|FO zqRqt<^>n8%9nazncIAw0#~I|p3DA3KD|SPZFGKbJF|*N6=D%9`31+J!Vf#U5+nW%Z z6dslq6E&)TUmHVxWoQ`?-xAV(=ml6*6isj%^bXjX$kvCwoCLtct1M!0v*Fv$wHd~q zhAj*G6%A~t)GKEr%qD~m&CK>k{q{F6=HK}QepJqe^axztC`8rBgV5jGYgUi$lR9?n zU}vWW`5KqmloVtQbucD zND;XRN4%!uy%>XFM&KfbqDN~I+v?mDQHEl{^_IGgc_eR5PDD5Or{!!Lw{Qp-u8~tSdtCb&Rwr`c81ltI${UEdDW~Qga zMkj`c4eJ|duA?O<&Qz2}z8LIdP(q4JBdjhrJs)-<>~GKjP(Gw0Fpv?278D^XVNMM5 zWU6rW0yL))a;ulwh&>y!Siv|%m?5AfCDF#*JlNmg&)l>Ld$wlX=)V&xnpgdgJ^@=J z9Xby}{kl=8``B;^08~i8t^fthHo)6!cF!JDI(P2m;GhYGAR>9N5MfMOUrXIUOI==? zVm7D-bqx&kb@f_1xh$A7zvSW5N3TE4*&Z_`G;T(C;_R@vrO_!_XRegiyidu>IdCv9 zCT5pkdms3TvluN+Oby3QnXnD9A9M5Wmsj5@e-U%w*vh1=Ik9_C)}wPk{8nI)axY{x($)7flSCogtS)RH|R-moib_TQIGQC5M){CLL_w< zADjm6!YLUCIED(2xDLlu82GVa8OTJ~A_1nTAX`#eKoFVv7@|xjmCjWPn8_jHF!MsaFz1}B4F8<(jX!cJtTUGIuW6MUJT0803(&2|@_dPJ7!~XI9dxy2T zlCYtXAM20r-yUB+3Y3M$`^Wp$Te3#`9GcndT}{>Z;}q@QoH4A;_q}o_dPENm8SBp( z=f@fUZ5i5zld%5#kvOkkQbIX^R-N{|r}%VMAmWi(Uj{wwlbiblmr~!`T1MGRt?)DWzxpo0I}DR?%3k6O<}V_1OAqLIARaM>5niQ zgNZN#f-2H%4@-+-9XkeCnybh)mX{6tq?Dz#jjgqfmwVfJv*zBu`|$RY zS2H$8&IsQHZkJxw0# z-V|3Wiq+CPEibm!ZOlV)O-@8N_@|kz=HcDbn`WL`H~GYhG5PZcK^_Hwr-i7s=pm8|YQnusM?|U7Z>Ki+1!K5yn$=?-lSJLMC zSCqJs14-KVUFa*2o<%ekZH^jt=VD40N4iYx@_Jn7(otQ`jqH)@Zoa|CJ*ZRX|9AFm z^*`(X(AA${HeOn51l8z|2z0%C@f`0sFP~NIP1@Z(AOJ7ma0GylJoYY%yWokBP~@`G z*aOiXnG4|Y1&4QdhmnFhVx&uOV;`YCeCHVgEwN8F%xv%#6^7p^k+X>~1e%%c-%AV4 zEB_Oo0I%O@{me%BAi&qU)^8L(2w=8B?S1F=37p!sYe##?*&teih7T553>g+v7LjyC z8MuNRaX|xu7R{eOe)Q;x6DB@>`mFNZ=j8m;>vm^t+>^aEEqi@j>ha4rYd(CuSNiBt z`IF4dOz(DW@e+p-bo8`lFPxi@mb(9NJ|b|x`uHjL%%xqqM|U2`kH|fqaQIZ#(KA&w zZ*Skackj-Ft3_8gZQBBad%|G#9%<^RgDz-Ht{~nT3T_3b#0>!?22mSKI~r#;>{{r8 z9S=jHJ6=3(tu3ccp0s4yvZ*s?1&CYIK1y(n=o?JI0Z!|L4lS`VL`Z%QrPx$ayD-22dtKkSi)=7R_DffPk(SaH2bHS?Zv~p zXSdEdy=lg&H4~369(HJE;KAuVb0&8=xq8B<4~Rm|f#g892YbJ6gcdi{_TF=*$dzOvsSvaa^?#RHTp@XIebZGzo%?F{e=k=fX z?5{E#FR(Q(UaP}w)z!~GzWea$-G}VGnY}u7QD95Su-L+a3~bv7?t!fXngwhQ05-fz zYU}Cr>f3wPyg5r&E?cr<>8P=z-M!jM%SwagunPwIDO8DX|sk*o-tzT z?5PWuPM$q)^~SBM*KJ5k&&bKiUASOA#9Z~#8o5{pOL&O|b;$OKdX%f36bG~6O_L1R zh;9^8EP`stMvBy;IHDI`IYVa8I(72+{@mQigv7K1xra`lU%YAi=#a%D=Pn%@vUKRY z6$^I69W5x#$v>HQ{Pdagmty00yScf8*`(Rxn#gr3FH>i=4V~7x3z!YV{shcMrJj*N zNOL%i)Vhx1Vx7jkrwxt&{q=vI+3rE425c)>KlS*sQF$Q)pdkgh<;@RzT~*%rkMq@} zE!h)0qCMb^>cuVGdY=Q6I^Rfd&>{}TauBl7UFb@FNVnaSR?O2z%QKgKf?E4L=X|%Bt=+C(sJr*s_L3* z>N*-GHWtoqZra+Q8zUWkV{H>Nb6a~`J4g36ZN1xhcM9m};o+gFtA)5Cl3^Kr zKqEA?pjVsLt$e+`+*-M~Iy<_%wQA?-;p*Z9a--UCecowN8?UwzL*ubRsLPiwWFE*)-nai+N!jg+s;#@zmPRBjib$FhmN+LoWqZ!)(u$hml8TF0 zZ{IC>n1A$m$BvzWh&p&sDvGjr-Tf&!8_jG~C}3_5FRT`eq}cLrFdO}#Q2EE1?eYD> zor{5OXSU2bxoZ58g~8B}=FJ~;IHdoRYv&sOy?*ud(V4At4$kTWz(X%m^5zXZI4kf% z#Ig@>UNzMHR#x=E8NKK(wH@aN9i87ZdD^Ow0i1b36h!fs8NE3f4Kg6-{W}WGX7}OD z9l+Boh%>V{XWe8@<>Q7HQhWXSdCDk`o^I}-H**F(nlb3oltFnDf>JiEiVx&OJppJp~%jMij@ zFx%}r_wPR_eNkN#6CUa9;VC69AuN|#BPkA3NT3B?5*Y%u%tmEEpu@63A<8XOOkLhsAA-e8M0UK_7HtM?pD&zhUX&W7%O$4zi z@D4^X8x`dcHd^u$tRNrnITW*X>+0&POodfMTnjP80l|Bdii`{*{7^2FqD%y4q=Z;v z3|T zD9K1GaTS!Z@-j+FiW(}aYN~38J_+x1#C(*7YzvtRKqiRY-IP5WVIk~Yq(W!}3eYuc zSMS)lW8M0-Yu2pVv}wbZ&6^f3m}g^SMTBpV|JMqvxbfL2qy+MD3tmV;N)U}{X{aHU zJO+erbWdtZLBYv{x;jUHqP<(a8&<_RQRoG%F%~XWpfI4=Wy5R^PmH z|6zGW!I{&&d-ukYbhOlwZwup--L>8$FV6AO6zW(B3PosNLIIOSQj6!YUaQlK>ewhE zq5&Q(Y4%Su+snr#h?Z6uvGiQ%yi@C^9$Plz=#t?mhvy9_YRG_$=jZ#w>zD9WI27F7VK(?GaASOk2*K%;_>F$ijrueiQ4&FIm!ODjiZLYNMx=!jtt9Y1orsiJbd!_Np(G>iX*8L-L#Zvb^L{?3#*X%mDSIl zat@_%77gXB9P_m-3Z}y6*7^JNk&>|S{z0U6;TY#oG8IAhdLidW{i^YO9y_|!y% zAC{JW`0!!t?Ah)r$|fShR%{7#36{37up}Q}puZm=P+we3nU4dD1CYcRB2vmGFFx!{hRj_B{=0RxCZ?u`&{t!ZFUdEsH1RPBD)D&cYmf5;>Y2~DX zBnV7lZi*4Mn!J*(s=A6i(#SKJV#4_DQz;UV2!LAi2_wY4>{PST4srl-RxmIoCiq*#>Zk&B(UBe3PlHLK1Q zp4*pwAT9I2y~mXgU%rpd%w3HTCA%{>BxkQrIuM?Dtm;KIN=4<97cXC&IC0#^%M*R6 zrGmS@Se{_&?+Y(q{S$TE7jMB7ur9_GJaF9mKf-KoZm-L0ZPi|umqAc=Id1L6sO9Ij zL)10}aX&~owshpZytKdhyIfk3Q&V=Q&LDRVr5sx}lAZ{a<15Er+VwU5T0t&n*(lE1 zNnZ<2zt7C@`UR)(Se>!|@+qR}LORDg*P2OhS5B%}I_cV?NvGyb+!wYzF*Yt{(v&Gp zGTY1Q>IH#;ZKWjrl@$Bw>5MWqnq_6N#Mx@unsyLk#u1 zX{xuAk)G()ZlH-#A8oBbUF}}lT3s|XoaE)SM1&I}BgwP4d!cZIg=v6-TqkukGI*e_ z4#xLWQ?-|tI*^u1n#HYJ*@i9QBQM)mM|*^k;dBf0g^u=1Te;4&vmI?@*i}mdE0^Wt zb2cz2y?_5NKjlBK!*64@Q>V@zKUuJH`AWA|Zpb_=BFs=$fWAXSMv|oG6y$EWaC5(4MhAGL#|L^2?*?v42vt~B0xpR1V{ju)6!H2jG+!x0~CQ4 z2$?{B1ssA0IwWfn@2x-U2T^7W!ePs^WHS5{S5z5VdE zvg+x+tc=#JT+o2Dr~48x!Att1^7`sCr~eS%ZRaA+x+z~L!lWB!yjwTp$*LLGm(4i6c>00J zu$08z@gZ~PHmMsu6t-iqiqZrVX1BQ_`caQ)5eVr3-DX+Xg|)> zxSfhJ;Ai~cL1fv;*cCH$$Sfm+dDd3*tSuMYS}(D)S?%Jq#?^VAndy>NF3%r7iW@z0 zzPagg2fGyxcB>uj*E-s7XzjYiyWNgX9XAK~ZSeA3>Fl`7-gcRt&3qfH0eU(PY>DKk zC^CND#tk#{bmrMu&9%0~sxbHpM~8K-Tg|gD8>y*&I+M!jbv7$ASYL0rzTPwovxPQR zD;?~%d$)@p*gtdH)V-4?Mt1AE!r5`0iE$fcML9k`NZWq;f&V!je;c!zn_F91+Zq}e zDaa~7fq<7yN>(N!grf{3>PSr`#zahTX(?$zF}7nn|2gZ!w(ZT|wCC{lvT8&zb(2f+mSM*S_!8i~)=%xr%MAv7=JPkREk zKc*W++A5+Og}4P_7=!)VQ_R+_OE+hGMFi{-6+&DyST2Cn;0quo469Ur22`fvEGDFE zqEtdUC_E8*7b&jbtpH{N6%fP%0)caYD?l=W2LzLdoQ;Tg2)_Z&|UxDp3GzuU^(KnP zS5F^aOWkoTd0SE9Mi{n1)OL1T$d@vwV8gTr$FhF^I0Ig&P|uN;XAg5WOyz6~`C8UbsV8A5l&(lZ}%E4}plf(A*zDG8!FUrg~ zwqy8F%9PL-y+pcfrl0153VSL<)ZClePO$_z(UFYn$-pK(_ zH`GASRZ21?x|Z1vuUxUoz0DTSwrianFgUtnVHkWzfM3Fp!KD{2z&T=Vr;gJM^_SS$ z(u?2NruE)wQ?BeyFNg@wm_9YELjZT>#!hmw>P*q22M^ZyH~rV0{x)V4frN}HF3b?d zP6m?)Y|GfbVBQbCUZf=-c`|=t0GdA^(+`v z>QT6;GbP1E(F62j-=I|~OQAt9D91MwN9nG7j$ zWTS)56yIxDk%~w%MO2ZFlm%&yiV`HKmxQbc= zifB*fB1550ErWVXMVLtu;vJ8VaFHLW93)w48XD^AT1e6=gIKvx7IV{7F=4KY%?*eP z2V9udBI>x9h$vHpKq+L2lpn#DkmCf>>Kw`9|G6W%JKiH85oIUgt z3*=llPBCE^&n#rRuto2-FM7Ip(d~_k&aYdTml&Iso}RjN*)lMjPQy9k-@SMd*`xbb z?{<)Yt+uy?L~E+C(Heh0T<3iLd^s&Ob;9`206#$20vl`SK&|9tFP=Y-b$@vCCV9-L z$X-1*dwQ$^={edjwzHXHWVpIZ=Xb9t-`kq<^3+KaqWkpT>g|OFV5d2j7Sl|PiwY_g}v2s-0|<9KD}@59L&Dn#R)RHLHc@n459v=I)YKr z_uu>X+nB9m$F8m2+!Ym+v^BNVR4990ym%_g!JLf(FoZ*wMvP4`n}igb_k^XJ zR>bdL9Fw&=cHi2lR5b%DCJO>N{33{f+2CTvFW3Tj))=!fL`h6tC{w{~@)BasMutJY zz8$PBRp5r!@E>;EW*>wD6;~_invh zomHS1g;x-S;ZJ^%SJ^lqA*Uq|{_2brfZFxy4dPQ%M@g2R9&LrZ^=iBVa(7 z1X~B;E}Y^zPI1H)R3Lyt9nvt;k~9NH5sIT*;!}LoP$6^GIg-WzLXUPH2s&h8W#R1N za`V!yxtdw>M@?@d+3?ftO`zHuXM=hfYt;EZq~YB^nC^~M!JlB& zKwTXOtPbzrk5Avfeg$TW?i;wdU0cFzP-6B~Q(MrlFX@YsQzwq!HK5-%Uy9iPUE_?6 z1{xaN=6Z(S$~&AkX<}4hul0bgdYNtQn&`mZ+XMX27Y)E&!}RqATA07AsdY!adFbG_ z_C6?BHkb|6H^$houb%FWvuCk@hZisIojxt5e_x749qgu9XfAF{wunH0cmET)s8 z0hq0mjg@LMv;F4Z`{wEX{ZF7td$tCdt!IxpJ$m$M-AbJWC8&@XQZliahRX6zdRnaw zwcHFfoQ*Xd^i~yia;zvK{%3n9iSqBgp1G^g3u5H z4Uk5+!4(uT0tgC9Ng{k}gxTl;$soKf<(1^&*aVMFjLC&biNK!SwP84i9HCqtDCtY4 zLw8iLW-JV^sMz9Q(uN9v4Z+#KUC2=i=@|k@3L_r`62TxJD?>;EDpYvWGvPrm1dBfG zVAv=r0}nW1QCpcHK|U(3$QQpS>gA`CdZ+>&`+3Da2*c>Jc;OYh(U+=55MX+ z@p@QTg1&yTwRLvKj_+T-B*VUW_M|v>_w57mH?v}{?b&f9p7KZdwye7pvl?05%Ns~) z@cr_h6rI61=tahXj|2P*E<~*Wq+Qyz`ciD2@u|~`F)MHG+eI@QrUFXEt*u*P*HW3{ zp$`RaMX%(eV6quRiI0p)x?=R;i=)$dnF$(F!`7;4vQYJ~b`c^|#DDst_;oolaz zt~r^$=TJ^=_Ug53%^H=ny?Ffi(2C`UR<6jLHFM8|@!{ROj@Q-RK7ATlLEfrW5VCFa z@gkD0VTSr`zrlp0yg8Zc3y-45Z4r5d}8OR$Ig0+Ps^+Wmj919<9wg+8Ok4HtXeL*~8g7(8JY4Sx!X;qPALE z14w`eKn19PSWvjUM8%XKzyMT$(hx^DCOF#LBFYEc6VL_)#DzBKg2n(gv_YL0!|K!t zlh8mye@d=El?maPEZ0F5eh_-vn!S5;gEuG)Jm5cpDKI|qj6fZ;V=mk;WNQco4q(Fr zKpi%FxF{sZ4+aww5fTs)5D*b$h)`KZ1^M_`!on0|vc>rs0xhuJAwID*8w>|g8*EC5 z6cM~fBC27QpDQ$a)u}W&8r`0LM5Kc2xL-VBxb(tf_g6AoczB|*@g95ooGx8H@G#rG zywtmgl8bW^Ze~P5LyE9$$l+eMBy5C;tnBo`w~fX-gVe6%#D26aO4#sqgv5Q^CKWp^~_nleme4OrtoGHmC#Va+5fZA2b%?0}cx(_ECc; zY;17w-J9RXZ+;fL`9bvNs}Y;d?Av=JFaOZ`4I3I~wpW#vh4Jx)NxM(&41@LBzB#j3 zINC=}nGBx6eTDb$3(ez3cQ-Dx*};d@TS@U?8s(M?X4^A<951s?w=naTlO5Zm2Vo&F z8ydt93fkV@hcMe9Jso#dl}l&Npg~c_ULaXiub%5$xz@{UFsS>6*=($OYN&hb>DE-& z%GoZbrbhJa9^SPxR*2;-wzV0ktKCLL`Qqu*7{Bb|h17`?fNeXwbixAGw00e+t<_#% zuco@1Ebm`>{B6uuQBn2r6DK?@eBPY7LxY16LL4uZP>oV505BW$qp)B>&^D&16qD7h zdthpI-refgC2u+RUVS`u^|p&!TUA9x*rdtgy<0>8ngo8P5ME9jlCwe4fMlh$ayBuX z2{bd?@BM{up6$Q(1e&&I0*$8goQ*;D7p#kb>0A8X=?E4Cuq0m4=H^3EKM|301i#oUqV`{0ZdV6}n znL<$-NuZ=LF9OE_T1bo$!fZHFdQ5Hs@rl3zgCPVl9i(l1E%+$unFInDA&(zF{HiGJ z0|WV#MfimnE%9FoHeX9VbVk4;h~u<$G`n}}f|zxf8fsPy+azK&)PUUP_s53X)7R-P z^dlk_ave8?=L2&7h0Jy{A_B&2sm{*1J$iiL8cN~U77PY2gZoGK-aWjhI6Lmf-tg;b zJFcaMLgw~e2?ccBNDnVLd7!HJ3i6Geb>(Y>k}AFPaP<@j}o@b>wOFTu6*6jmi|;iPQm>r>GdpG6SWpwF47ySHcsj_+9N{_w6ecEwb?y|| zvj=pSf05a0q3cSWelAn1wE?FW}H%U-x3ZQ_KLF3#hvtzLeK z^xMpA4aI6B@!4L!sHu7W?B;rh~#ET}J|K(~Ua!W}|%X#|+ zr0+ZMu=4ri>KE0o-c>$->DAs}R!)Hl%MNPqWkREhG}G975nvZdNFib4=Wl_rbal05 zpl%RhFcG~?L|6dttxO>yQ9(psSCkZYFwhy^xlVt%o*v4whQNLdtA$Cw;9>c964~^>MWv65uox3}j2DY;5=4xrG zDkBF1L~;bCm^3_(Bw*Gi%95m9O95TRW+r`x4vE{pKPD+9F+F|Vrj6|b{6z2)C)^VG z6A(m5MiP;ADTy3#0-OexBT_i*IUp!-1>{r^SfNhy8$LoEM?e~Y3hmJhbub|=g3xe8 z@Q^vPX6kBd;W|#Kl^7Ys$Hr)=si2O6xzHB{bu_^KhAB|6H&Px1Fk_=Uv1*Gjgl~|! zL02j&Dj_N5=;V^HJ1IIQR!`qhKtK@g2L^`5Lxzv&-?tC!;oznrCPpm}YXBBv0W?I> z72Geyay%eM>Nw)o$Sq)Dq#51oFIBJrJW_NaBjXe+p$oZXa`6}1v)zh{O0l-y+q(7P zzI|zCLm~r6&q_{a-#?a#`~|o6@4A^81+RpL3Q~o_SpWs_hWgFDkrd{^g#nzF8b)1d zxG(o3YH(_hv@q@<5%5Pq=#R%2PrQ2ai2n6|@tgy{2RL=^+eNt^P&5@rRWc%*E_)+6 zX*($@L$CCmUkgrA8XqK+JO19t59yILsgaM8Ba3%OUOt+C`plVv?V+I-jWQd(c)Ef} zxoO+Cchl49rlf!v8nErBya1dW0B@5_j0c+-KjsEHYm(XCzjz3SQOOr;8-0aZ? zJ_uus46Ve)=1!S{xlV=e1PTJ@pu2>W?0em4!*aG-W`m>-%oa{Fo1Jxk9c?E?#lnID zj1T^VswyKkHZCF}E;1sXryw+3T=>rYX=%SI zT^IdGe_@4J&ejlg{mtuy**?5~`=X}0@@d7hs;Alevibz}!q!1{00kLIB}7<)aV_=! z%f^n@%H3o8&dAe+m(E=*I(z=o&Ek8@R;)6&u)VX$ADx`QW9zeDp?gQ;s9@u zxdjIgGBGg{5NL@+^4O#BW=b&|lnx?7N|G!v+sLk+e~8(rWLkvTSV*G7Wj5Ep^841@ zw)qMC*PZ}!#H%Sb7K~bwN+gPGO%l+KBD;x*n79I4Vvx7jg5JFr_w6&-v#k!7*`OX( zmK1k3(C+MD*~7_lfV=(9C5vKLEt%OLHgC4w98LXf4NTQ!;D!M1LAE+MaW+5$VL?R2 zsqk)y;$~uIHfZ$Nn9Tjz`NvNcUd-6PZ`g>Tii)zZ0fXqC@=2FKKo3f!2Ef3PvK&Lg zgfD~!vcf4a1_cdNlod^k48V1`NPq-Pf;u4+TtRyX&_Hphj~zW~)QI6Bb7n1CIDhu6 z88fF(%gxEQv@j!|q8Ay2&eTLp5RxL$7lOJy~S*K3MC;K)&qNl@^I;H$e@Y}!tYjrC&HqF^N%gZY-D2UdLe*XBO z{Bps=vxiGh=iEP{Xju8y8KA{+BP4v z;$CLPm8Zwv%S^g@{#@aO3xyGpk(NKqY_DIw+`W187!UU@iVA~tb*5REBkCH7-~s1Q zXh>)1>uwo5h#*aq%!bGEsOZYMxY$!+I}mmQYS6{@c3sp|k^UfJ%a)vNTjv-VZ1rlp z-qq!oFdOXI2Iy$p$je>+lKtw_t5=`jzWw~>%_n3{ef8>HRn_YXDkk&&3m5t!gfCk{ zPeeppm_ZkHhL8*&UmFYacW>X;`8WM@PAe-b>96hIWV4346J~q!8r~kykRe30J| zI}i3B#K>idiy&A!gls@HX*g0rG z5Yl`mDY6X(_I>>V5o)) zZiFlVgOdTV5Qpqy}V89ZmKFisw$J*+srgKh12Ld7s?v# zZ_3$--{>#{JzIIX&Z^777|Jo)L|8 zsYyR=tsWZcFq0$2S4G)ajM?77{_P*kY>ys2qQAKfLD%2BPMEFa!Mz9f?>?)leD@ z*b}fZ)K-y~;f1t1b*`LE9I`a%MtPZSVPNlN1Nsm1@zzD0G1#Dj*(Agq^)x%#TR_e> z$kQo5A#VT9tsz0Z16{1TJDPTJG_%x@SCWFrjwQun%d*(m8JJYST_I_4rmC!5=MG(B zlhaNX-7dQQ;O4#3+`~skjT)t@C=X_n#q@~z!NgWUd21qN08KC0G_ZAG!-4TX3@50a zhl@Ipp}_(TM*>2i5qt!qgH0OzAF(509JE9Qbhl;GMp$*oyOA6UnF(Yq58}imkU&JX2#Aq;7gE9hYh<2VH*c%a~ck!YH)z2!kGSW5G)hOD; z8X!3YjA5T7Do*ag$VBwKbOpCV6BKR=buuYw|8qx-fQ}dnN8Ae_7S99^3Khb`^z28E zHkeYJhJ+ui+(}N}@8@^0XU`L3$G&;;gzg2`Q3T?sxKaS1DlN!;aAH67q_A+ie`N2y zBk6y+B^^f@7|P`Kf8Xt{N%|8Sy^{e zQ}1VHK012z+10B^iu$p>AN`LXIW^BXWp_E(&r^Bf^V2C{JG_UJpGMV>{9M_~Ir63C zr+>^#e{(3k>R|e#8`qFv^XAQ4w{|Bc+KP%A^YN+k@eT9$r`OM00mfv6hj-G|X)iB} z+)~pm&6nEQAb>3dYY1Q)(>E}7-~bq&WzL)dn>V`Sk1!i)3^#|;!tL1a&XJlY6Zt1W1H;|2v+V9X{c$giTJBqSt+cTrpf zzx_0`A@(H-(T&1-rKkk3CaxXnSw_CUTprC?j z(_WR8(W8C-__6x_&8OE3L2i!=kCvS|ge0MGG$=W_zvTFS2*)0r*hd{3D_LC3%K+xx zKbBQ;D(CUV<5k5)puvVBuTrS?^lA0=>ksqt9%N)-ZTI)?eUO<6Y{LPkjN*`Y&# zHxMS;(+lRUKp=;l@(9j`0J*1fIL9(6^nxKADo7*>iCmKfZlovn*Ors}IVdOgeLlYL zU0z1@nIjctWu^D--o0N^k`xhP-=c*TAD=cK-|z;Q?Zlpxp2~_rI$BdK%n%nB*$@za z15tM2m5E3laf5;oRu?V<2%^h-3qQ_mq!;9n_fMXZ`z$zQVy8L!s5IxX?_`IDKgpy1TkZ!6bUwjuQT>Fb2qFbk}C z@zur`99~5@72t0{b^tY1>_Esk$iOxPixjdUU|WOn2IWJ*eLKb}NDSsFFb#n>D4YcN z1%yOIgehMGWT(O&D8fL{BoxpZF>?D=%mxb?Q$3AlIor?u&^Pz`&pZLjo=u@Kd$wBL zCK_j9w!jgHLPzG-ey@4l^UdODbP zvNJMMmQq0IY%v7T7Kc(0ydfti#S#&c6cJUCRR{_idh+tE!qUo1WmT6SlxH5y4<0&P zUPeZYAwZ1}9iZlOADBu&&6m|oM*XV*P_z1itD9{ogK@Eyid`id-yA5_BU==nf zRLC|3QJ7mRmt#ls?-bv9^sw~)y*oE=Ttgj{6*K@k77g@8OS)iQx{%QTkia1vQE-K{ z=hj6vG*o)`?p|40ey8|mK!C5NrfTcf&KowYdGqE)Ty&JVi4k6B0cnU90%lWDlt)B3 z|b8<=#9z-eou29!=a!8wpM~*zbaG~bT9b`)VTwfG6z#FDT z$_408A%8o6gmdZu=VUggAcupD^GIM?Z#i>_Lkcn}z+{e;GY8S@!>NNWO7B-ac~V|h zR#skF8MkVc3o@kh@fq^*%^5J@`@4hR=*BLcrW+Z+bZvz_A2=ua>k(qJK!+^)WTpoC2vI%J!F`<2`z2oM`0l`2f>IvN_jdinBQP0hVi zCm)M~LQHX#&L@Gh;U45tJM>`_!O5a=r;DHndcb)U^Zl$ z<`=*pKbQ>*z>$xSPf}6>FRqjW0(Z0eIUfWfXQM)s!!$-5fiBsmx*F}>o&GaFzRfq% z`~-gD2{dWXCIN?Td@td=!_|#KJ*pxjJ>1_9LbjEI2GPuh@3^|GB<$Hb*qU{7Fb`_$ zxN+Ll_~nZi4(=1|;n>^Jth1f5vw^z4ijsni3`A{UHaKodL&Ar+YGN#TSw+7tf!mU^ zR_xALk&wP7A#K*m^={t23}Ip9!;*tN8`O3nE=1ktI(`COTJZ6K&1gv%q*#R32%ACt z#NV9~#^@u-AZoeI|?>vu(@f zOBW0K_34fGP;7C$h0qJVyW+i6T}278L4aH2h}do@sB5SyYip=F+F37N5Hf4}WE)E} zbyX!xbK`z}dT!pZW?-M*`kESAD$2U*YC3AFsF)iX7$b14in6l29ClIcjhL6v6jqLc zI_AYii0^Q-s9^KNb!rRcf+!lG{u2eLhNnty4c#GuByZxF1v8TCGGtxgmW#)z z*dUiqa4w#pj<|mI@TbzduV1}>QB_q{@#INWP0fx86WZ|cx%2T^^YQIkx$^sYEAJFT z2Z}tN03M>LgzRgRN1Gj;I^?fg`|9b_@4JvIO)^_~@$Fy>b4MiwV>wwPIaympMNc)g zvG#V=52-}1SFYDCBeu^YCRzt3!NRF#vKFws@_ZR7Y8KXc7pnxDXb z<_TCEY9Z=1uQK$zIe}lln`>(r>*{JKDVf|VVnyid;fM5H0A#-NVn5M6%LlB4%5w;-M znDy@)Xbqe)GC+_t13g`cnB3d6hWY^GqZ!%UNPA2~LlMMWvQlg?o356IzK#}-CI*E17HKcX{ssfXsVeS>9=-qw6!qPR#gGEp`fCvtb~e&k|GdJQ%wa_ zM&5!kDZKzfP520lga8l?a0P3_5nM{Is@@8g+DM_94RetjBqNhkGA}u{a&>7)z4(`Z z4L^Ol9TRhA)~v$Ci=Uo9{}vSSE%Usqsj4X}e*WNA^}TC|z=njOPj6m;H5!C(6-8$& zicZ7k4J?OHY}NN}AWQwoO6BrZn zy63lVzkT+sUdbDIK1e(N>ILWNW6r(noU3Okgu7h8DLT!$dWKuha;}}_Tt7#N=BQFg z9T8^a!7VHwI?OkSk5~Qt`IC~8W$oMh^6~lb@wIE&^4b^o0p5Rt`=<-SI(LMc68cao z!<2&^1a1p0&Ce$$pxJ{fSB~f89EM3hN^Z{K?EQsj&X9juirFTNuP>%R7??YzV3Qzj#4);bp|cNJ{gg7tMhm6eX?=91+d z*|-6jr@rPv_!?8UHrB`0%uFQ4f&v%R2WEp}bf$&b92={W3x!zWwf*~2#*IM|2a@_~ zp^bH*CP|}E8Ekw24xKs|`{VXvd^XJy>g&J;cfkhATWGh<5kfPSvleVi@2*cn->${4CDnHw7F zs;eWP0o0w4xMAx+lrl+ql~$d4&W?zm8njvP83OCkh9c1Y}3pf$i73M6kB2dIXRaGf+GTO8`R2qGfz1Hlvuo{XxJ z0t9Q|G#qJWqoi#*;5SVJJ&4^PV3XC>P|?;@(NI-XS5ZK8UdYx^^fc6okPW~FAsdYT zDX|-z6JTSfAV-Li%ud#f1>ibv0RlNJ6)VAYU>kU~UR0wmk~KGUL^JXza3pQ$j=Ue? zQxN05dv|};PvP@hw=OJOc5%guhldZpd-jZu(pEeE=g;qIp1rClMYd362!)~({PyhL z^=g#+H*f`2(DFgD?fjNib@YYK0iLbapval>+_7bUr>N_1IWfsm<=hSM(Jv=8_=K9L4W?d zwoB(Wlu18Zhb6Af5?2!7@7lI40=QveV7BDZBas}6&RvB(2<>ELMs@E-mR((18r#3` zR$uRhj`mZ{O~;xT`>80mQc=En|1&OHK9si4&xI-kR0X zfxUQ{t%tgrCz4Nn@g2UNy+1y9FhaBuqd3I+7-4A8-$1|k;suOwJ}xd{NN{L?KX49A zhy?e6ni{=qY+k>rO@Bsa`F9<`qJDn9^mnjv^!n*f3A15;!=`~FHZ*J$WW7ESMF>H&45Q0~fDIqP}LXZK+QFs~v)!-q9 zJbWmSxeet)n@jbH^SI_G*$}O9Ix%IX;>+fpa%h}ReRZdM(0+gbz zq6|w3=th+lk=2g+y0gJ-9lOunxobgk#=PBW3*wTeZP?PLb2nkOBrNQKM##3VC@1aP zuI++3vv+LXG;YKQdn=3X9XrgPI%VeMNgaKC%#92tjvlozWX`alf$crpb_wuXws66+ z1@k>zU0ONV{~vqj0pC>B{&AGim9$CQq)FPeP50hA-MgiQ7TQvv>_XXl@4W?7wkRM& zmdF;tg}(=6Ks zFthAjug<1f?z-zHnz-9rBEb)zY}xY8J@*jz1D@@NufM+0G4rQ?e2?$Ix0lWm6`+$1ps*eEhgn|M$r8sat{-*pc{AR{%;4~r3Y?i{bCZ-V@1&z;B&#No#_m8o z7jjME>Uw7j;2RDI_P{E1G)LBbID-XagN>?4j{gT76+f`^B3cUbW}I`p2HSf5*Q0 z_pd4KP-E|+vSpUQ+@g6ica<|aNApuskiyi|%(%FW*x0Q2cu}E+dUiqrBKo98MHLv0 zqC+;j;^XO`nUv^kGP!4Vk}#XSt;y_P4(%Ti79153isda@0G*pF)*CoKVfq0m67Qtw z5Vab&*qG?Tf;G&BuUW7LA}XDo|?Fg))?@ z4uWCxa1SXW>j8^ znMfHGGpd;9sfaC;sH!*cqxG?FuC7!_j!Ox}2bmiH4H4E_zMcKNIN zDdsuw%9%4Ko_S`fT0Pi=*_O6yWqGV+onU1COC0e&ZVM`3J1zxpRvP^00*?fSbTY6Jn!sRjysiT4U$`{rBII z2Z6j%yGM^&*Qq1Ma_BB=1O1H}w>L~V+;>f$G(RB@?^IYacrfhEYW@AX#Kv&!Pd^d~ z@9LI815kQ0DuLO6WbFxr>+OApFUyp|jKCu#r9wZ;NhIxRLR_~1zj#-dS6_UQu|L$e z_u|Y9LIHC)E~QgqV>-C&77ZF`dF}sm^=F@XMm*Z$asExHX6|q!W)r}yfzlGB)vKFl z6($of8znOafX!rH;_PVeKtOctSTLXfvq7abGpRp8Zg)0qidO=38ReaK-bn?UWdIw_ z2+i&!A1SZKaw+dJB%Ff{W-j5L9(~KoIwmJKVz%2{wi^%o8{dJLAcGD=0qcLZyyz$- ztOidlc?rp#uxG1nRWhYh$Jw>r233@S*;I~pPPWZGoE(yTJWHZN!E9BjF%K`CyU@xnRepFjWj_JH1X58l7( zi?e6mf9LIQh<u9}+hO`43vT~wtak<*PmMaws5&yrpWLhQcMmS8qwWmI^3MeDRn=FeX- zVFEf$crZK^Fyn{m>hA4%Z{I!~xMRljNyg;qaWNuGg1~Gu;$u7c`^M?C(cWI8de_kn z$IK_^&D}Y2`0|2$a$pS(3(0g-_3ha4p_MC!BqvRaiQ>$75FkLZ-hMvQ+P2}S*B*If zvN2^^Qo`K$ICC%%Xu5u(!D%{8yq|ATVj|Fv-vHUEo|rRxLzm7_ZSxZ1`iBIkxVj9l z?XhX`;t_GNL~LX51e!yp#60&t z*kU|u3Lj4FT!~YIYP+LpQ%7fKQj;o`WI&Jro8(g3ytyfori?u(3b1>V+sm6_k8E#a zYu^IQ7U}IZu%e=UVxp&7ZB;Sa$g};8VM*hqH*g1HgMPyY!A=321HQtpj7L@pQ;nl| zm%;)t+pHel>Pm_N)k^!OO~7n^ZmyXj0j*-fOCkbGV}s`n>@}lj=YEBmH71^|gE1~8 zz@Wt!iPI2j+r>%mp~WxJOQluXVPC55*}MPIW2fHv^yJC&Uw(P{hZkRcqkFGD#Qq`v z4=$ooED^0bDJl{SR-B$r30ec5L8Bp5fN<$?u?1-tIoJ>Kb_)FrjaOWLO1TMzYQVt2y#BR45+frJV_fW*VM9MX`u>$KE}4Q<{PX|*`O|yv zzD-gs=1(ym2E!!))dYSsb8EDl>!R|9aBKBWvSY_1f8gTC8ckr0Pq%KxXA>K+pMLn^ z8lGv8RWlC&FvA(J90Te7&j_Ps%(o0pfByb^&>Cdj;fWI$Hg7(?Nt5aJ_8;uqXTAwH zR)}ly+NOta(!|S>5FfB%gF=Jx8c1@KmucKaMT9|8-J6-dG&g%*a^g@Q??Vqfz)AK` zn>sr#W?`C@QNBb7EqN2}j@NCRxme|a)&STDA*fwSr0o8a(WEwF=o3sOcp_)Kg z3n)mp3}$O`=bf0c5$OX>C}<6pC}<9P4e*Axls}@op-GY1$(rLm3T7i3r=vrxpU?2> z_8l8BTLTMo&?AaR1gMiDB1DqJq*(3$23-4FtS?`peH?4E0dj|F!-Kl+y zk6vlt+*NKLpjBrC`?rb-D~}DUPLF$N-t_y%kC@P*ZLjQ+!T}NO-_gNd zZU?pHrX=yGT;r(BP0PM#(c+IkIq~UdpPxGZ`I(bvpMU!Kx*m1lJ1`Cth+Iw!*1&Iow}cQ$XPOoplbH~oXG{U70o!s@l5>)i@>7jqx$K1a{N&_(qp@{C zJ~)lHNG2<+G$7dsKxCS@B-31hg(&Gjco3|}&+gd_;I*cGir^6F+$St-ZT;uD);O%H_+(jvkes zYHZfDDbpzvDMJ-FiV7_Z*ew4B%+{lOw?B6MBj4!fPd#;F*Dk_nVAUqHoB$PxiMlo9 z_Q#Irzvpb+0lYKd48gH)%$~ihNt1h;G?~|=$r~$HSPb$e(dXC;3-`vu+YYZ?^VsyM zn|sx+XjL*hHDyv<%nW#{yc`0x;T(#=8=A^3eftpHj6>eswhd}-Q?FVa5QN*NfNjuX zSdP_r=%#nR7VPE1habMPd-tmw*FQdc)~4DXOIsFAPfnVW5H~+Pby*Qn;M#KLbsalE zh^_8WeZ`dL;`oa%?ioF5`@sHqeclaGW&(tioP2IlLT^9cPT^r!Od&f!v&UY1fyf@u zuUO7_9_&!PC?{)rQsVTaghkm|*s~D~1Qw1caLbE}E*(E^aV!4!s`uTu(){p>%Abwd zm^92{iP?lgL0~r8nMtTK`|&0l##9y_?(X3c5E$s=>+6E*(-z}i^1nd95wc0**K%v=@oPADl?ed-2RmPdK%uxE3T+4-tnvcrP9 z=VwmnT7Cc2(Ss{XhqP%~mz<Ext=yd{uHxxK8CJIV%xHTT+O+Iy=F$5g5o#q3F}S z_L;|@{_^6NXV0Af;`4Lgod4pZx85H&e3Tm#fx;2iOW`C#cNrNR2sT3pit1A$)=bC^ z1t=|&q@{w{TIJ?cwk)nFE^3{Z3)Ke625bYc!Lt>nr4?sq@$LuCktQXRJsa^l2>$5r z?;jHzo1K%BUr-Po9i!1`VFO|K!9(<8V!~mQ=?kO;oHKZP;=CCZ5f&d4g#$uxfL{-HIknRy#YtZ{oy$^L~)?{rra?e)#yo*SBqb@%~jfY#x|8dEdA(d&i94JAN#( zWBAamz3UE4pGFocaW<5m=q0i9H#;wYso>lsU8FG?zH9Zs{^rm9^0UuAe){P*w{PbV z(hWQ|W%8rr$L$+8cHe~Y$j%X1)79=7JNm1WC&eL{*x{jY=$=Je`qW7joXNofMJJdI z2sbk^ep+_cwzW3;(uWela+_I&Q&z`w|;`qH|N0Vu5@Az>$Mhx59 zw-15f&b;%Ec|8A%6~5% z{COirjhZ%NdY^uMjmA`+2Azc3L+6gmX-sr1o8I4Br$b;D= zp9NH@w!{XJ91tMhv`VMU@bGCpdv#7p@v`nW+USE|bM^gE;5&b-(ao$`~v#*A2?_3{QDnR^T3+56DCg1FDO#GX?c&t z)=lbZ3gpWS#uSI!W=wP>8Qv4(Vqzi*x8_e|58OpDT|@O56%<&Ko0FH8+P0)+dCTI= zl;o}*+QYwf@6@rZWif19cA7Ce)mT|d4we)EBv7qSx2`=pcC4-G2y#QIih>ntE;S(@ zkJt896{*RIcpr!8j?A}GDDpEU<;OWKtRzA06@mo6{x$yBXnMOG+fj+KWy7=sp z#rT}wo0Ty?K6XJu+>E%GF`>aLx^}tn@yB2PI&}grs9&5o@yVe>ocxWgTR8dQHLG7* zb>DMKm%O%d!{=|lVVQaWt@n3de+|alF>DBqpW@_m;$kO8MNBcKoOg%r`5${~$;T7edirM%GOUz~l zX$(WW$%?(aqB1}7r1PrSuBrlah_e^YAN}Y<63lPewzYHTE(EhAb~uxt-rb|TynOB2 zwJ*Hz!tUL>moHy_@ZiCgEnBM9YA_p15y!zX@0}^IyFg_c8qxO!3jF9nuhUc}ty$n0}PI7^H#Ifim{J50mzr8uSO6_1IDdFH zY}=s!3kr+ZuG{eP;aA^#|AV*Qe)q|zpP4mhp1a;l?u227q%#Ewi6|dQ3Gsb<_nI+n z%CsqyMvWLYpl@%C+0cy==mSa(O{kZf8oDewIx06U70d>`*1Jb{09gCBZ8B1lv3bMJ zEhR3N4k$*;iwe6|SNHAS9Ra+hC&Yu$^O|AOK6hrk7UmdZuKlk#>B1P22*Iy^r8MGVWGB9lE&$Z;&YwrVJ$DYfHA02JI)1c%{Y%4#?@CMC9v8PaFYonP zv$*ivyWt>S@Y3aT=kQJVnh+@G&i!C=(!B9(uyf?=#4VJ#xY()@m*cKfV}D?~S1glNB)&tE$^AMxEcRwLZL^~m;p6ULFAo|B^_y*DR&R9NW1gg87>t)2fL-+g=K z;sr5s%I~jpan}0(ue1}nrBh8u^OI|aZGSdq6CcFqirK?VwK2WGs?kUXp;n*|^Gy5d zsy%ylpE`Ty_^FehojSR4)vBVRBCVT7t9JAD(7U^7dUWr;W5*6K8w}fm1q%)wI8a?( zjh+DLZan61d{Z&CG0-lQXn$pRS!c!j*~lN))3+ii?g<7&&&_`c0enJo?z) z{Rj3Rd}7=7odLn2PA;wxZS*7*8}k@6*R&~<$sqsj)yv40Z@&Ke(#0np+h1NMf_`%w>AFN*e!2=H*UA4+A@85Ud z|B|d+Nt~1SmM?#I>C$%=FMj9lyWhI&E{xWWOr1(ruV?D&4pvkgXw&BDZrwh7@Ih|K zpLMr?eO{=uSJpiU7x(m{g$HI#J1}GV);@KUBf=JSze!fpUmto)Tkk!(4@E6h9%nu{ zbH?tGBNk<(jf{&CmTb3lioZ&yZQHg2ivD{r8&e#ZjfsUJQDNQ#xv`m@nX!ENvU8U% zUi|9IPfi@4d)NGoj0|@zIs3eQO;XdbF7xVY`KlQ|vv16drT4iU)1qFfA?wvJr#+Wf6w{2_I46Ez){F6_N95`V6LmTgz zHy2gomIv3?b?H2yXDx^*Cn+&AHWqKwd*;r)cj1DNpa3$Kl0Y8Z=wRC-JSuM2-uR$#W+(2$ynw*7i^ z$NK=+17dy9h%>35-UD{-;J&^8xN;f4Q4D*&yL$PlCm!!y(-E$Z6st_F+&3}R{|7M} zmdP(X|NNi0e*W{H&`RVlxbVs=IF_E+z5AGeZJRfL{Ln)mZ`knRx^;jVREHm|S#wQ5 zasNAVboJ_^V9xvR2WP&wVugg5DUr<#XHjkvuN);kL4g7^0Bd3)y$&U|FkMr`3889ZoZMO&DB)vla}^a)P(cK$j|d8+a5 z!2|2kQ*p7k#}+&Og@=o?*2z&xydH&}i`vOm4RO~D%ZRY>K)t8N(aDbFDZJSMOPD%5^*V!> z2RxX)ygb?aBH?A^8V+piya_NgbI zKlJp%xpV5ecHQ{E{To-U!XH60Y)ec8>|yHGwPSnS2b^7%#0-+jrI@r#oBk1j2cCWU zvvZfuef7ho%Rim}^6I87kNEo-Fy(V`k};Lh4H48F99=|sXmnHrCT*0N>1hyOB!!O* z3n486@T|OLQEqw~Pz^qf(6}Hp!hQ7U+=)imHe-AoyWrpOL}*o5P}#Z^H&QlR7Zn!g z=0pSq`g-a^0|PQsjqNJh^y<;Awp*7zy=rr_GPn=0f(!$Wi&CI922X{7fhQ5#1(u@^ zB31;@CSXr=xM?XmTPsQTY)v8}!oI&*;-o)(wZ(D??Vc3S5}NymaXj=2Rh42wW3B z5wSa@WS%CuQAsK~h<0icP%U+INO4Lz5BFo z>8+4CgV}h*9Arv+duJ^C$wwt?;mnJYy}c5^Mg|2YB|OJX?gnT>q0(^5Bvy~wji8GP zt(%L74i_Y~8wu^?c1#`27}Bf)S5FodUi}>9#5cp65^M>`4$B%np<%+2j#`ml3v47`|(E|tKMk)nu%g87qDo9FltD=I$ z_&B&e$%)B90ya3N21ZA2+OzlRBkvx1E!d1F#teY}IYbi*mEsEXv6So24Zs z5YVGbhxS7U^dC*m)P8+n;Wz}NxKP{>{Cxp|l+h7kp+Ny;AjR+x(>vvLKQ9KrbjnD; zU}ARVLZ~xT=3z>~3Q~#+P8>HyYromZX{`Y^(LQ0qc<|J%8w9byc-oo46jW_@yp8Cp+^kpN54a(2)(Q2(>HfA?s1;_+ulRMfu z%G7Qy;Xyum#@O3i=^Bq}yaRuYJK*J}P?;c^HPmLpY`ic5q9olYnd7i$>uloLz-;}> zOMRW4B%Tc#%E7_K-pUrnBx`|+6PSTD8u8eq44$ODaZpDnB(PD=|JbCaObut2vV= z+&z27qFK|abg66${;6tHHf&)3+Ai3%RjgZe-?F>rj~dXwO<_S%dKyln5N=~f3}3SN zo~W2eC&{-#^0H+53W!czw06_#y-%&$_ssqKpIf!($-0pfoRs8ACT*7lfe-)^0LItg zMH;EHR;3kf%Bw2d;u??`k5_0&fS(Tu;_+@EN?UPWZfhcq6cqx}fMKXd@dM4kgEct` z+715#oJoOpK+uBhtPYhGxEpk<=~!Brk2#!V^Jef04+%;)CRdi1VS3lTvLYul9pnaV zBP=B-i~GX7N=cnjp`*l&6k9u5#85@ar7>WE<$e>JS?lndn2q(~fd}qyT!kC&K;s>_ z#XIobci+XuMw>wtm3mOEVaz7pl{f@!22SH}(O;bKrhtt`^T%0E5zH6@t%*|1EzBec z-Izd_gmHK3+^OTTWlJYbnbL2-fKekx%$YT7_RLvbYC5^OxZ1a{3HA>dHh9RwyY5=F zU;!m8+}zo7uy$kmVU}`LD%=zfULIQJD6N}>*@8UW+oq>2A2obPVV*C!3$6YEXiiMa$`Np{Xl=!@4BC99l zCdcNc#F!-~Iod2)iNs)!$WDsNNsghB&CG%< zJuJ{WEWj%~&^tWH5D{dcG`C2bfrb!&ZzMFpU@4+8$WL!gg8lR%{+_}9o^%NG^{6NQ z-tPY1x|@ohm)1wGxdm}Ec>G%2)drm;KJIRasC#SG-dYu+cXNiM(ra9PEmEVqTB%bh z-4QkQUx|m>S*KE1h?CY8al9_n71qSf+0mM)m2#CrW=%*JM+Xh2{z|#4lLI0uN*Vad z-Wp(|y@jKlT*(^~>4Sg4Z0JVe*_I3$II=^#P;!|&@@(0;;%($8(<|hj&TJfogJl6^PD}!8lR@yn*7FE5K~9ZLo8~PeE>L zLzIjMmM@z+c64q^Qf5LNQkb4PtZ&`S31cS=AJVN|WkH&eaJ7Y5nP?l!iV6w1(Z5HJ z!bm99#eBa@ey&_G92D%zGWT5#8n?GNwSz4PI%Th=|ecGAT0DanbXZ6{4U zunpZPUqlvl)@Q-iz+QFz*PZ11p=}OCk2CtdxkM(65+ER z-ge;8z590UggLCM?M_e;2U{B$Gcgh|sWR&_8T$M230fvtb|LJdU0^o)gS%+7hRPal zzZJ~pVpmL#8Hr1eDxtd9>G4Ogud27j>jPHn@fO~)>luO zo12S4@8)e?ygby_M6Y%6uqw{(8cB3+N<^zxXjKZ0%1MZuT47BzY9(%cd>wACN=a1C zQk^VBuqcFdaK`+`N$sLw6ZIA}fT=|xwXo@IRmeqYRg{kC*9c4{$*;RX<`A#Sx{x!| zs!05+HNj56bfBpNfy#c7Uk5_ zH5yDxX>YgYdRW|MZK;dD|uIw~{@r=G1!7WMD@;P|oAd-aI-@p8kO z4RbYTWuVS2%F8|0$0OFyBPPHQ=WmEH=;M4m6L@4iJzPi-@9c!>YDlnusINf_K?gi@ zQ4rMElV{!)$Yulf6YqD-8vq7kxaricut=?o3sgs_mTgt(II%;d;$*fty_24q#@AzS zQY>O|8xWU2YQgI18}?4!`q;Eb4orDyS9#x|4z5}!drbKp!9q-203jHyF{4I4|Lim8 z&YmWH6`lxResSs0Q%@G;=X!eRz-*p6u&AbGUT*t}Hb`DZIj(ydDCVfH!r;>J;7{h zg#+3X5FmpkkuyA7b#~U8N#lPLv+)6v1q-j%*xm3lD#uPn;i+@gyD2oTjtF_7>j{l+ zE^@P|on=rH5CS&}6hS?4b&|mzPzs@L7Fw|Xu_mlrm;+f8Cr7?4hntF{L?7}?xVgw= zwhai!3gK|Nfu4U64y5sBA~%_Eo0kKYT7+p|`b}b8V|ta~2g9$+@@FHpVCh7&6~UaE zbN((7AI(n+zUPk>)J;kSS~?{HXfcaup)|egD4j95ye^{U)=PYJ$P8d9w|=Z;PbUDC zbs-!s#szdB#+sz!MBAxAVd>1KT(VZP`UhqM(Sr4)*D{5a3V{%0gWI=TJ7L@-vuDlg z(>uk_AZ0gjun+e1$cP9jNr-Np6y4ewRh6F9DLb_$Ex9w2Zfq43<*SgpE1e8p?vbHE zI7ng_$Emq4^A4h=F=>dfW6T%;Bo(34q-3XdYK0S6h+rC+u@$AK=A{rFH#svt z))*C$ofyw1B`u_^BJn|KPBwlABtc-4YzTvU^`a%0H1X-_z&W5)+w#^LVt0V=IkjyI zLX9P4S4>;JdExda=I(rA=8gl?HtneBKUAsHqdUb>mR}c>ShJ>gAjO6G6UUETwq)^r zE0$9(U3~AjF{6#iNq#29C~8gc*tCfg^0P8AT|+C1$3aa?ydrNxCiwr#y|=JeT9Cn=A8^x?c&GqGwzH_FtC}49_BR=7j-5OCS+z~SNuNl+ay7if_R-GKCX;~ z1UCebo7$N)I0OK&Lt9EC3JfSXDlSe6H)o~J6+0A3qv7K0?CR(kpwm`oXRe(*;kPgw z_HbYbAe&O5Andv`z(FB*g0z9W0|F@&1P_rZm2$I)7O4>e=ek&8R7<3K(+-ls@U_HV zrr;zfEKI_kk=~T82)l0llwVq;1>Txq;vzwdn+xl$l>>nt0&rZzA8?x2djhu|oK@ z5NK%t&qyCyPp*R>3F?@z%{4@1?j}WBl@g{45hzHM*IG=`%x-KqAJRa@@~C?C299D^ zz0Q`KTt1t^@e|)qDq@pR|D-msirAc-h|h-3QsU~ksQ}IEqO>@PHlQ>gsZc=lLO(`{JlL1 zh~ci1@{Ky$+X8sVC7|)p!jqB#lzD?`jo&<=4Q5G>n}E!L&M5!FN%t8an;IQS*(xWi zFwF>H6Os}cUW%hZT3T6dZcSNPO?eq48x3)a?IFjiQ<~cxVt$n1#BG$fj@f{16%}m>tM>O+0 zX0~S&%QWk)=r2Iv^%YpG!@rbfh$!Xp?u zQ%05+`?>3^nzQl2&XUcI96Un!PDgMb%m(;|3$`Weyd-kgv0p?Y{$x_>8jP+H-nJzn z_X2_ij0x{bui&P==JHwx7DPY{%mhkVsn0dJeg<+jIsrRwD(o_!?Zyfxv?eCNBv9c^ zN^3_+?UIU2pss7BjPZ+$q?Gi^Hy5xI#FId6tQ=IXfjzE_Q%YP8P+3AlaV$2jm_t$-IKVx zN(H)RJ6jum6TEv0z$PX-zG)^m^pXHJEXuqwD)aFU@G+qD#7i_LEEHQc7&i2z>0}Ef zQf^Qn$c^Y9cq|b5LvU`{IJD;G5CeomXva4e&8fEs!7BA=T8SKj*{;FUL!-j(&lZ;r zyl92H0Uynz$}}kOm?&8YXknVgm6bsXY{@PLf7^uH@4{@rwv3FlPe1+i))%tIo{e|l zFMkKHVVg617SM=?Q9OyDECIdD@a(3QdbrNavvDlD#HvY!O%4~E*2)_(8&ias%1jKH zf~kWkg=vjOrZp;zmWqqBG9@`_*svj!rc9nNY2vssV+Z!{pP4Sj)CH|Urulgr+O@5y z>)xYh*KWPKbss)>aA9s9yI|V@Z}4ndCVUK)U9p=|N%m|yZTp<;t#fBhs%jgc_ppxH z56e4yiljKZ#&aJ=wrERG7`n55FXrsw-bv4*BWYLu321!6BF`jitsZ?u?1QWg^J z?H56d^2=V%1FBF$=3Vc=2T@l@$MTWrrwDdnP1tKiOvtDnkTGxK8f#Uq@n65-Zj0~s zx*pQ9kAPB?+%anco?$r`Tvgk}lYM2kcSg4+4X(EU2fg4?4-YQG*X z=Ee#q=ggGm9~-|n(M{SV1Ml7rY!lzQ`B>?Pag7ZGK+-H-h@}Ajg>d!k7HUnQrWAEk zqx3|W$7a4Qj9(H9G%5};ea}^{!4>fl9h1UqGh&yF z>bG=wpYd&5_RmNGvvtofM!BoCggkQwMo4ZAu973Tv);?Fc=^g_Uw-A8!>{al;>kx3 z9eU}-=LZiQK!zsaH|hqZE^{E<2kOzdkRY&Gp^=2|2^ld_l)yGxic(YZlM{2};|obD znwUsxQKGS7!&a7`*SV^46+;hH1CJ8DL;i0|jdd{0W8yP=t%($_majGKyC{!VV zKD_nr0<#fKm${B^y#z)>`C#y`?%*Iq8RwX7krV&c!2PP2dHBhaR z=p~th&@3+e|^cl_m&p7Bnd)*!N*HWAn~BF zBSvn0=%HQPA6dUTtbLm`(lakn6joMns}& zI61(~RF^cdrcDXviKSj@zfnw!`L)jC5X;i4)=(%5Es%gEDllDd1K%h3(hU6SSDCUF)EP0Pl+D~ZtGoL22{3PGj_}))2Ger*(*K3U(GMtwt1Ldmmd~X6(7;r7+sg2 zvUk~nU5n?>@7;BHVfNsxw7Tq!U>s=iT9uquTs1CulB&ofjNw{s-#%+MKlIegFTVKJ z8*d-`Cbb)@Aq3M?U%Z z!_Q6}`{3w%Z@>Bah6mS{6c>tEAE-wS9=i18q=KBRns!yyZ6O^a{X9J*f`WQ=>k2$8 zFKOAPqy)iB6mAXUx&gg=;e9}fc^mAU3A5>1l@xE@xZ&8xAD#L9vB5iSKa8OX7zZ70Fz>hGHBrgbyiV6-5#Vu5DXs9?eI$cfIu8%+c z)R{{cKmF{)=V#B19yux@HV(iR;^!Y?@Qn%#?$fi^V~;+1^u6~EKK2-~J`O$gR8m4B zdH_~V=1#S2VNo|il!G-{>lfoSzWLKzFJKTi5-PCbGfjRNZ(Z#8$ISC0= zXv|MaqF$7m+Alr-jm@sg7WjD{jIA~ZNPIgu#1f~^ANtX{kB!;e1s z%=Y|q&p-yg`NomAj=c8h?p@`j zCFn6F-Keht!!xYWk`v;HtJbMqbz*c(u&-ZCSa@aYvMgh2L{M;eU{F#_EILyneiUS9 zcB-!GQ`^0NubvDH6)M(ldY!hstQ84HPku&D<`d_MJbwDr#trN8a_(%pb?eqeMMdq}wJRtnNJ&ZY_V(r& z!P<~9dH&ovbLY&SFmCLi0sTqFH+J->Q6q-;s_j1SuKD{O+rN3s<_^`>w#}MjrG~MX zN~LaFRkeNB&huYf`t0=Q7rwYOd)BPH?Cgl(kjS9mKre%zyS`J04*U1*JALZZ8%K_S z+1`8Soy_!fA^~uLXxlLD@Kmex&T0==R0T?Jom+Ws#^Y;NF6z~_5wqRmDtu$N2G;rp zcHMX$%a#TXH1D$PPu<+!SowF}fqLIUy-j;OCuO8FkT9FcR>09qtr}ESxqial!;-X$q^Ck#pyuW3=O4{lahjOCW7TZ@oA$Y!Y~#S zigj!@7T$f&$DbVg=JM5Vzx(0x<*STj%-C@nt$Xtpwl+4BwLhvxFb_TmvC)xL6>VVK z2zFc5w!A~T%Ho1NY|r#M4JBw0Q#4~z0>L`^_pa+$Srr)^0%r5~^3F(3i3$nz))DB# zJ2S;d3=jkhx5At(!nk4QhW-@ySVFWJJoRW`J9X@E@7;^=PF?-Ls>S!*O|nt=K!BDt zz(%_@z(%_nuu-u@YodPZm<{B1BRsol3z)50vpc=KJSR_{bfM8P;ctjq{;royT97SU zHWwEaXw+(Sp%^lhwk+AVXYYai`zy-ZM23ae_3Vjyv19uVn1rRJ81G)VaMFYcIayg@ zA)&*D40-m@p)q5|z{Cd!2eS$Q)xc~@m@>3-raw!>W=3nG0<`1US6_Yg#EBE1eDcZB zqel-PKD=VZ3h*0;3(WS9@BZV79^Ssy0rVxNq*j8t)#erR)(*;+CgULp>*+bbHjiY0SiH)XQXAXzJL9R<7dyE`R4TLZ(ciby4Tw^5%%a%R1 zbLXf*1FOqgQ|{ijb?u53q`PA8(uE5)J-BwtxUtxn!G@v4B$NoBF0_gSjU@2e!`rqz z_2lEEfM0mm{Pffmp@bLCq_5&Y2|mf}Nq>xYCwZo@H^X0mN?J-%QGRZA zT3UQ$RH%P|&Q-e{t46N@xg zG;fY>(bwPu7>kXLNsLbj4G!`5^@|7#Hzp;gCa3s#8-fFa66508OFIG0fN=O8MWdh$ z4)*ZyfH&h0&W!{D%!QJ(fr)K1!?t>u&C}EK{`>Dgefsoy)8EC57r*)Do5vr29KsFF zslaTP&R@Fv&DHPu_s!J{XD^&PeeUvCmyf)11n~C7mtTJO!}p(mero-iHEzx>YK4+e z9vY3du(){5gKN*8KX>lpg_ED3y7!)Y^0ISC5Kjh#uz*02Tj!1)(T#p_@uCpG+t9&- zxlG~LP9htHtqnYzRw?-)cxu%p87W}4m4o|*`WS9paT;6xgLj}|{BYyIME@Jx%`FX| zuz|hiGu%d{fz#ghu7-!vz-b#ku;IPdPTTNN_PEYCI$%&LcsA6dK3WZ!ZQb~BdjU@U z`lSZ>jcdn`-m`4c?4F&6W~YwIOzoYPDQ=%%Rzq`A; zUatp$QNbLI`Prn|#8g`PyD4BJU=x2FGI8R>7hinw)TvXKE?qiv=FDfGeYSV+-kO>k zEZhWU`{v7Ue*EFbpZ@XF59k!Wy8P9puRv~(?RyNW?aGy_KmPR7#~*z(f7Wb`vx~fi zEh(fS2FH#a`|>NVz}%yv2Zy92B=)K8xq0KpBd@;t>Bk>q z$MKIJezZ+ln6!)V~N4IkL>UTddq_$chz zaGsVT-*664N6qVcmq$ zo90fN(Y5{Pf~;vR^T(C7H0WGZr14TJ^ezf_m4ZwsSc*9)RsJ!_brWXJ+q`Gu`bS2t zefX}e+fz!)lv;P*E8*D`&JIp0N2RkP!5lGXMW-1YNPssF9MhvB!g_S;TGz7&2#5H) z)m4>KCr>OY$YU>{Y4nI;!-ovU2MSUxA|yyy`0KESbtdAVBVbH~#UR`V=};v%W!8Cux>qG~7?%dfYo_KuBn9)3& z<_C~jf*C_%<{j{lcSJu3NYlG}2!s|D5ea^yg-z<=p588j$8H4U^0qU+qD<17rD=gr4RZ^g1@4{zP}zOvytn;UF#kf5c~p3}4H--drp}mKg+;I=srZA~mHQK&TbHa4V5RVpRSrht$GIGL=r zFvSN-F-ZbH2yFpH2JWH}3>Fm`4qyXc@xlvT77`SIk1bOuY4cQ0jxKWYpOT4QN~Q+n zgE!+mfH%^snG)F(VNwF7)ZMje4K}!7ImItz4Fb4^JiDxw<0zs>OYIw>Y2Tn zA(@$Kv&3~Ew`R?n;^Kh4Wuu`}>N-3MLWT<~mwd>F;{C>%DJi{G|__uXnd-{N)5v;|(ViyTAFR zmsDf(nxJ+Pf1>3ZQ%5T&`Sm#(xBg4-fcdv^{foUePO#5sCr-To{(CRI_~Oo;JC-b2 zJZ$KYqQU~=X)_A}(u7bKFGr%0pE*+$;c4O4(0hW%5Wq}GP%vHzkZ;uC*}!aQNYS6N zSFmv2UfwWf=tfOB)t$w1z}zl9HpIuY__G9T)V;jCCQO*Hb?esc+qc8Ez5DLFycuoT zvZbo33I|ew*=pK%8b5l%fIb5|weMVA*}g+n$I9}m_?U!tZL7O>=~mLRWoTfKi_B5) zs`l1sJvG`uU%#}}RD2m2cA%esbYv9DTtbdM7l01}m~G$6#p}il5BKx^GuEuebN)$pzzo&Q74bn0AeM%A z{Ym5eYn;}6lW$sS;2NbIB-b&Ui^9dzU7r{pHmPUrrYVzmOrJixM~_5bZ|vE?Y;gw9 z%Gjv7w4}b7$$j#SnQBUY#blDwvd?Ikr`Sr<>!{WvoYt%NKak3U_LzCGfzK>-{`56pY7TCNLgu1!LV^! z+z{r@oN?c>r8B2YsVXanWJ6Gr0@cuyV*BBx)x||b5<3@!mYb25pOrzNHiVp3#0^F_ z%E&U))3B*~;_(Bo9)9VyR}UY0`pHQX#^IsQfLRW1L;et+tsZ7$0lBe7kZF|cZPB6y z(NutH=(vM|0@3msjmf0ADlE(|D9FpqOb?F;Gnwevu$s_~WhyZ-J~<_cU3vMrIXPMB z>8WvXF+M&9PSvDI6O^qI2$VvR*s)xu8k2LfGxTpA}RGD{H@8P&W1OA z>b5Ox*rc7!rgz-Q=tLv^MNhGp4(y_i(33j!h!w3*KrmL>HZ=l36jgO6yOIb-Xo~raugh5}*5PHR!yi!snY^}qXOXu|3)2j=dRNU z8#XCUhlF}02L$GAP?;rWs|VQFgp?aFV8E0qQy|tL+~&`pzi{EgL4yV*BqW$-cqwR` zr@L2tG=5lN-g?Y>y?wp>{0#v#MubNC8hqU~TAfPm>89~^)7szJ)XB~c!!{LBJ4kb2 zinqoyf|VLzjO!xzC?!t{gt~Zkc+lV#&FxYKQc@%k)-u39h`8fwty<}fJzG&~BA9K< zl<|=P{tYZWjk~PfftxPkx7cXyoVU_`<41_2ZfrNV+{$Th+Q)o`+o;_1g#Th=!^3Fc z^1T6oA>n{5@PWN`qEy(5W?QB@Z*fa^c$|qZ0;?ow8)pj(Hom z&)l?Q!@;LZJ9PH<3(~u|dJ=e-Tm28f7>prg3S~`|0s!&qY15oE0oebu zNxW=ImQG3<*-ITa0e7_uvd`GMIFNG!+rVtFWEJJDhYuOlp|TQe z=I7}py{j60uxbOm1^M_QAU9OBtj;7p5ZSC)yFqJ|w1C-AwIsyFU|dIP)at4VUqgB8jWy0JV(}8M@GL9>RXK#V202F4#Fl}bYL}M7n_c9dGlt?Sc5=l&6+k9fQwIHYx zG+DlWAuO`NArZl$Q30We5z%3OfyTH*RN?#*xV<>n*xELe$)x;iHx*)nI@#HR+a&`} zCr92U^loateYs5wegOQ0cspQ=Q*p8U>JR}8Zt?4`*X>_9w%)0J@22=@b7{UC;s?pu z*d-dxeW;lC(!uhlOTFFz>g{cKv)-{5o5VnsGB4ZPfza@Z0-(97pyA~Tol1jI8aY!$ z_;Czjv8ymS(A%35CrK|*=8^O1;^7j*0A}%1QdjWPcYADGVD@+qGv+b*HwiD~j@pv(s}Zb2IbWmbIy=Zl9T&#>=u!=@Ov#aVOpGcGCAHvoG! zc(ztqsbIG4(^xa_WrnKJG3mol9Q2F)t@0Bs$E~ z%LB}&b#yMxF5J3)+v!u6PM^R0>De#eJO5?>;bWpgBRz0jQnI3vG6Bz3xIBsR1FA_3 zh#gcIBphRsz?&(n13}~*KxoVwlo+kih=TxXP^sO?ku{NI3VAyTZ{qp&#Hg}a8h7Cti549VCJ`C_SS{)D$s21SuMJYLono_9(De*y|WbmkZ`8fE! zJDM~BE3&AuF7TnO2o?*??;zYP*D|rJSe9lmCMuRHPRqL3Yes8SBm`xF(*#rlr;)-H z5p)DpL66$*J9a*@ci*1&9ooglMkgmHw(n5AZ28h>o;^fKe=wU~?>=?vQe5y$LJTb?K6OUw-L@ zg9jeN?T#gbHJ={{A}V(_xkJ=hTp$Ff1KTKpXU*(YJt#K~Pd)xiBivPn6t zrL;6R$84msAX;EeyUL1Ir9|q(va!4+nJ}`_lM+#v^FjgJB48V5U_jECOknjlzkRy> zW}km&2Q!`#74r?T+~n%SFPwpiAF5?H%bzZF%fZ*%^_!cP$6D3_$G8jFki=3-XUU5i z-<~6wjn_)srY$5Y&6N0tnFYXRV{Ze51H4I&Oz`m6`A>S82SA;6(`+HJQXqc-8v?5) z5E|eOp#|gyY(r2l@?!(bp(;hisnKXaYk)LJHmEi#H_qFZm<_*!Zses%nl<8K~$>%F(%J9Fyn3(vl=Y5k@nufP8JsZ&SaeRtKe zWz1SyrXpT*6iR0$c}89Jo(6)p+uIOdogbtrvNy@CR4xuu`ePm}o;qeurEPN?=1Iv{ z6g7&IT?*J9Gl4fWL5ChXD=U3*;FRG zQ^x0B+iWIh)6U*i(VW33WX+u%n#%2)!Urqmci6XRiYK8H`YK0z7bi+FT1L(#z!wwK zSpj+{j)Q{?;Y*Pb3Pz>2!`@xm>tF*hEwdw3D?br7rS%%UgOiMQrOJgy8(u;Q20`6P z*36bKnTe9~*xNYR(uV^jwHEKHSkJS%n$~ijGG37g=wDw<8J)yqC^|6ROJV{Ef~#Sn z=NT0o4jMPpxo=oB`88jAgr!ARde%)XqBK3-v`eDG+}%+ITclPx>eMcX*mPA$yHpA} z$v$YgCU{xWjtY+vkhztskVMLwOI}`Xf`TUm-vF(ftGfo^a;I(c=CJsXU)&RPNpw>= zgSrqYk1vZUA4jAMUd7y{w|aNI*4vX=MdM=nm5T z^sej8495E%)H>e-c@u0~wBTDceSr=TYqrgs0%@4rrKwU{k{zVE6hn8DhE)23xOQ&EHD7*#f${>^1^}C!yOn#32EkU@Zt~-4<<(fj-_6b!JCK1O(Oj?Y5*rN zPm6ZUMd|LQ_Jr{xRj8Yab_uMRGO}?AC;U!3KibH|}?^(3q<(FP0!Y8R_`R*7Y zL?~Eh@x6Dy`pV12h53TyoH1<*F^#88o=8M@?gO3iYy5m80s>;gLZd^1!~Fd+l9JLB6C;Cz(h1j`m4P)Q(O{&nj|bfJ`{XLb zHzjZvUmwG+>)HL258pp``sDf3Cr^BM^s^6-p26wv?Kk&t--^thK9%TR7-#ZLNhC1$ z+!X1B^H7&&mA{5q%#GLPNz=2;<7_!?afpij zq-0!2^;#Y58G%PiTbI@L>|IgSu3be{tCponiHTl>i?p+0kzwY_&CPFH(XO(x-T$-q z7T{SO-5zg|LOc-n5O;TXS0W@K2_Xp(+}(?Nafd>2ic6uT#ihl)xVsc76sq6-%^rA9 z3Wbl;bMAT0bMMKsp2@tkXV0FQJ$u%F)>^Zss8L~M(~78wFg_MGaxs^(Mz&_VsDXY1 zVPwD=rF!lTmgQN=8)i(L-K$HWi<^m_u@Q%8@hxg%8=y;Ak8?$ZWr1S8%-qZ5rmL-{ zqlKUxv{PGP3|3xvp3<$)sqwrhK!Z9bjB+@rt~gj!U7Pe*gh7qAIN+L4rs!&jlc;27 z&K7-jNn90YRw*g<^{5P17|1ortij$lj;PmDK)S+sCHs993MQ-&h+Ys3`85IX!5w11 zo5Fhq2PQ6g2b@JPZCE$<)p~kHEEROLab9PjD}HiX1SuTaXd+18)WCqzfT{?=D@+r) z0wFt!-$k5$VP#@sZE7mX*22QEK?4VC_!NxE43lX%6uV-4J=_Dlz1RT<|02b~+S1Y5 z%9$z7)&_EFU~Ok%ZUa*@GbQ3^W$A8X>*wO)W@F=GZS8Dj8H(G% zacf5pSv92Jq~=Wq=cM(|O6iyq=Vhd4j3+m~Ma8ZR^a7-T6D1|YEm$!B;+2cnZ(Rqu z{rv1%hqmolfihj7FTi1V`!;Qn*vCXfMn{C>4woB&I#T@Q>F$b^l&6oUy^}rCiQqtg z_8=(mSYS4R)|5S5z#)k51>D8A!zUw&a!8k$jmkixWW9PsB*x(VB;r)pMwnG=~94Zqijh4u!RN%2+XEzQh@c75*-mnnMmjO2}qL< zrC4f0u@Yy}1h^HLN&qT_h(kaEnj8}yNr;EIk89WZxOPn-5Zs)rgzuuaOH<_(B`ds7 z#n;}5a8<%K3Fp9UO#YakfzDth{J|ICFYqP>tZ@R5_`|IffDIK*7e!pwzC%0M4w#KX zXc5}p(vrr2v0+07gHJ+&0;W%!g5_S@Hm#9lQd{y+F=s~yT($pj`ed_;@&;CxC_vdo z%Qg_S#&l7gk86WDdBrJ7iEQJ&bp8ilUr%-cgLdHE-afvQrc4_G!?c;ix5`8^(@WJc+tE*N81MY z(8DcrY*;9M0%Jmg{XN_dHY5cMp7awMDu1uHKhNVzZytWB*qL;#x_qO8=;I7 zLR?azHJKu_y-}d*Cpd~v1N_fN!D4}-C3b`=fA*NSIbu*@!7S(I?1DWTOH@Q{82NLK zC%X^i!iSGY%E~B5A~ax|s$p+nHh!WT_4oJZ-~&ovF$F|q7|X$oU4iU6e0|_h_vdFn zgW2$=%TFY42fjOS`NCzk>AZOP;^y`1OBXD}@fw)TNRMeyH!(4B%CzYlHf~h7&ami^vEJPVoy!^7c*i@=5UYj`#GA_Vfzz_6+v& z2=sLKb#w7{aq@6>bak|MajAi4-tn*R}mQmDOde% z#HAp6r(g$XD8$hv)X7yL7vhq_oLnIi$slv`Gt$)~#MwE-*{K@w(>c_|MMdFmZV})C zH`g#%SK^T#9+4jIp{_1rF0LvHcXf+!bB}a)kMi({_V6Sg?Bo>TPG zep0wBM_!Hc^oSNnKwyA4&i(QBj`Q$%C%KDD@t&SZ-rnf}0eKM-g|V^ukx`jJ!D(QF zfWRbgpESRK%CwA@**T5l5>kErQ+)jzhJFu%`Ld}y&NvcdtB2h*BtWMn0CMKb6Y@&+V#U-hzOKN71tlSPsX{}=u+a;v5 zPfR6j8=p+rDJ7#zS{BqbJ-b^*!|s_ms0%PS_fsG8BH-JA}c z=5^{azjN2mJ9nMmsmtfxdq4}i_gvhw*Ro!HR`%(?w%@?@3auG9WK_#G0S-dWrdLnh z$I__K&!bmb{J5rt3;J}L-mY>=Rg>ZQ=>yW^`)4I}%}ny-vqhv?uO9OlD+urjK*iGB zv~Ta8`}Xd>dF#g2YgevbzxwOTmt#ha3Jngy=*Yv(oek!DcI}!rdGe=Y#&ql4DLo~L ztyZ8cgfQ@ZluNyP_Z&KWXvZ!cGtyJLckPS-2fhi5ltdiviF**h9vDe3cI2ap6OpJ% zVl#>*h1mvdCYM5lKtzsC$Vg2_qe?ng$;`b(I5X4_DUZD!ix)&~SS48)8A_soKsB7} zPMJ8qvaAWN+jx+lw`Wzeig~kVaaMwakrd7oDGhNh1%d`uY!t)-*H)20R_wv7T@#nU zKHi>aR`>~olbl^810BJwJsByN%7HGYz_8kfOr<}W0n8nZp=XfPp}0`!7~v3Qq& zjTZ`kk${a*i5nm>1h643;DDUjb7nPf(M*=Zy__h)OUY@Nb@!0Ko@anj=F<-q`B zFiY_obwdV78+n@&YmrXH_{qwmqOA1iM-M)mF*PSWCD_-?*Uj0-)ydD@#SvMAkvC47;Xb#pun^ynjDO1E zS@L^iNhPa|Jng3^KV7?g?f8-7hxQ-h_=9cVY+Jf$$@Xuz9Xo#f_Y ztJgKm%r3~!_4V>#R~Ht`cxN)c3Odk@$tf-3lbXdQ zR3#+$E-da>Qr4wmUW>P@y+7n`Pno&rZO(JSwegTjg5*d2@fM|k(AIpA)ZKSM0nHaC^8T! zkB#Y&o!PBX9$`gnOq0ln=JZ2!T$70C((ow4vdEaGQM4<*d3+M}tc;1TjE?&ciivLq z#U?b5O=uC9NCv765osQm`0A39PM#*=QQY1tIjv=4invO;lCvT25&5%CYKB6jr?p8-?~s+`-X|ljN5fPPV?E9f<=A!pI4vIJgLECa)3POtE?qcx<jWY_?IM#Dc#P>gx#AHd|tOT(k1BJ2$Sc{$e={9Y6^1TefK7!@GBS zb?-{C(il&|NEE)535kud;3x&K!J{R(0)$AorD!&VX*zmS$-&9YPnk{T`P+~TGAEgd zs9>9T)@xGnHC5zo%qBC}edTgZ$fH0wfHWin2ov}tqWr-tki3cA{w-U!m@;*8S<@y$ z!uA^b@oK=>hYs!^HDb7}jWwb+RHdKKo12`JK>a~13c}GgGc^I)f!Uf@mV<(jw&4Y3 z%H)aC&oGrICy;|pcb^RCcm2x6z(8N*Y_!qM&9!5vE;n!8IdS^T;bSMyoIST_(W11p zG`J@fmhuM}C^!v&2%9%=o;7RMz<~qf;^JU)AUD!OLPCgR_XuX=ANGpan_+vFo1T`J zo|YOL6YTAURy5Gt3*l;7QesJAK}=KxkETixN?SlC&15vvA|kYi3eyUNgg@QAJ!8VS zFh3t_6GKBRs5I&tu;Ha1EE0?-Zil#$kb7w$#S+Rmk^e05ToqNnmttkf)f217C8K|5 zSglx9`5zkj--p>4t18UKSY@b#*$5f5s&7O_R3FG2>D7M%r~rJ7H^qM7mGJ;D3^au| z4>lbjVh61O-oR;?v9Toq{6>Vc2l#kET;$}-k}6Tezp^wH7<~h<@sphkJ$v>XK74pZ zMMY(0C6091K+2Ftu&nsy6)NTdeftB_7B5&ldc>$cJ$tur)2_I%acWWukr5+C_UY57 zVP=+%g{8i>j&XfG1KoPqcBZAKO`bCK(xq#se>lr=S6eo3DJ?E$n>OF8*cJArgxhqDdanX@{GGI2$eyog*(2cSaU!M`KrRHL8QWO`nbmXv&GrGxq}9MF4ypB{62b)DV4^PH}o=6CG)S^M_0+P0onRW-4)Vr*HH zktM}LiwXu8AB+I*6rNDU;%M;?8Dg{h2bIP34qn;g0SG+ zApiW3z@muIMxlX38b^i}M}-xHi}XfeK?<&pE{y^h3o%#I*!ZHb$o!zt{GgD6kTAgZ zUrB&)3CINw50ey85E9NUxdFjYUSLRWU`WHj;4D8L7mmygXH_6JfGBs4!s$;0D9^>Iu852GrFKb5Y=1Y2a z8BvrmFe|QqMr_}Vn4TGNowJgh^tDY{wqX!kPwW%`AQ7T=oH%am%4JKJE?fYf`Fi7q z{d@OLn>Z;VB$T{J+g2=Jj&r0tw{AW9@yBIL7H6fWBEJ&Tg{d*HEj%=M!h}!p=Y9A7 zUEI%N>4fABPA6F;$W6vkm~so)3{V7A13vL|pch0O0;+M9hziJ&!c~dx09Rb%Cvq_A zEK!!sOd>@Qmj!Z{B=P`9JG5>6%kyXFPM_jbdeTda3J-j@_vdF%X)j2iE(ZkE5m1eX zVxh-VkhWox2cVLe3ZNyy7(e0Ha6|Yw`q0|7YLYJ5I+8bttM4IMAo=MK2=D-3mL*fB ziqWVzkt!lF8ySRfOcAmnZD8i-Cy6iu_z?&k76V#?A63I_Y+Dn6jSZwNTUD{w0L;c+ zssgD-T59s)g9kXD8m5Iduy?N>Lx&8)+a3*(6-M>R7Rthc{8J~7vrCuPjSJ-^ix#r! zfHevjnZQb(piK9L~9w?YecXxO1*1ac^fqnZAes|!|_xlgboH;WkB?Y%3 z2rFQJD3ZXI@U^{r_Z~ZTZ1UvE6DLm0%F4oe2TQi~>(^IRRUr?t!uG@35<gVSo0T;gHt3V8W|fE#>1POe8o(0ertEDMc;gZr?Z&w?C-(2FYEm2- zOoLA#c#Ta=wxNPP8Tw*IUKD@s#)d{NIGx zXr@$sO2L{O|H=q|C37Q1^_dV+eIV5n--v^<5RNg}_$XK%FxbRe)yN1ih6$yGxrK!p zp^7YU&B%^Rj9%qOgp3z;D)~Wu`~k`SEoKAb4H`6vp}T3*rt{~|bL8mpVP6 zjVE8FlLO91oEV$-ww#t_&BDUL&cWRk*S_{_j4(E0W0wvm6|!fF-J|S5z;$Izbj+vY zC!9Wg?%45@n82MqeYQ=j)_lJxKrPLTZLKW=0)iJTTypR3gBw?Ga0V6ZVb* zw))34v0%Vh0rNIpO*K7DbtiMvhLI6d`u1KmZtTM0pUfNFckU;>XAkH(qi?rqy}L~A z(Q!i8cH=s=p3t%NtPbsGwr@ANO{?)$%|}<34=XDjR9rN$sGwg#eutcf?U29a=Co;; z4eV)=o(45fORYo}my`$!s!pUx0%bKzO(7d0L}pTC{xa|wNGv&tkT{W+nHdz`Iy;M; z2=@x(VhUbUVSH>+LY$<=iSbZzQbLo|>Hg_=9ceXHc zvo>{aVCG?C9_;Rz93Gew5fmTnOPoY6J4;Vn3s)->vN@R>a-bt2DP~%lPNt?IZf=Re z!AUHV-Q4Wi>8z`3Rj*zHJw00kgEz>|(2xuc#>O`K`jW^-W^OUp)_z4gI%YaLmi6m5 zFfcIJ)iu)4fK0WuNr8;;(fU_1#Ce56Cb~Kn`g-Pi^&zwR^-RTqO*+Op+LDae$;i@M zLk(iHboDrwjCHgi6VxlZ|!G>Zsf$3gF$#7;@!-P59b zWX5*Nh;5S*?`(`oD$acbXpnFS+yasz#MBip2OPo4CQ9WvPBZ)hnH!rVCnT(1wet4e zJLfK(zkC1Q+BK_lvonE1m{PzBS?eXn$4;3t>DrBJx9{FQd*<}^ZQmlOfm6Wv;Ceg? zUMcXKVuS|bk_1Mg0uV(>r6h4FaN`n$5R8zz$voVJsEw7Q#F-MgfzyCnlpwPa5+{WM zA^I2v!LY%D9^AQ&sEwoKd2dCH@{b-oaQphTjceC1fCNIx994PVj=+n#3!sbe2T>1wLJD`uP_i2pC#oJ{s^_Ovj1mE}fx95| zp6ot=j{w`GoK0$Bh|52*n*v~LsNbPu`}rK@(6R+j;YP_HX$2C|!#pz0LPyqWEP%oi0pEGl+ zv$H)-LuHIl_|9FrojH5{_^BTb96q-Hz(Een#x-conl)(;_23U4hdAQEfdjjD@8)O* z&e!(w@qy1$e_UE&&jt#`@dg8f@c?_na4{(+IxQ|1z!n`GAgdV6?~tE`hDFT(e9_&z z_n-Xu1nW5F;gZIMOwqtOOIFsxU|x7wf>R(&w$QH+Y{O1F(c3#Y&^I|qP>K=~Neb|e z_w|VJc8l_Mi}3dd^K}dHb_wuw@^Q2GbhdGIuyVGuaI!Ubvo`lo$j!>k+1%LC)X>Sy z$kD{W-bl~Zu)d1y4C|9(Z>$eFm>56}^mVQEbgb)ZTh-ULtfyt6t7)dKZmOkbs#%u^ z>E=2bGQurNnTFhAtWn2MQw=t42;mPLI~HwCNybVSzNPOtrL3*i5IX zDItUm4K+3Jh+xE4L|rXIZ4I2v6EW7+A|ze>REUVUs;yxFw^azX%i-VeBKjHG1jN=w z5l4)#r4C?Lb|q?}5;8G>u?yh?j7)MXm=_VWQcOEy&8V&T+krPJf&!*|JZG^TUfiao zh6@Syekd*|MG9^R8M%fAoFc?p6~O|FVl{m|tk#)gYeTv^%=xVGISPk8^=kZ-DdMVn z9R?DnAUMEhwa$b|1$Z2LJQ=PM$w*WqfX!=cBi!t8Tqb7~DR78Tz#-HSq`;9BLW@Qo zHTI;EQvpldg?A@~HwzApPD^g*lzT|%GE(ZW+fX6!(i?=+GXRphjsQz_wFIeYtKou- zba4rLoYzDmr?dm8$UruJ3Bru$HIXc-zJ|J?jL49m;Q3|GP zh2(Qyg}g)-LCVV|h4Sm_vgKFpV?;kXb!(eolc0QST&l-=Clot$1uE30KKKsRtZT#= zs!=1r**?L~BQw~qG%l(vF0v>pC_mJG@+YS$FohhJNu$p}LZD<-VrC>%K(*5*$hKKS9paSo2>mcqQ;y*qb2esKTG zb!*+lQdAR=#>YajL>MLlyuAaq!L`9}2$w(wU=kdV5rWoeBMp?$?ro@6Jw?_Hw8Jgb zmRqE#P2^FeZPlTgD$ci~!fX<)ai{?jGa#A7Y_KHI8Ug|SUgI_XBYXpSuxU=OW2X)a z@XOJX6eBQp>ILaRF&${)zniC4BnB9 z3$P?ULv>FV$Ci~%cWwLT*x~&{2Mw@mV99621PDlj$i~}|RZIKXvf?gPS*Q zUbbY}hPCT4Y-8W(XR|-szJ15hW5+mrsMC=ZZ1x&VHvbIv@9=g_SM(lK6>8mnq7 zGMGjL6I5guKp`d~o+V}^%rzPL$~?miL;Q{5t@;q~H3$iNYcN2ysZ7pP62Ix_u%d^^ z#<~N656gLwo7f4gg~Jam{FHERxWId4KO3;GPL5gcuImULP?|p zz#x9A@o=TYLdlgU}tBIXu^>QcH6pMtm%w9)0-eT3&L2KG-8anD)SbWyg;uI+4T9VYY5SqOvCEKg_E?&JRqz`FoNYc|# z*Hc%Mghy`!%s$zz^I8nZ2!Q}^ZxiK!_aFq<@-Aa-Ei>HD*3$*`A|5mVfeVqKx-st5 zbafyy7$U0&#Ii_XX90+?)<+FY^zF?JZH?IBGRa9vw$L}UGqW(#<$EzmPDot4X3h1RHy%Ix z>BgPg%a<=}*0jtY7hQ_wE&`U~#)XR(F1UX4`s1gM9zS}BZZs=19bO4BM0rOHD#0ri zQ!z$6FiZ}6*el?TnFIn~kZ*5w?4$%q-Ejd1J;k?i8-n@Y`UPoISjkn zHulgdI!1wfKxqOxiYP_2Cv=scRfxEy(9I-lS z;`kHCkK+Af?(CUUCQX?4*__p@R_xuqi#$Dhbi?y4FSJGT%B71Jk&~V$#oN=v%hR31 z5YU-+Y~K#d#4dgMgm&RV3YVp9Lnvrm(xG$rai2~YHEL9GaWOT7@gcJCWPesLXQPy8&{xq^L+XAjF4<1^ak|)=-QJ z*oLgn(ca1enY!2|%Bzt>LcSOJTs0|iNmoY`k8dn_EGrKax92h-p5JG2& zNn5@n-ZF*AMF(+6mi7-q?p2KnSyc4`tEapXSB;Iok0`UNs^tG%nRUcl(EekO4jh@&o5s-fBDPLzo6y3c<$o$E7zYteSYqTbD+5U z4<0;w_S2P%mzFMA5Ec+vUsDU;Bd$))9Xobhvu^#^u@i<3A30~{9QGiL95y^HIf;3a zFD}r}yA!s}b3XfO^Vf*r@Er2{@4t>2Ih=GU>Jd^ST`eX|5CWDGEaljlqYwD1S09(b z5Nkg?^gu*ZKQR$71>gz)oH_tAqxyKkLTaSgd1{5TL zkOFx45(VJllDx_SNX7|ex&S|*8c7leseZnW!0eR+9ML!l;&dPtp+P1^2knz?J)8=0 zYzi78;$jDfj&KSJv9TXw|E#1}KQVX28w{mEL?mg8lvj!Pn5j`Z{7m7zBT|?x6;MrYqs>IK3E=T^ zbVMhT5FX}aZG};hnO=S6b%5;!Db-d&QCkstbyXOpixlbuP?t?peC(rEqgx>1M~%27 z;Zsc;!oM2UO$cEmy>hpPN1%6+f*XZJv6#)oQc?K05zIoQXwV{>EZh4!6ukj4;FbJH zBZUZ5!W*%s5G1|}Py~>bZc+MQ9A2Q0j2BxbfqPltXd7tOG39I0;YcZM^rYrSyi*N? zSbX&+^>nNZbgk-ZnQGTH)>SjAr-8K*TuH7bz(1Jr8`skXvsoG%*m69&uaA|XF^f-B z1*j0hLqccIoVk1No?ZL)9yxJ*|Nif%PnnbyADb8#lMolvwoR*r3+5j`e)P`0JBZpY zU%Eg>kN}(xVHY95Kq5C#A|OqoHLw=MPe|Y{1-5ZXm4a^vFd?f*Qh;qTGiVCNEk;N+ zS0NNGF`?wq#36+#vjWhdO!hwX>Dj#?H-{+;F&a=XFFR}Sfd1*pNfZlY6@oQ&B)E0N zvH%q)s>65iL5bNUOI52Y02sU*+(il~g^(1P=Ut&>sayrpNTLLKi4h{_a}_^QML=k^ zF_u%_I4PQbK7APHyL3ur5Yn zJ9lhDu!iXuyKhmCB2rs0e_rFFg6yn}+?;GQp&YcjYv=Zf6F#*tH^UsiqP(fZY)G-# zUdsEWw=n~9cXj4q3uM2n?=-Ox0FG*?b8-%_&DPP$)5kwDDmpe6!%rW{?67LX;0?bY z05c-EA!VzbWT`YKA|hh`{Q1er$#7dR8`zsyZ{NU*?FQ@=4)OJg2=IpjJUKAZ3Ee0g zhqKdDTQzS6M8`=lT?)xJBJmZKlrK(>4f+8uQJk;E+SAj+rCXN{+qP^zari*b&K(>Z zSi(oRi!WCWE&0}Diuj!0ZM62DOR_SuC_-784+-U~e`olPv8sB|`y&6FFdM^CnLow4 zo5u2jAV#Siu5!f6MAfBt_Q~sZAz|a|U+3m+O$E63mD7I&Fw#6Ku}m1pAhzo zy$AF!z@*>O5(@)kbMt_Z5HK5eN%5M5p2Vq>EKR1!Vf+ScL+i={Wcu{!OP4NPy?Qk# zjj|gW6vx_x@h2;c91Q1dzy0#t^PiqSdGv%mq(n{}J%JtCv!4)?J->J7&eknkVk07% zy}=&%j!TM9sI0)GJ>K8fFC`(dX-R2GVId9)QL!OY;+)jX^o)W=1?5f3dUowLb>gI@ zixx7=A$cYPYY+rhe3Sq@W;}7i1SS>0Cv7dMqBq1EyWWD+pdb-A1 z>Sic0@$&|F)73JCn{adp>{YRK5sX{m+PFkxQ=2GXF(<~e82}N$1{VM&^3mbglUoeL zjx^-hs9gX{@LZuBWN){a)qw}{r&0pbGNNtCFPOI}TmUmopqDOaQ&%0%C?F65Bu-WY zJ{jnMf|rs4GdJPb4cVq5 z?}4=flML~(fS*7Oc(*nRYo<2ro|qm)HcSl>!18pEp+fqa2xN2(z-ih#27o#ZEqzTb zQ$;*kPfguOM+hnPcqnEq7?UH3f}tZAL@`H4$rO+x)25C#f)q@jbkx+qa^jqBpeAEg zOGgNW!ED;P#+0V53klV}CaOJMb_b);BPT^6M@5S$@Ph)wr23C^;35x2I>fpffTZNt z5RxLLCPYXGty$T=pqG* z3h)p0_O>@Ot5>HED{3R*U7z;_^3*nieW=&9#c^B%YvS~bK0fxr4AdM^7$6YXgPSHo zPRRs+BA8XAvdCsl7&d6D6}c{IM$*YIuqXmjMU8@l8LhNnM+_#Ug1lx$p9?ZT$*aqV zL}!hNm4yxIWYB~uh_j~nNgQ1@xa$o9BfKIQ3J8PgmwVBTA~WO?kU(f<5p@bIC)PDo z0L%=gtXrG$29_41y}l0Z($lDe6AfL>x+cbYxaf0sun{6_0|Q1Hc$L+?cUg95^Z zm|8)qLa|P1bP;dU1c4qbUPsH?*vJ&dug$R0$K|ZEgF|U?4hUub|o`#@W@Xg+VwtgknJxqjUmz}wi-BR}ci7dP?(LMvz=54wDn7z?ot6hWCp zWm29-oKI3hGK7BednbhmJQ{EXn) zIz>VPkP{qMT+-%QDv=$KjLM*BbF#OiWS+%O@Huk=I}yYiz%{f+U0@r+YNT0|30D;W z46O|S38%ptidamz_`rru_`(HxF(au!T6MM}m`*j4+*1@KF`H5>^%UYV1xHE7M26}_ zX1uY<*`BzBYA`bLC=d?T#_B*gr+tmnSg?sdB?X-ij7YC_>y{irRZ?0^Ig&HdE~Zls z9{uX8P2e%i81UUOY}k+u>(_Pe)B!w3Pm+i9;-W&7pZ zvIoFO2pf@pv!R!#AXEfTGWuDruxLTv%|u9*;FwZZg$zWxErpZG+7b~?copj-oLmha zJQ%mSU^e`-F%ls5jYfxu#zut2goPq)i;DB*$_^gPFj|=qzs8XX2PCQ}72nPLpJ$rQP^!=Wl`}gc@R#xKdXh$CIk`gxX zC(R*6;y}`?lk9{K3Eu^uxc6O`RAZ+4kofP4%R%+GAp`8g>8~X)gZ(|dtJT zu3yAAqI@8#t4O&NK^LD7ABc#nF3E^YtR5`n5_2T)9dv@+dM0We;t-E*b9NfQu zas|db~wV-yrG`CF~~u~93cSmXI#zeXkuE! zBj7&byck44*n`2Hl?PD=2{4cVNEr)ghlL?ikofL6QI45h*nrnzzrF#8N23l;K`Sbr zsDLO!S_Dy!4%4r4_%Dsps9lT4NqH1k0W%8rfUm*a!EEYWk~a#r2*OeD7@^3F5JWLw zp-5&bCVWT$OFZ!+H4?xEBPlf+i_H?KKvDSCQ}`E8 zNbjlFu0>}GP$Z-@8nlQ`7S#sVDXpV{^c5-cEdcgF(eO2RD^tfS@dfyY*9|ykz%Iv|7FnI)UaBr|q&U zh{)0Mu8sTI+tmf)D{mx}5v34B-{ONMh5U4*Tr1Ib01xjA2^DKJbX1Uqi7;p7W07+L-fL6h zVjJh@Wv8X!hr!9-hJlTTD=Py%E1cG%;r0hKePrR0s$c? zRnK3&d=(#&ECy)+T!TL*6#kekky-$h(2dTRIlZ*B7`8}hBvK$DXTh)Eux>n<&Dzq_ z(|zQ~;T)HclbbD}4s8dkxVbo^7-ipRdTKH_t+Jvim<^c6guq8Z=a5Hy7o41;oNPtO zlG_piRieh_iOL2FVGT}&<)378#L0oojh{roY*OaPPuwFQHWdCA%uE@6z<5-j*%@gK zGt&tR^6;#dghe85XV^=E+7#V4KZ)>)B{*kxkuOVrybK8<5Yvv3w&9Ik`IdWFe}Mwton{XV`G5`uqJKi_0PRx8a8a zw(2?mwkTENf1zCr+JFD20#2%kG$CUILUK$pAc?R_5uk+ZbGVEXk~7$b{g@`nY0CEy6e$>3~jWoKdR4$}HK9IiO(o83ESM$$OhetmK%WVmU1B6N6(iQOw=l;<)zZw6&D^j~Hr~N& z;EXU(ih`&=%~7jaLpB81Mx2uQ2}q+kJOVJSiMYlL z9El;hi#qV}B0S(6MJ9is8%=HIyHnUvIj_{;j;7Tjk+~!@b+o7P`N6Qo^G%8 z(MQM;P=ZK4C^;RN2SyBogV_;LAY5(v#(4`=0HUhc5E3f*4TvrtN`F$OV4#XrpU#9B zb#x=oC4(FcgrI9u#Y^F63NVQPx8hYg+E~$15OBp56F>I(3HK9IyiHs}06mI7#MRBQtxd|bq z$xHl{P^Wsx`;vsrmPat!*}=ytQCfA8SZeb|Na4$6<2iGJX? zb+Bb-plS5hy9lWlwq#s|J4>jBZwD$s|8tm#sh**gi5YL4A;E`f#YyBCSSlUDJL2hL zBq+*O%7FtSGUAYTtRH1>Q!G9`C|?NBkpI-FqdY~w4kwahEw3E%#z@xR8+*5n>KQZ6QUd)?MIIu$+_^6k>QMX znh9=!0Kka}amS7xZrY@TogHAd#S0gV9yNkId=3)1;SvPrC;X&L_D2xX5S|XNlsp|# zAwNjs?-gi!UG3@+PU5%PwQJ)B1Szr9_5wT^dn_Dqb(;_y9UB!96&{+L5Qo1GKpKhi zWGf0)q1u}gbS*cQx>LFnRwlV91**G!_w<7cB&3^RgKIh&0`}xo`NlZ}m z1~<}VMuMsY86ojQ=sm-ROYeE_|L+HxOr=A{e9ytBL zUz~C(3v*9BEZKl<&UW@)+jrRZ)z`PKTseL8$f9|l1^Re1<1xMadAPT&YTl)NJGdc4 zqJ%wM5|h6o1A%X{u7^npX02W)D>Z4%u)(XBE?To}@wnkbqJjh3wx}F4d`M-JV%P*T ze_7*#nNufzI%@bAix*rxef-Dkm!S(MkM!u!Ho()(OxX^={LkZS|Fzfpex!`g-GNLJCL2 zYOX%qU-RSIM7nqCNV~!U11J*+%5Fw@T%(3rt(#XS#YR&U=`aE^^IU}OUD~z%Zs(3& z-+nW4$Y4b7ltWjjNPfS5K3;|Sx#)%{O5zZhtgX3O63#thqhPGm1fB@lTU%6BlOJ> z4G=<~0|nvN+)K$6(xY>S5rYR3Mu!E16G-He1b6~M)B#s(c)B{nUa3DVWv3qm2coK& zg-AdPLXbd6qBS@#icyq_rDBubW9fBzk4o7B4z$P&dj1TxkwdE_Io>YJ_ zAj9&KqA|mU3?DeKyreN~m#!9uZHU1YAOsGtQ=Rap0vQ>;itMNMZ>Y3g)6%ULi^NxaLQ7Ykow}qmM?&2I-=N`{*N@1FQmT$&fbk zL>?rR;FzK*LTS2-k4O%3O5i7hfzd+e$lb9FMap3mL0lqTg10&~KGLfDvBYdL1IP!0 z{V{hy60OO~V<17{JTxvM9Ov_l5S|E82h!;fYUpTX(X6Oo^niXz;i1Uc#E2C*S?v0J z7twZ}f*cS2E8}%))nEXVpB+nPdP1_t=UL|?)+}mNyMeiJ19KxsYcn4gXFfgN6k`VA zHnoLiqtQdVN5=xv=w$5T;P||2{DSicQYaj$8t;x3D8v{BGqW~f0FVy$)<&+vLWLE& zvNaVk3kU>7A3j^&!+e?W-=GiYQ}4%Y)r*yA?R6-WiPd3`iro+am`TXgqD3=+S(CC- zo&s;;UJB#@#=N|o!$%IWtCV9L!E7T&3|qB&MOs=4=u0XDX*i~Cc+I} z$l37q!QOE4u#V%k(IIfpDt0HgqJFWSsl5lL>iz?SQ|A*!G!A% zj_kq0&ED1qJcdS_fq~jRB{4oNIT4Bs3n3lFH?lQ|6UuzOJfwJ*cgOeIV9PANPwh4;uRAo&XpFD9Ci$2a9C8rdxG4~;DlfaCKEI}212w)@6dxi~{ zK75?~H|G4GfoiI!{16lup-=%HEvq4AZj66Y6xpvhSVUeWlwXIXM(-M?|;=B0~|@7$g_X(C>3Y|Km>=jMF3WBZAN2RNG&Yh-3fNpeC~#f3S#o(|hf zGg1=QeX;b`<%>Vwxpn8tr5_*O-?Cxto~>IhojJ8=?yO)RPglDJr;Z+ac<1KT3uo_e z@bukV$9HYpx_0IB`?t2NTirM}Td^S0gf&w*!Zd3WN<{Lue8K0}F8uJ*;|JF+pZk3FbT4NIDSt4-lO%TC zNQ!i{fheN}4ch+ISD*Cm z@7;s*&yY=#K~GbSLshnawQ26O$*FPCuoKkE7KVD7wQFW3CoG-++4YO(9^Som|K6Q1 z7Jr@)9S&fC9fJ_yzp!=qU1)&cxRE0keKr?gl-eNJdb-$|`?)yx?b7+%jT_Pv;^}rI zIa(jruBR^4&6tNF-l2<1^71B+9owr*XIe+|VYtkJa4}%Bo1@*(f&JEevBbv0T%`^M zF}7+}zG3AT$uW_bi37;(EzKf={PQwWmwx`)nPW%pUcG$x+STiqF1Bx3g)~*Lc*VUc zY>~o|^#PSvEn7OIe?Rd!ML)>EXjj!@$^3a^h7M_fofejasQ(ne**K@+##JkCUA@Bj z&S#Du9`VTl9AnzSj};vyy+B4!R^zG&A>4t!g zF=K0K78M#)QjpiHYo}RLCpB+cDk~r`8@(Y!=3?tB0x+@4R`e+VY*?RC1@PagYr(d-?Q!8)|KUaV#1J5u_a&}%7F@+1--e{Da(W3kqmi^TZn0t-Ic!i- zqa4;~+rQqpb@Tco`*u$I^iyonEfu*UT_Mgyz`Patk1*BKjS3AJJ7V~T)hoYPw6H~a znX{d(Sc53m4go%%#f@@pEiKe)iS-3t#L=ab$B!8^VrZ*o6+yn<0AOTx6a@glehnTC z=SBVZ9_CveS*hlKX6X+h$y46WsVeg|NP8t=d(Cl#K2b=oUL!XZD1zO9$|w+!)~Z$2 z=L_a{>fEtbtr{xXg0HW4?>;?u@7a}I#HEIxtuaO9HOGrpKbm&k~Q4x;iF{cFZ{GzZ@HH)4&R3&T|n1 zk_fO2^!N2}b0H5ok+i7MP*NEkeJ*mbTZzb`@Hak^jSNa_Iis@a?hv!72X`vtiq&j54v{lGWoU50y&^ z)dwXLRl`-e`UAKSj&hK6+E{Dsq}OrJ4r#)5eZ#*7>@ zYQ(4|3l}X}v=~1gA%Q{2+02ZLqeH`n4j4FQ*zgXmS`F>j_r;?hubn&Bq)~p5muLST z-JjgQ_w2#_gotps2D6_Er!gVRxL~GYm7&fd2>p9@J9Fyz`BNv>E?G2h>g4;kZalbk z{l-oO^U?3W`{U>5aqJefvJ?i=$l3Jj12w?_ z_b}f(dGyNp(?`DFQ{K1$m?St9?vF6_2l8oZP)>)c76*6lLQUCKTO-_~)o?(jdisIdvipynXj3MP2QUC9 zL^^t8ElmeY3yPx2$M)~jXR8I4e#jj3bhDBZP9EC-`}3#cMhq@!m>wSy?COHk5Y_(^HxhH5xu>z`mW^#*G{fAmPnIQUV5Mll+TWTG;h#;qXTdho-4X z@fXgXUb%D;A}qRP`lRs(_w4M~y~~V=pWe7~@zB2AhxhG1efZ#4>((Shh5=FDhHWa$ z2FBo7$mCci@XCO%rTO`IOXGXIaPm0opwFgH*}i4-wM*yE96S8*=Jj3Qd|i;8VTqRc zwWTFp%FAMu(yo|CCyo{5WZ7AnrzXVCo;r!a)3sgeWuMQZs<*FP zx_0gii;E%sdNb-|J!L3GZ4zHG0MLy}IU7%DSy}PTmm2}$SP|fFp+l>dr;Z;k%4^uA zP0Qu;=4{`vZrR+~7tfxaKYMyefG?$~K-wD-WFvW5nY*`by>jmCh0~|bo;-2>?3wPJ zIx-l(-@U7Q`*yY_Cdkv4eE!+t1N&C3SaRyv!P{5QpE|Vf=)N7-u3ToU26}q%8PawL z5gR?pBSHiHhkY^-g~F*LhxhN^wP*X*PHkGdI@s}AEsP94n>lsGk_8yFBe(-{C&ol> zT(k1fcY7EB-+Z}Y*ns}n1R@Z|7aw+pe4)TLAPU0(-u*6O@_&OQBlwU|@|3r8QlN^t z5P1#NgnU3Df!XBW8^}!oZ|b#b)nWrjWwVMob7v14{0XPV+oCl#Hgt1yLF_hm+?Y=W z4dkqO_>`TUP2YZfcI@1aJC_da+BPjKZPTh{rw;8ogmlKVsm&_O0dh1Sm=qry-M3G# z`Sa#-seRivEn772+NBdfZv42h*$uO30wOg+s`v57;w*cK-$+!|6E3F0Y$Q^1L~|rc z%m&(Yb#-msx;6Vuv1h|<4$Q`L0g#w91JXcc5TaD6x+P9JSdQ(hi2i_N@&%EBbiP@t z4d@c80!5EW9I;(;Vl2W3CSFz(teTOuva)E}r19Nb*B8#87atqLjWn6kB;J!{a<7DH zs__3X+rLF??;6{0kM?(@{6owpN16O2WgTRkr&Pa0qI@oi3|Hta>DoV0iK?*O8<-8x z9_$3nf|Ctre}v)p!`;Cl zB|7TH`SZX3{Jd?m%Jld+1a5!+^2_f(JuS`4wYRij>I0_{!U!N0eiQpQ_3@3VzhKt% zySHw9vtfOEzU|zGCl2m^`P1V^H?DyLS+FODhm0IF;Kff*UOamWV0-f8{iAz#x6aIn zb94D_(}th!-<>jktdF~kusBi}F&hAJS>Lg$#mx&B9$dc$Hp3?sY`TH5QBlKez}4^1 zeoBgraI`SD#u?_hwC*5Ebl)Ws-@WFf?Lmk0J(M0BE6141o&s8~*<5i_hoGjEe|0 zs>k+EZFT|{=VsH-ySHv>(kNFS3lp|jvgc7#JvlnESxHe|Mp{I0z<}O8UOxW`hf2gL z8KPV`HL$0wsBp)YEr-AVuDqxa?_0FdKtnw@IeG0;WTcme_Up%%OpXbl^V#U(U}2t@ zmfEFt>rZ<2*u8b@qx<)^Y~0}G%n=6yK?&P<_Vnr1iwq7p{N0|X_wU9>hFM}K24>Sz zcd)kDyZzgjPan0eXo_st27_T6YoL2!c1EvG9jcm^Qeg_;v3c{;M?dCeW+0XkvMi)S z%Jx0_cJjEfSI?hA9>U}3bEF&qClYU5ynskh$N+V;*=5YYD9*`2aQfihy{aaqjWg4~ z|8@%lZ{v#PbkV?G-KDCOPJj{TW~8z+=fdfe?B8d@3snUP$3=#{eERsv_j_Z*L-61S zS(zAy2l@qid$g=5W8)aoP-I8EacT&r0&Gak#+)zaa9ws(VZW_uW@?n1o$>hLy`A5F ztJGaPpXucCY)#Am^*Fi=plozo;$m8$>N-}RHXWL7UpM;AGvV)L_xz$ z1_qk)w8Xe|E0#^2FmCkFL0dO%-0}5SU{TtL1XxJh#KzLvY>HHwwf`+_lN_OX_zoWQ zHb1%&heCil$uR zp};Eif7#htqehP$I&^T)?p*<6guQxjFhVEhcspAgzzM=DNWwPu2v3pow4yQseq-Mpe{469@-#RaHI#BT$=#%4lsK4;9j0ux zliLuO3_wc2HVKnJZhVQP5Q5f#ZG4r)sTFy^Y}8XCD`auV-$>+TkpfA`O$i9)=FOfl zpij@JuwXlD3pkOvv4M|=>&$7BZe6=PV(4HWZ%-aa`GnlA!ht+XRzns3A7+z7_uqzZ zkL?dm`RADJjYp`yCi#)dtExCF7X`5W<#8(L^^YTOU^b2_z&YEWzyJB-IYOGBe|hoC z(??GczHwOmgM0U1zIbu*!i7)AjFAo~*nJ=mi?_G53itInvS-gP&z^N{+orOpX!VjM zf4q3{`?F`=+O%J^Xf-B~zedU`}y!^C*R3ooBN z`RVq}Uw(YJYT<%LX(?-$F8bHM{&@c6$GbPLJ^u0jv3+|gVq)T4oVF}m{NU=PiK9pQ zdAZ}an(qxQCvXDf(6*xD)`bhtA3SK7l<0;HgQbOyu~BYXDl26$TS90k`-sexLyO$) zY>RVq{`KoGJ2tMHI&$dO>sH;ka^cfqgAqU>OVP%Zoz0Rg#1I)78q6F&e!+|x@OM8~ z7kkB#qH6=|Z`Q3nynA==jvc`Ox^+I5ha9mH73h+cln7S&_4%{-$Or@obOr1W&_Y#3 zZ`9Yt2oO2X{hK$)2GitT9^~cdFr-hfr+06Ezx`Xb(3&xaU_Py>ZfT(3FgfAUsS_s- ze%G$5!rh?(hX(;CuvG*4g4tl-92;ccz!LMn-(Nmoy=*ZXqO7pA!Qx0;vw2C;y<0c7 zZ~n5ZQ7*1gI7dmVR?Yfqbts%;8j!pp;A&c2_~-AxE?qc3HX;-r4O~IGB9NPwW>s0) z?r*jn-~WB*R;}n{Q(b(t*3VB#S+jWY?Q7RY4j3TzcL0YJzpv4OflKDjy>j;K`D4eP zJ%0S>FE6)k`ZCPl&;0eaV!0U>!$kx#PaoVvgxCOkaqRZB)ZOfD4(#6X;>QPFT2(n) zTgoFOB-NwYo)4?{v-^ZFAG_TG0fk3=;6#>|!v<*~4A{xMh`}Q8#v%6EPmI%Q2 zZrl3jAHO}gaqZc|`&Z7Mo-$@6MY&j87UyJz`gmHi5k?UL^R9^yvc3THVrd4BLi)!r zfG~GNe*5g{W0cwm73a^M@#FnF&!0ZNb@{@-{``H`#PPAgf#H7MjT>fG6g6@XN1VJm zvXe-4Z1s$^i{WE9!v^zI%%$hbeH9n5j!K1r(etGfi@czAw*!{b9bZu1?;OgA1 zZL5AgyJ9PWK;vDQjU55|wr_iK_s*2DWBB^oHE(wR`n89*ZW6KvoHSy1W=!tS6(d^c?S4>{Z0m<=Ap69Gzu=t%)= z><`V$&xwnVadB~KfO^r|N>&NXhC-9`7ybNw{QP`SfJQ}xg@=WNg#`P0d!l@-S)&Fh z1xcd<+tfHuDmEr6IWfLbUT$h~BKZM1NV*W&f!TPXqF@4*37r%_A!)u1W@CQ=LN+OC z1GdRHyIhIW1ZhD;HU)F4lMd#Tm83LTvSh40f~~LY0puzv!gz@fNgQOLDI%Kc>_g#v z2c&H(dLyq)8n6T&i3^2(`%QntzEU2(+wU!dW@Xy!1vz|=-01qt=cx0R<_Dv z@p$~Ox3r873^=f3$1jf`5AM~oUzg51H*fy!>C=Dx`YWQRKrc^#3T#xYSe4bQjKE&e zV&KCQJMArNS3SOYea^VCjS}NO>DJ}y`LnXWJJ`asE4g(>*U1UZ(VxHlx?YD&;60_kk!{5vEvl-K${rHfI0UeVg zBd`$jacy?dEkbTX|t4pdiRc!GWAEB#zTUj>nDc zarooq^V!oT!0VzmoE?N z+n0s|hd5~ulRSLYG7SFs?YHflHi77VefI3jl`C9q8fez4N!#fPhCzKz^)P=QAo`!b z|I)clD-@vEt-76@l zD&e3&p;K1290E2ddB&uP2yMRKw->yGS_-yH&!aHCapA)DFE_#u@ca*KqrxqlG&u@p zJ9jS3$J@?8f6A~SS5KeZv}$FDmj?h6(9U*N5CWL3VQLauzdP5iG;dNI;_F3KZOu*6 z;$oiOyYv0dZLwj&U^ajp+CVhU0AQ|S+_it#&QU`KOB96cOJJ(k7Rb!lV#g@nIJMM( z|D}x!oj3hXPaggL^5>%m_XB}sXEp!?;)?(!AgZIf zb?89W7ld>v3jMT%_;xL;5IM3@lzsrrPn-BDHl+jm^vq66M*a7%-(LRf*O&i#`SZX2 z_^nr`_Fj(mvXVCV%2umW9b8q%Z^SVeLq;miQ0LB=e&h0`xih9UD=S5d{l|-+|NQfJ zl%ZG%?D}d`RdJEEp*~*$5D+;ATU4qSTRo0#`Qi zMUuAt?#?g_5aRCc?uI3S5G1$+x8NEG65QS0HMqOGYeE7fga`?7cf-!VpPI>XmYx0f z-S>CC^GwszPp6*h>gwvcuexq4&QJeTU0k$d^{P>QdY?af`1|+I`T3by*&i#)^3R<( z7~tjNYHs*GDypWaXxg~3HpWJPF?9X-MAJM8zOn@4SX~XWojryS*aIw>IfHc;>^i1~ z8OezgM~`5+fte_)B=*KSnhfR{;S*mydU)sR6$1UC9+eE+WLzkZ2?vM&UohK`f<}lK zvBx4zKsELP#xYWm^O&@u$>o4E@Ne*JqGWw^tPOs{f&`u#dt#2+@Zn`a#UkgI-+mD>SP1;Y zh9;YmoFUJzwvMK-d82tWk_RV17b`C#Lp|(QUp#&Q;r#l=Q})ju-hFuI22}a5LH(^P z%qYywQW6WsI>;xKq;+4#0sZiwZ2xB1@Fy8g_`kjXD}438Y0O{M$@%|9wf`k%`}wWm zjA#Z2j55($QH=8fvvHmQ`2*1U2S{UZ^7+U2|Lo|8s-#Cuh!2vy6YJyZrK_h;pxijL zVeR^`aT7Lg*mUvyg|nwmPYMe&(l;QQt~LQYF*3oJ2?^ltR_qDuy!SskV zixwut#C)%*`Tp(OimkLDx4fjVvaI;^{ks#}xA!+OzIEhaabEVW?OQxu zoe-?d{}`=7o&cF5#*fcSOZ!$^i&+0!Sy@?Fc;no;JzF+o%D8dJh=*4%Zd<FHlbJV~A0FtuYY_@?tyESof0=gho;hIPU>0xJc_Sm6}65}-5ek@&5S9UJt40ktmho(jovkdlu3pVB zn=*c!qooB#fJzwo%VIS!#_izv>{Oo@MoxgGSHq)(T*dq}@++z@ND7i3pFbdb@`h7bTvp_XB~Mq05K zPNOp2sCxG<9U-jFo;WgQ_>jlQ) zu#jXch*h*)Ln6IDd-U+lt5=XtSef$dzE@SGy^n(%1S*dkI#@t=DwMcZ=mp6-i%=Mv z4Q0@pgp3j46PL^2iM$K+QbB&+_AQ&IgiW}4QAdnC-x(jf=u3eTaGq zW-BetPxug9Sd@L~?D4j^xR@Eh2{T>Hn>q#ZoKXrkW5m)t7MRd(U^W07#t-iHcJa|s zA7W#sg-yV@1GU2U>WYNe=tZ+5^y@T1Tj188~o&D?Vq7q9cGhZA>x`4WaBqzC^ix008Ax# zDse4QA+SxLJ4tNGKnVHY!D$?WTLfAIqVNi^iIbopFdJX_E8&HIt0xuaa#YJDL<_kz zX9RfD)6)fp!J7$vD6&t6DkW8^fSu?@#RnNj;{j|Wm zCN9mG6kFZ9!vGZTg=iSX{_kKmD@$`*8!J0oYXW@0PP@7|vA4Cc=8T;+RyM4&@n@GL z0(*Skn|OPMbniA}>J*$Y;i;mYJRUxv|JtQX(h}YmWo71Pq-TFj=^WIW{Go_)th|`< zFob66W6>({A+jJ{_~%`}bTKde(}C^VM)d2uVCvMx5!2^|Pk!;>Zb@z?gi>-`Olf{r ze9X&=qTK3|{Mxd@n1}a)ks@&@`w@X zaq-m^6?4ao-LzuW>Q>{u!lj!H4J2)?!rXz;B-`Z=XB8 zanXXS$Btwtyx+TVy`Wj7XtXH804=IYkSfWsud8x%uAVr)bKUCacW-^JDrY@akdcl! zKunM=`rWISQ^$`t(bmRFpRjMELx*I2N~@_T_w{ra*>jLGbfBPIkg83+JtKGS0P>~B z$8TS?`t8%Fa6T|pcM)6FWwffaAp67H=*4qqcsSZBH$oi9bB}FWG`)J}WMb^=9UInS zqK~Rhxe<HqTH1#slCL9Nm|H=I-hdbfztCwm@ickyUIg99_T9kcIjzFx?etjR@zFnM`_wx3g zi-(U?78mox&z(5_^x*?g93CGpA3eNs_DrXs*7$(HeffKPN#4Zk*Izkv8v7s2-gx@Z z7xWDBiw&bPFGmN|%0O!};KFx(`jC(u_iq2Tt#>Y6s;R2NtL5hT^IKM}8Z~erT4Q)i zfEEYTj|(t4R9W4faj`DKE*uxa7GC54yIoVXmmd zU!FU1Z(8>-cS^dbOn%@ zHy4K;{3|Pq3KveF{_?^7(%jstit>u8@^2Dms~A6EfV+jc4#}_@HPXd9PiDgRPq0l~ zf;}&SWFUm{T3&7&o*-$d2lws4mQvyaYimB2moaS0@^Y`8I}1rjJDEC!S*eb?>d$CR zoT0Tz@o%e23Rf3)KOc(@2y=XA7@u5GL?DsI0Ga{>c7xyXk4Q`WKmec6{{3KaXHK2+ z;^BkW&z_z*7>RohT`C4SufMCE&A#p1a9dcjY$+Wm;*AKXMoobBI^p}X3_=S0yoq9n zbzw7){T1~{8b+BjBj-5=qo4wW>jjaa2xLRTfo2dhq~?OCs^5U%F2DTp>#y)!z%Rba zu7uAfK(Y}*r+_uT*Zcj~zyB(lK)@1Un&kB=*FXw(R=)v>92#LoE2Yau3)vVYr(6R$ zLQp`10m^`0pc-6c8#Jf~)WPM3i*gCjA$zU}0Q#j~Jt9_cj0B|s-e>?a!d=m%-(aKa z*XOT%z+ke5112Rr$rKq@m5jz`!9bZ zMHewT8^S&UN9hh8u>@#I$RqKYJQ}(Uv@9b#rJ8wOT!ND_#k3UvpEJS`k#Nm?m7+FF z`7HRYl!HT7iS$7Da2~Q$Hh$4ZNFRPn8QB=X%2E1IgSf7^9eyPS30IU2Hy+F%F2*zf z=9gm9_>sk4=C_omk$gDGhno2lWyD>G)^eURjpT^W(@4rZ#IFg>M8-@EvXzOe#V;Ux z`Ki=48Y$DiGp?nLzj0A&kew$TwZsWilGlhoiN>=hexR%s(qFkLzA}LMpvjl?_27Q~ z<0+^r{l>_VTi`YwqgmYwrNfmzVyrx}*TZn-d53VKP)zoR8KrJ2m;~ zjceVS`1sjbUpjOkC;9!xl}p?mtPM0(G?nClZ9qXIZLRU4L*74op7S9w(ABMbVC%~# zPiCYfr+-Yw_V{yo$-2c0hV|+hOt3ObGjm<7{vqAIf2}zaxo^$9IoHpe201X{n;Yn| z7?uL016^chU9NW4S&0e7X{jq_&Fs|DZ_$j1+VYb3Z=yja-08!cH)c(pf;$6VX$V1t zKBg}_H*bRNDagqt;17rwkOo>qxCnv8v9p~msHP}A{r36uEj>JDO_&fL6Z0u43A?H4 z;=;<}g6$jDP8u^3)f>7tJ#`c=lF^rmj^>itGhxgg-@XCE!x{9LP!KR<%oQevx{_|R zrt-$w(_;qqW4m(1vwL?ci}JDUe|Y=G@&$88hYmE=*JeJ_QbwsqvZ{ud-yDzJ z_w{oPp1d5R>;tv|*d)_Fg~p-%`rW&BE%9~C+W8AQv}l0^W8SAv@iDJIynXYfq8uT9 zA~JH)n9lQpmKD~brX<1WJQl6U&klVFk!=Ro$lzy*|4cn>(3*hUno;m&W?j4NNP98ky?&yF# zC2JL($>5Z9f=cpB=FWl*dwlm+XusZsg30;xkzqqzi_FxN(!xAQyv@s(4h`wyYGD={ z(&N$1>tDarLfFz0fX(di@a7)w+=7GzLByrkBV>@BUpmBo+K>vaV@Vg{y z$hXSMq&IJ_oI152A|kMfFEp=wy?ToEr3SBCwj}!LqZ#30XiFifK>j=+4CI*Y*@(kQ zG$(0~J41`6NeOYRQ3z<0^!{xwF>SK5c#p~o^54C9ft!!Mii(ScMJsP_D?Pn`LP0-% zH8(bdye0oNk#-1MasK!*I*Nq=Z1A)D_jyv8Daj?dId5OSL}AJ!z|xwB#k&b+t3y+D z2X)Yhu0X|1Ke*W1ESf#*b7ciAdT~}35H}|)1Ct8Qd?_mnA3D_4)YM2th1SBOGFQ}9 z^)C)szc8y1{Y+7wteu}ylB1tLd-3QYv~xvq5mZ~|#}s_7&!0NUs|4U@4q*ZTO7X;b z*8g$?v&F?mR}>e_o-%1bw=VOiPM#kzbx5zC=T08O8W!jDxTu%4l4$+m)rIxNM^v6$1c}#*JfiA(&FAa(ZCH>Q%YfStpJjX&>0i#m<&6 zKF9X&zkT^Kc68xm$IzMb_3I1d=I8Bo^3XxNl^4yO16fCBq8vxJ23q?AupyLX+s`8S zXTZi8Q4Fzzo{ni50Dv^7_vl7AA5krNvJk3dI6(=Ikvq@@;UORm23w3aBoJ5qBY>0) zN`YIzOZAZkk|^dB{FA&a#Rs7Xr42ClOTAyD%*QM+0wH}>G0zt@rK)19h(82XUe1H_tDPJY(Oc8uX{15;eu|(kCq$EDTIk|@Q$Rb;Z z*~Gz*m<lA64(Y>6VRmr{9^rjoZ%Kw{R&_MGNB9W9+SW! z{E0JM2$aHK!A_zW=eaZ=@q8&mdHy6$Qj!Az3~AKZi^8(!!;q7RQy!N%DXOIyzvU!f zxda9HIR(UrW6p4%11g~;by8Ryh&|2VfO_}|m5BN&%mKfZMU(%H>?Q)d)&Kq1`oI51 zCvcvY@>_n0%AWGv2p`dSzS6PcTHwz*(8w)_X0WFuKNmmYSUeG`B3~NMS{gG7jnU5Y zP6F6KZmju<^2rhk(`a6KUVLC1GXQ&rqHF{zalm}b3<>IBLqL%DWB=}5pHe@vT{?Sa z?zE}6WFn5+1q7fez&r2q>C>kU9fEzDJvrQs+&6!!6@(K#st_pzy3E5G_UXcz(}<@X z8`gU|*c+*_wICS*2Krc^wyaZ zg&7~Wu3PElVy7>|Y``{TBEp5ma(Y}`LCQx@a|mQzSbtqSdU*BR*;h`VOixK#y=XqFE>aK?#+?my47wp=SmmZB=Oia$ zV&`UMF`|FpFXg59^nuw*b944>+v;X#i=bz=7o=jZ&YdrwK3!W~m6w(2*Q^Oi?hs*Y z^rV1o?44|F&|76ECto;x*iuKQgTMc)Cr^rUb1-+uPzquPQ+9NP05&XSP`I#x(9jb0 z2yT1j%qisinx%`RXdbd)V%$67L{T>n?$^7vyp-?=T>>$#_TI2;$(Jv+Pz{(WCdIwM z54VZCi@k-Z(B*;6ge?{~i2WOc35q`-S0|tv7o{I0)B4787+^oRc{BFev#`)mTLXjr zTejqWO3V3_M$8Rj&;ilA2M6O0K%f#h3M3bfisOb4!~PAYQGEAK9X^C&l=H}35Q5me zog8stK&#%Tb7#iMq>&?DKY4;-BqoBGz&*NobJ2_$xQIf>L0$z1_`i7c2%tzC&Kx<+ zfWb)_MIHzB_(nVF?IIag1ge);Tab!`>=<=67E@Dan^%*_n}Y>J8m z-eIBlFQD3=UI~yALczogGj`O7sSK+3u`$>%d`e0z&da@g_AK`Qpdi}G z(2`iJzW{8!Szxvg@oz!kqa-b@2|8{sM|(>{y@PvqW@mn?EG|q>d`}3S4{@^y7N9(jOu4LqA<3n5d9q8#UbnQYMk zGGUADXMrn&Ap%_dV=s#F69j>upI_%LU512)P6`j7Hf>ty(4nNRc5-%R)j|+xcmYX+ z)JP7v;^gAeE;zVH?_R@4kD3@B-nW1M4xKu=d3b1QYa>M@tRlM@OMiWR!vO!5?b-!T zoEScN^3;%!-hqKZ?rt8Kw1EE_qN!{MPtr(DUBkh_DIlPAhYnp@v}oD9nSax!Exf&b zJv_XKpQNBD|2tHhJX9DAMMEwW+_7U|P*BUjz}9Wr(2~|cLGGTO`{4r%#{WuU|h84-aB=Aj|5+9P*T6fvsDU+i~cK;oiQ!*0#2;?(W>C zfsqmD0sJX}4}c$*Z2J1Gf?5w5Hnex&zK+h${7`HfT3TGX4r++UU~X;QqGe0JfB<|a zY;0_8ZESF@AhQRAD3FPl6i5P=<)DeLmy5HbyPHcBA1@zoPgge&Cub~?EoDv$jg%Bg zY9>*PC|!T#+5QQ$0p3V14_AZS7YD#0I2`s;#(9~GN*%xx2b@HX0~dcDF#quxAiP8_ z30OkM0#W!X`v~{}l;XkEhv8vkuu)dFky90-3>vBt2LK7if(&I#AdruMI#kO6AFcvc z0R{0Vt|Gp2Mtt}xd-&306@L{!5rsMCfIm_AkCw?08pB=`Vqf#57lxMkQl4t}c-0VvUuQeR5_ zAn|*msT@n?WgYTobEMu71=#Z^K3qaHM(nw?_@OAkUJCXvxl2RSNjxX4CI+Gsoh?hr zfnf=Was+0R5Sq*bn&lg3*n`}d44H74fjM9jc6P8Ms4bBe?%laPeDENqaaO^2#SHG# z2lK6@xOZFEt=qJEb#+-Og4N&K8zBhqgkL-}o;3BTlaxxP-H>H)zJB=TJ0rY+Bl}I(Ep-LzW4Fwn~ z$Nf9E=VfOcKe!(xKvPLM3bv%FCWd;U1N*@Ng4sF-_%(BLUOH!HO=WpP?CaXf^1C;# z4(#2NI29m0FdJx%ARE-r8K^}!9{g|tWqp8g`orb6ZR_l>C>UT zLhOu;=1dOfK^Nu_F)ueO{nOHUbGdyeDQ=%+3 z1ZRWKgw)08NDL~-ReBZJhDRRIXx@xzxN%*-biRcTt{<9ruU*EJ{ZnE>MoQwVXOD@? zp{uN@qokmxtT?bo*ISn^Fe=869${&q$Aws5V2=l|MDl{!1i?a%atu_SKfGIARM5)D z%R*Os&g4l%A!AHtrKObR=7e>yd6%;fG z<@(o{jiE(X=wim8Adlwm%DJ;;`FX4<9^SYCe~1x6XEIA-+M&$XC<#=Uxl4d=Pjr>bfyt18Oy4jwyr5Z*lo zDk_@tQrC%xQdh}89RRVJVGuy*_(BH__>d6)rKTEN0zym^5tr~g5@yTIxq10gpKe_x z=1N_SjRA&F5EIeA+`w#voh!`E!d1jbOC8T0%<6CqA>v;d<8|rM_MZs*Wh?!UaJ!V4!{0!ST zDKMV0irRuji%*_D^XSR5H}B%##l64(@G(I&!>3Ghc6I@+!I6-P3ZewMY52&I`wvE5 zyLIzrbo9IU`0F=s96Wq@(&WjYDQGB3+96>j5vAO;x!=v#r~(i64ed4EJr)3<-fM2eUC; z%-{q%b?LHe&+dH(4zL|Ma^&Rc)5lMqTt)ce=FQ>05MZP-1+XD6P0h`_hxFXIW%J{w zPm@uLq^IA!d2{K~r9nYKq<|Nq4Ux)0lcr6l&zyPU^r`y~A8gvPWy!K-D_5=JO#2QU z)HF0?s@2Ba8g+ucX3w2_<@&V?moBYdyJq^#8B?ZBn=ol&mu}sZRaLnIdpB&_w0OyqdGqGYnKgUl@DbWtT68F=iQ&qgpdWK)%~-m4;f8fp@&5~kq1kREaWxQDYGmb+bZu~* z^?`5{1EI06LwW+RNto?V#+C8#Kivd)0HW~WnEnJF!0pJe%^#ynfHb&8iC&bjm~<5Z z-h__{C-FdG14VFNhEV<>LU}p@>VQc^{W63C#Vf%iPI4h?Ll;Kl%YnK`jG_JVqFE_Dtr_9zJ;a^vSr9BiJx>Ieze<6t#@VU9y}w z7>D32CIFk{LkG#Pr*r!FvAo=zV+SKU2DNsxw$8IVmeW_4}9FE_BLZf2cv=^$`jDEqNotNcMPkzK_+J@1esi; z7QQ~)H*KseEvYCiY3k!e!W6oW4y?m$yo{diu6uWGM~vRRc+p5r4HpJt2oU-sgRBra znRp=)!4--R!9hz{?6(VSNxW8=H?*Y(_w3A0Pu;(3o5bG8a#zt_45ffhBZm$7`nmez z@uM9B{F}SEtXsOcvZ&z0o0!_FimMmThji^EQ>02kx5z#~C^nn{v6v+^F%D2*+Fe^W z`4MmoI!G4YfxZQ<5A4(X&UIpaJR8}sFPII_)^|~_z-&Nwf{~Ka3vW=y0Jo3Lk6@^v zdiL+!0TEYOTy!k*fb{eMw1_iV{xZa$my_eQ^XK4WhxY4>X?JMfKDRDksx2?WR*n7g z`SUQ!61*jd1y>PRy9YOJj2tu&2**Y`1};QxELFwGM2^!H^JYcFzl*(f<0|ABSruMA zeTdcBhj+0b6W>35be}sl)zQKaQA?q5?@k?VUcP`d@7}c|0ZbrCd|h0;92~$fP&zzE z{MjJ!7_=?@nngW(gjYzXRsjJ1Y2!wdG@-mGp8y?b#)Dckr=5UOz@A*aUm;rAXmjfp z%}6|vo|w?azd4#~FdIA@V~LH$1!#?YqfAar@_sB#Vx#E%JJ&B0E?~*LIhb`385rCG zGbRkWOtiIZjg5(2!$A70P13$0TrjPXZ;a+n3J+LZ1O)^D##w_pc^025%5laa_=#i> zuc|`Q0Uhl3{xoK*18f}Bp)3Y1HPaQ2)>hNQCt6IE7}KVj5x8xundeO)s>9UC)atORqi zGgt^*J%4^c&mII}s46W=ONuYa%RF~9(w~?+Ci;nQ-vEz^o6RDWYtezaj98iN9Q}i0 zlEt@Bd9!2!*$i2Jq5T_))N?``)jLG5XMz38sk2Rn$ zjSw0QFq=fA{58*pP+&vE)otR85RsNvHn;EG%g)IwE3Yi8sA6APRa018dgIoe4#6G4 zY)B9U0U}M`&~U@%%}J2ql@(RBwY8r=7nKxeWMzV#LVEWGt{_t*ER94MrY1GJMpidi7C9{z`-=^ngajrrmq=nmuR1%a^ay(lRoL=b4%w z^*Z**u@ggv4pUKAm6WXT50FJljbYfLUPtE@Gy%!;a->dNY>l+=%tr%tu7vf}n= z0N@Hi)uvs$?K^kGC%mW37nt17pYa|`O-)_1W{tPEH+O`P#SoACYTlv+(CfshQ|Xx* zpTB(h`t2L_KY8|a{-T9eHa2t|$cv(V~}8uef^c7fhL}IY|AKcIwP&V^dQK zaPPE%j^gXYsZ;JgdYF%KGLZ{vS%*~8hNQ#~&6+etpT~m$jiFVuv$H*a{%lHe65$o9 zt12rh%4tAZdBuz8&qfR%YGQ1Nc^Bq1WG=(}QQ-%BwmS61m}g@E$gH6-2}9e(F$(72 zIsOB)$q%nJoF|atz_dkOOe> z6lQLkZ{hlR7Qd|pau{beL_2_ifTFFBYJ>(sFpgZ zLDWeBTF!^IQHHD3U5Ex#hTGvn98j_W$edAxavgiQ2K9kzv!+KZoe7BXnPYKMTh|M zA|=PYxqbN}*7#Cp@IN!ugV|U#5kVB#gNNhB70U+p?7n%;N+_u-7tewxfhC0O;I0Xh zAQs~w6Xy1?F{AUcv%Y`-hCLh71dNI><@N=@V8vu(Wx+}u?bY?OXRY=1m&}^=G4Vre z)GM--B3lux{!M(*NeQ-xFj=@j(k*?vcbz(6?8AGvlRm`b4*;^88sxP2-| z!qNj6{}3i3E;a^ZCq@M+kPvwkLw*5=AR^rC?9LrK24*8bJ(vw$Dhx&qwo-R)vnM(S z+9h;M1P?)lH#0mO_m;=EZ{zAB)K9=F-1N|1@x&RQG!pYj9u_$WKD>YT;NI=-oq~Nm zT+v^n!6d%}gka3;C;%#68@Qknp)R;pz=^|=q)VF=CTYZQe7=A6>ZX+|sTmrOo(Ckb zu@LZY?)&`FJv=T4bnn{S-F5BK#hD+IfP&PC!Vx|Vo{d(q!8!ADf#1AcoK`JffV(dG zXcG+j33exSrW8Mfl{kK*z&55If!R_L-{UmBY3=GR!EM*AT2We9z_`Mu3teHq9^G*$ zXzS-UXY%A(lP2+~e?(S49@7bI6u`8P=L<`Y23ljXVHmlbnAG3vOJ#6w;+L zBZoB+0g8#ar$=~+zu?*Ebh5^@a9BCQ7#A=Is z9nExf>CEY!Tep;#mksGpOzJMrpFTNr@7}dJQ9fb;1`rbTk+GTC z?*02nN>@-;nwFIbwqXN1J$(FV)R-|y8ibQjO_C{dQ0TDe*tgVET2WQ~`74!kiR-uS z3>iM0MLT0oLrWWq&)mXl@Q`6APM*!rFRrcq^5xt2&)>cmm6kt$6+L_Y0s~Vc)(oVk zBWN;?_dZRU#J+t~R#E=t+t+W5?{D8~KG*UUs?F2en?^#i;gW!x04&+1D_07EOrL9M z;rH(tx>lEzl&oLB-o?cQp$6}PP(vnqczLZ{z4}u|IxwuDsPN0zua&qgrGJV%bf|^D zKNTXR1sa6S+q!+*$Fx)`1cp&FKVknNDG|ho_KT7rM#1teTeJFoN^)UYX*H3hYHEt{ zI4&!t{va$9v~{_0HhBdl9bNsMyZ5GiOvCpEs9aO~g^gRw&dwxiFqjQGl^2{vnW{3v z^e=ffkQh`I00}yaCrc~9NC53$ev$HX0V{Yf*bv8*L|CvfYyf-G*Z(=gCId$jZ~|S> zlb{6wBm{V%{~^sp1Guy*#EvS8NXc24hQTuZ^7mf}Aj*oI4R3D@2kZU%8%Cy>AyO3> zgK7aMU@Gy9>VOt)1*K3xUH0Me@l^sVGHQ#Kh+hfn3B!8|P*^}I9y%ZD_kmbp{Ofu}x?*p+O-MM`Rx3Uw*`IF#&85Il_ zAe><2IFA-jOp@>|Y;bOXz4ve5;1P+DaA9r^NMqlwoopA+o>{egDRUhOny+2Dcsw$) zf6t!iQxFa4R+#+=P>GTpItqmdUzxp$J$Y~+S#MI%-w~J%Jt^s&X3HSupniQZ1A~hj zHGC*-Ub}Jy#&3k9|6E*{m-aFF{ksWcN7~w0NWp&U{|a=$_{so(3039xL4mk7u<(Zg z!=yRsef*Mz^LupZ%pA*POS~rZaafUIbB^l-`NZ*lO^kbka3_`0)QRJb^|WEPU`2p! zs7ED^OI-!m*(djImzUroT0$~{;+!mC0QAerqepVGGAqhTv(rCu7a*<~)24d4yMiJ- zT%31p+X^R1UQuKy_bccTkQ=Z~SykD>(rm@j#TCWH%q19#<3O79_APbDIK} znwuEy-MIsxNVrslKDtYuju=Hc8tPuIF7(g0Z(l#Wdy8RY)QjiYS(&7SfOLhVjf;8B z$!ixcL_K}7e9^)gQzpYZ@igI`@N2+Lb?3&7L{|V)2{Hu56CKNw8a$xygZp>D5tu-J zN=Zb5@7cMPu;kAk-zQv5Tuc<2_Z#QWESxco+zL~}#?g}~;-&DvB_*$)Kc6yY3=|o> znZ%6{P>Zx>8fvZlo1Hp#h@fF9ac^HeyhpXEACrzA+(&nPsj48K5h3@<$2xKB7+-fc z!0PB>L&J+{ic4=iJFAZ_C9@%X`=PstzPQDJl! z&6~qmihA}GoiYJt@lrf@{1~@fn3YNDG(pueoPORkWM-mh-&i9sp z3FC^11p|z%jC8i62P6B0^pF--9}>EC?#MtA)6vg+ZB4Zq)29HWAKkybXWQn}M-CQc zXC6O%;P#CxAoHtd&-dxj88;agDPO9q65qcq%+16CVdkXqV+Z$VNMAXBj(Bt|H}LQk zqm;IB<6}k)e|rBOw+uX+Gd&_JEfqTf8cBwQ#JIQiHddq*KXc;vt!r0#o7k8NxFb@K z)BkUyqh?K;3g)DHu^a}eQYXlbF8%K?8zR-j-0J?Lrv=4jHDA6}*3^QRYQKIfEGa*C z;Y!=~9gtp#4M+h@i_EO7w(r@UfqUyqP>L0`b986C-Tw_|42MhlCDGN%>S+2@Hacs|Di~mXsx? zq%K>v+P`&69YZ}eZFOx!9eq zW@LGgbfaK4g~n1UVIK64n;_YQkR>j0aEErJ0~lo0CNy;a1#E*R0xAFrz!G$ifFsfq)tr7BZXQ+<7X!C!&9s6hZf>ZE3IUlgVi zU0q$0%u)|!_zIc=*RdDB5_pd~`MI^VHC(Qvqa&5@5ol1{lmJ&+niy3=vf=(?goUTR zo&ji006A>kz+Kc21{1iEQ7S5-sr-rh`4b<}DoXO98Pv}nyvN;HT3P}i`4wMjE$3CF z0Je=WM!*eO!%-7r9nP_R!jEC$FY|$Lei^POr$wrt;9Vsh_xDfR- zMf?c)>=nq_{(zubKraB94E^T3A9MGa!|GvHZhV%>_IG|VeZh#X@ zGgJTOetmj`4DCB$(x@>b1`G;r8R%qXqp6~1VP@X3U7M~Q+Y^+-h~7D9CQzP*ScHZ5%2xDi9UckaNd1OI{%!$K!doG@|x*s0+YIq-0G7JY?)^Y(D- z*{ut6G;jhWgXE%fIN;tJ;!>p0xT&{S__(o4=FVNWge=&z2KMgd6;;XZ6o=;C<` zmMvVgVa?i=OP2NT)rU@Su(q2uZTiyra~I5>0egT3lbL~B68JG8`q6JG@pKfGu&-Y* zbN0IBE4Qs#w`Jv;`4KZZwP}Zu?)1r1*REW(d;5+<`wr~gv5RV{)7#A>e0&&qJ96Ky z)hm|t@6(g)SF95u?!Z5iRR*Y4QQpnPY2vuC+c#|3uzY#sjvf29ZJRJ=RDfS|IvMRY zyel9O(?l>p&#qkA~`}ghJxq~425J5y6BhmbhO&j;^*bZ*lyLD?sSQy+LASNJ$Kf05Lf%Qfm0`k?ccZS{OJ=X4;?sj=Fe{Ytqeph_7>wKp|G)ypJby-99m&{0Hi{TX z|6+ruSA>21jininV9t!`+cs?+HfSK20nIh(M>nilJ!j_h{d;!BzkL()>Sg?!SjbWa zEsjM$*H#C#SYh$PlAh7r)R?#F+2cp^W=yB^?JX@#y-MO3+ z(2o7N{fF|G@-hZS!P3V5#Hn*{-X-MZ7XjD+T4j|ri79D&_aE{LXoRImY$iD2gAn3 z!R>nw`VATki;cl3aXtVo@N5GH4te)3AuB7du&}hSxGcAzC^bFvMbzv0i@Fp(V?fg0BEeuqS{kHgvVuZd}jJ&!ddQag~%5 z6cl7;X0Ben+RMueX(*%~G86}dgNF}M3}{EqZ27p=Bqi?Iw+~`X+>WTTS&J6C_wJ1=ziJ94g70VOTQj$ zcbYo7WJDmM32jx=(%!Lq@9Q`3=%2iTq8ynjIV(H2u&`iy#8kv941(|t|M$94^d~{B z+q`-e^*-Ul^XD(_+_`)I{)3kC*?G#j^%D0jM|-C26pyr|0tJ%O5^`NUcYX z92q@&w3U@r9mgda0RG`8ptTh%R$RDnf%`gj>eMV!D{5*|kEo5-(oX8_C`_fs$V~6pBTXPTu%^a5n+E9XlEGM#FDNB_ zygV$(ghKQZG}c-=_Exs$`bKWH4i4s4raFjxO$cmaneZzT*3%?vK(?aBLUclmNSi8s z0@9E(Gtjj)H^Jl5!OGmu!j$qvtfL3hzn5e#kT*WmW-gIfoplfsM&gaEOFm0+vp%>tV>Yvb2~ zblzB`OUOz#fayuD$O;$C>EdX|&0yHy%D=g*vprOyg{hI3hig#lfR62gx_4~fEx2tn zPdB_uNpx;)X%-mh-`1~1OJ5(7y$Yv4s5XYK7`>9hU0vDT#WA>bOM>eXU!{Fu0FS`T z*uc%zv0q3J(k-z8HBpU0+tNe8Y8puT-Z3?4*?Ji^~Wm;DT`>dt7$AOZ0f zc)vJi{Iei(AT%*6CQXe_!R`E;<+b+rn>`}}@~Tt&b{uTmvI#^4{Z1MBgq!`jwtt+_R`1j~cuIKK z;`wtH&YlrAdZeYPk-uNl9wFVDd3l*==$PvovvbNZC<9a}aW+`SW1hsoo| z0T*$+r7L(uTWiB!lQ10OBv2f{%L&r|W z#wC(gFs8|01$4;Gjn~<29m!DT$T2NY^n3{Iv< zw4$=Ufl<5m9S=kvdHy0gH@C2;v?8alI6g7?!qsat=gw={wzZj!rG~z?mZ6TNy)_!o z8@F%0dG|IaFBi;)5)*5>7g4Wpf^cwh;_ARfa3dR*Z#WcSdj=H3mJE_DH#avXCT9Np z`93~A@G9^RNMvq{OxJ7IuLGoE&&KUQpn*kS$HuH&v)aYYjXJp<_SA`k>f)tK-^9HG zC8FhIkDm1T%NJX=Z3DA`?f`5wfWk(mrei0EpSpB0E;%V9FE_8KD6gmxJHS(C&-gZN ziY#g*4`!2RQ&dq~xq98{vlrgPCCK#1l^FiLPe{zjNJlqnWTa1AE`ix#>i>;Bo1U&t zpWc0Qa`H&=_vX#Jn3y-OU&lsA$8gM?M`RsF2qO^r%*G4IR{`6k@$+BlMukoiGKW4C zfCR)ce*E~TsHkG;Q&e11l$4x!@K9t>n?NoBT9Z8)3AYhGZOGuE_wGK(&dMz*#)`8z zBR%u-_ve)(Lm-+@CORqLZTw0fD$K#i)=202?>8Y11Z} zT2xe&ot=#l?cE?wGo?AWqR8}DY#^o)!NS)!__qy>cFw;(_%X^R}OLSS6g zfPW->lx*geiGHI^78|@5)g|G}3P1y0oUysRt5?&2*8V~5oA?KI?A9x&eP>4(PYrDY zav>V1YoNN)P*M}iM zjiBK4)Ku^a)Iue#prEU-r=_RI64k-k#l_9t&E3Pr#Z?cVR4nYE5co)uxTMHe*hFb# z)F;DiyvXX{Kve}*HM&|#H=qxKm6Ov`QPq^x^lF;gx+W$T#-^5**aJ0l(sxI5;V|e$$1#MGR0wU>Zfpv9sb$QyRwswxDW|k-s!0E(`Qc=XrOkNWZh3q4CoU%OO4Okw4 zSftQ=*gwb}K9n~3H_Fh*5) z%SPNahDkgs4X8H28)0gcfp8M$q`_nx(a_MsYC}~+T_45|Dhd@asVgMu&pLuoZ_+cD zg5S!_Bk2SIu4Kyujupw>0AIv#Vk9smwA879g^dPJO9h)=H4PeUVQxX%NIDJAN-Y4k zvJy38!KKdIE?W%&T(}Cr6`;Wj0_vnf+JHqFgI`Mx?p>2x*45QlXVs&RGq#a~y`!s> zqm#9z1u1|V5tWWMaF0sx>nv~(J>Y*RciJyK6zMVH>C+fg118tkB6N#7ZhD4BM&{<` zx;i=pTX3**XwkG;+n^v1a;@sq@$$sXkgPSNQOX1&)hrG;mLMzY0BtQZ6Jzu@E_OEN zMh1)ynx?_LfISwkfvTpSx{jl@t$~&{>kj{B0Q)9Qd|WZrlWrELW?48&I+kjs2Q6E$ zVC-RUWzn%s>$U-YXyjRq8tQ1BQEsb8<8^GcjNp?&{pDSIE|_Th5(3`{qq- zUVd(VK|V~^mhD^n_U~tDV4ag7+yYH}BnFx@xt%k1v?5K_e;pEm~x@36rMGp11JQwHp~ZdHKa9x%q|9Uc8Ep zjh#Ams+E<6+#l%=2=wvqd=N;<+OKcF4<8br@#9xfF);wP*HKZ?iHS+=+O=m|5qf!; zUfJ8PDli+cjq~V9+5RPR18A{{KZyY*jyZ`ZvE=wm09)*yF%p(Dtf+m`#7E->VD)m$P zz5|i4wS>2$QXmjbK;(LQdeM!z<=}EtU0qXFR-Toe^YGy#ODiiLG?)q1Bk|n;>aAM0 ze)9AwI(U3@;DO7Dw3(8ES2fEAO)V{nm4mXTwT&CQxOwc^AIXER#KgKBF)Vq*AJ>=+w0#C!$+tSjfv zVe{P7$D7rzz-e`R398j?@<24A@&IcZYpKZ_scY-VYiKHJ>Fb+1czCz&7BY3w(sg?e ztlhnD>E`VbOIHjW7v>YxUeCrsSIaJEKFt=yYx=$Yyw*2z(h z(T+Oerm>cayn$p@4`IgJudELHrOC6y8m+OlE>pHX9-`_7mOAz>b}id=8#8g_+{NSO zFB?8>PWK_Bo3`m}<=R9=*9=NY8|g+cF8PLu-?If4Sva1e+w9V`dqr=w+LYHaJ|>g(s-vR%{Q9?iS;bqVZX>luKrAtElQ) z+nTw0+Bflc4QT7#rc2Xy-5q>eI(RnKGqqIH(vt~PCCQHiKLR$!17aC8r9mev@mCF1 zRYNsZQ*{+XH3fPbY^1HDV{U9t>QOsaFDK7t&4W67wrJzz)xzGz)5^wH7m`#R{G*7T zQB#EoC%pPhxpJUuMz)GP=`3NGu$N$+-%v%qfw8)_iK>A%k?>S?jcjbp96Vi`2D!Hg zcJggwBZ75Tr0wz-M5zNwv!v$u_lw~ecpgS)qdjlHp+v4N_l zfufqWJZX#+(6AE(U*gu3knJ1qmZ+Wo~Qh z;O5}!ZSCrA@9Aaf;O~~(w3OI zj51m&`BG>ZXz807+1T2+x?4E9S~$8}IeO?DTVbccn4}E^>Lt_(K`Kz;N$2Q32@NV> zYm1+bDk~{PSVuM95nVMk69aw1uJYszjm@lVoopQ4ZJoLICPo(aMyA$aS8%nCvYe4> zBc2G$D_|S1rvxQY3KL~TL!COYzQnD8IyK~#jI^}0ftRYhx!US_1_o9(R*o(%-o7@D zZWh*#mR1gAnQPFfzK#w?o2>gJ1`HyRJ+-lClh7dekW~RDIBL>AJwUpqCQAcWhpO7T zT2QK%HfDB?R(4Jn3|n)1U3FbOCR}VI)a11FC9e(okPU3i#(@M`8DlV(pl&H1vOMcb z5`OWv>Zqv^)|Mrk4ye-7(caA7(Zb%w*vxHKJA2%?Yt&3~No;{bZ-*D{gxign8pT2PE{-Y=3CQfS7 z!jFXx?8`mdAO!EtD#fp$s2V5NY4<&`l z&&F>Uvb?RRe9L>nI$_bw*( z^{^2`+qQ3GX+r~4nP9Q~vU7HD_Hb?AzU{)fbIzYULCl|97p`18dvQuwc>jI_+O`X} zvbM$kAEmFhx|XxOV~?)g7cW?J>HMXbsF>sr$#JpoP8>ZxYWPTND;p&>_1_val9IbC zs~DJ=HVYia4YcsCh2Vbb2i z$L>9S5%uo<)9BdKm#z*SGv3M5TT53T=Td?RE2yXvRjn%)b^ZEp-@7j+{(W3ha{Pzn zTX*kYyLo%^)CfmMClueJyAb;&2q? z{Q_Fud+?~Tx;87ffCvX=B^CL3MF|PXxB#o6xl&O>7ux`j78bL{2GOz6Sy>q+1x5MU zc^RLwGPCnC3yL@H+H2?Hgz5;mzeyGLV@8bai#Q_XwfRD!kdNYhjj)ic6_8EB0-o3Bf zz5}K#Ew7}hY)K!}Za;W5dg3H~6BC{Ytp#4P%I?^y%dr!uFfPShAu}icQ)UhZ3?GtH zckJFrkQ^ztP6Hk*TI9wqt}dIl@5m}BOwY~BD=N;(hX>A2O-sLW?FPNX3(Ql)s*nxr z&7KLlZM!zxcWk?Pdi(AjhmP$ye0=TBy|b3B8Xi7v(AcoC5wm=JT4)nsRY^r3&7;f{Qzp42Wjdgg z=}Su$mWPQ$Q3{X1N?$|6(!sSuzY)_{Y*?^i`||C3Hyk*&c=N8IVG&~@=7r5(92yo8 z*s;5jzHz<3{bIn3MCv6~I2<{`eM&kerfzBF4Syx4q1l+Y0H!*Ijq9uE8`*jX2KO2h zHf_cF1)F!R-g|h?n$1HeP471{Z0xkTQ|B&o@olN0q08z7h6+8Jt`<3U>LXj>Jpe!w z98w|RaAN=%<}DhMRU*Wrx-I(0w!z(pjOaaL+<-BYhK!%mXZX181BQl8pEq{$%$C7j zbxq7AI}pfIWUCZvUSchH`D6j`71ZfR;H;{gvXT^QU0Vr8OWVlQ%B7iq+uj5Ej0kJr ze|XSXuIBKkmk1uv+>hchh#67??jz7$38L?>6yj5KW3^%cHQqwh%NKZvMs3GEY5L<&K z%O5s^jpYmo11M7>z+a&r2mJ8X0kACWotn1m*k@eW%=H^LA3Ghsc-5Gh3r9|!)4A_p zXKzreSpx>Y3O%N5pbprOENjtUk_QOqDM>vl!L3GMHa!(3DabGb4wRs$XKG{Lw0WzZ zLq_!-IiY9hsNTcJ3>r7FZTDV2%>#^$QJw1nAVEZMGU!Sm7^O9f46^}WHPqz+wFJ@R zAFBaEgb+vUcU5^~YilBu_USV?JYwFgg)3$)T^T-i{+KBd9eeh+w0CGIr+~R7F|vU@ z#0>*c@DhOp>HvnM$|s&4;g`X6tQH8f4%?!sYh-EX(X8drNt1aurz~7Hed+2k)8};` zG(t_^h=AHGpSUf+6^|YjHdCb%|49udj-NaVXgYyakqQfLIl=RYw4L;+Iji5=+I@-;$;&SFAZC~eDtgZT?P#^b9BWZLs_Mlqu`ySVxXwOP7q&7vlhX2SY#n1Pk)^o6tMFP)bVf9Ps&SCp0Yv8bplx1hT8gRO;?sxTK)a zX`l#nemlZ;1ei@);)%bPPxXh7oo(&Co!#xNU(=IPR1}n0i1`5%D-|I>+fRl+isvN% zgNI@tt84lP2B*eHx;xtv;-gT&p`xb-(tv+^tH^-Wjh097%=NpXdGAWgsy^WWW~**! ze)3#F@WN#_4o=+g1E_+5_8~tgEP7v2RSlS}rlGOE^-Ej(cL27GtQ<9sS0_%KAOICf zt%{F}_y3mznCn%Z76V$j`4AqRhCy(R}T*k&(FXiH#;;oSykWU6&xmT_6)uU-wEsl`v)%{ ze_>Ja(9js^ggEEI!ph*_Xi!L)@ZEcd=}@D?!f*&z{sa$iKwxlR|KKR<GCn;8@YdPa z3*{&FHHxaLT)e!Lw6q{Ah`KpDyW-22B_FG%7nk9+!D)fn`iDk7*3}zYS#$B9gxr_F z(xBM4Fk4nm9st|y!g9~RFfJ@EEz0O2VUgH(5KY!G5n``NPImpq^@5Vp$@ztmsp;Xd z30Qc#diuV1^)xoMpk_g!x~(EOZYbWsw*hYmGNC0OO9Te^;W=_~u>UJy!~6e^*)R>D zb_R^GpA6+?GKkDLZ-_oNck_NzRWmR#J3PHGwY0wY>3(RfAdz`#6tO{ z?)fV>=@^lW4px01kxGGz8`eY!<;e)~4A2E>ZbUJShK_+t@QkdcUgF#G+P1EVh2^Eq z-{XtxeG_v_zy7_YXDBY~jiYa{zLovs=Zd@W$74P{gyfKY;Be?@v65rP##lgr0@V2X zw_Ln?4pGtLqh1w#Z0zcjQ&~$o)$r`{#L~v}>d$X|qwyK}W)ALFF5XXMl>kCe3Zjx$uFqzTGt~ornIT8d2p<*XRxfP?d|8L z_sw5@q7q)2T5DO@z0lI4RbE?0Te;*AmsdY>#@XRT5PRi4;_YzmpGO~B)zkG#)1~7o=he(JX$o7E0 z+rn)75zT>R1v)DT{y{bD!9Ib4`uIs9(Wi0%z!{Yd*)?BM${S+eeTpgi)~a6jE)DqtAUY(T0=i>2AW4_=HN`}Z8-=NDH{ zwDa^y%quKuYWqIDkX2Dz*)fpyvBA_wQ+x@zw( zoErld6+#Ru@Rno;cB0}zPC?DYdg9W}2g*7|!O6+ddHF^4P4Al9^6Od>ORHa)*-2{X z+606P%P3GVvtsLqwH1kKz$XB}2hsiroCr(}gohMx8oVe4U?$aJ`v3KhU3}*+YnWIC zCTA4ZHGb~zuj?PG_}2BQYbc|<)-^KewVkWfYkg{70U%+ZAN={?Zy`KGA}AsYXu!9C z9Yw1MN)VU_0g{oYvLD!j^Y}Rt(U&IXLDBIE`S0?p>)zJ4WPYgfNk~%AH?j{1mV2$u zaY_iaPjGS=;RI;klCj~>1+2iOz=*;_iHpfVBsOE~a%dMdIpfI_VhW084o<$IQBf&5 zxy6+wpBnw66I}ztu`RN6a=Ug%bSD{#1$#(O4GCc2PsgJG2NlOvjLD6AynguRw?32+`*X)GRF6{-Ih6DJeb`#uV`o z5x9lOZz0A5*>13r#Q%jZ3;P&)MxjgBrC+?nv*X|w>J$>~8J%R|6a3Q3(cCxK!Y@cn zRgH{|Wd}VKz#fW&_(9AkI422f;gS*uIRchZ6{W-^0A>3@n#0Eg&)k2mXz1eUotS14 z92Q#o-YdV*IzHJtCc!f)P1nW_b?q(CNbtY_W_Tq{Qv^sO3co;ch`=RdKtZ1tn*`KN zX<1M300C;*IC{h+S_Fr`bobKq^m$@ruH)tJo0=u1{)*-J32dr})Z8u1hHHrHi38Ub zAB;3XVM|C2LWq11W&pGgpl4>ga!W+V%sMnFE%8mUM@GJLa)y0;ic3m{UskSbbnLOy zXu!gSq%8;wfg#C=QHn*E=yL?jhIBdb~PEJ~;!_*K?P*Kn^GjMWq@gVpA z>^U$J@5yn=$9{M?kZ6n}IBk(0f3bUN}|$p8HjS3SsCF|02E|oXA-(_`r?H%kM0SZXlVwzItMyAx|x|L!RVx}CM)$s z{LzEUXe9&ZH8rIGKi`cjmtV*|cXM=z2@mu2aQAX`K@uijmF1p8R7?-?G8;3nB^Cn) zCi)Xx$IhKS9qjMt?e6C9<%YmdBYo|&X9a=Th+B>c2qq ztnnI|kbF=4vB0^D;FBRIfR+ujGcl$V!>Kph4{Zf@>Vr%qkId|5|F2O|6}l=dGq8h#KbBxQZz zJhwqbnS6uz5~l2-PyYGiT-y2RzR zAHYH_ZS7gP`H(!}PsT%p4G5$aV3FN@yuEyUn_IptEUn_3`-aDYqhhU`-OpS+PeTV9 z9!oj}a5DA?8QHmCJGw?EU_IVk-~7F}vJQ$YEGp)KxCApBI}JqcxI0u7s9Za_y4N)} zcXs!}#EWUw3_Z~a|Z-DOsV+w}z7#H_zUA_9I*16?1982q);MsuLlG8F} z6%@h30ncNu#ehG0lmqfhoUo^Va2EB(HNw$6GCqkQnrHF~tQ<$dEdwin;sFExP*S3( zq`0%EdkC4R(^Df;li&OMBIDzpD=PBv^V87N(=sr?r~*}_zPb6kipl{X%lQTPsd3tY zv2kEFV;fsuAwdXY@D~A#0yrcw585A^k&D&&>Sn^4j|E-y47YF|)KXJ~I#T z>hh1xp25-Rgk(!spT~--TmnMqu8O{N#PURi0w^?N07Y2HD2Tvz3IzJ0?n1}J&3{Wu z-ZL(xV|Hm_eRFYTV|HLkF>J7uC>GU2jWzW%-|vkfgH#s^1YC9K{AJh03}@l4uR7^BQV;-OuT%e@=D=3 z1vOm*RUN%=>%ZjJH0IYdWR%wcaF(@p;1|UJqrf8%~ z)LRc6+KWvabYCdIVn?%+f?DX_L!0oJH?1A{EnW7pIkJ|X@~)v$_5n{F0$&Fud1Sv2 z%zc0LiISv>2B&}^DBDB((02g*0JsFCn4>mIhEI+LPR#VQ2&uqaOmUcz=fYJrQ=7EX z>iVAX(7X?_#!mOtP42%mzbLJFPuW)}fioj={vTPbU76 zkF-osJl%JI9CA1YU=?Cq;S-|~F!oNUZ;}BDqS}Zl>>s=KQga-;DE?UA%`30EwsUl{ zb7ZREjf@6Y0W%&0^XZ#+ zmG#Zy^WIf7w|^O&z{PAEp6ZyGZy%peE32{&3fHiAeynS-cR6AErXC0qqgaM~bTW153Yj)(wt-8K3Q# zS@=3TSK8Gd`M%OG`%P3qv9*`~#T$32Xh8=OC&Z`Qnns9#aezS5C&v(lWQ`WBdBM8V z(uqEOZsQ%8@xH3AcerVIs{H$4ep^>&^S79)I^Tj4*OctY{C8#!9{dnpP}7ob7N~aY zlyPBka;)RvIk2nRUURn>-0e3c%to5ANh|Mmc@$#wqddI&X6EVnZ)}`hM8zc@J(0r7 zCH_PTr9jB}fZ3>M2uzFLgbkD6x%0qmZUI5c+Pb>NMmA24QouHXg4A?$+n9~0d{9y` zu(I8{D-s?RBmYAAxzY=@SDJ8)qP7TWDToxHAe1!Nxj4^Ux^VIO^(!}SdboS$=e{Y( z&&x8Pn(JAan-2+J|L71 zY;MjY7X$@-oE`jJom^}z94t+BU%$M3=^Q2EtT8DQvI_i%m6;BhO+oGDYXf6rD_bK= z8^AUX{~#p|&9hgoa~|iWJxq^{1ppgX!4rHZK|cc4Dr>w{P*GJ@dsXHw<+f=zHYQ2r!gv+Y5GH-G(c z(r?-RzuP0{ub2(XJ?X$eA^`v_JqR8{;xRmRjI1oTMee!#_{OHBF2G0e#~(lb_!F4q zb3=1#Mi!tKG*B2$giHchh?^VKqN$a2eRJyyf=zz?F*-vOMlBp&&tAF+=OL80fc+pL zadE<KUaSI0^JlD8z=Vo35F=X4H^j)GLD_#(bhA{$twiF+x-3e z*PjTk`GvZ)n}?6^z57t7;CryjVWBv3?Dz{cjk3z>0pgs$@i`H@3~nktD+lKU&xX4L z9V{MLCT7NKH*bSH{Mzw-afQghK^P7kzW55T92Yka^d+E|fe-L{@#9FC@K0#Kk_5kvWct5;{7-HU=gpxQ~sjY_bdAwSDgypGFwYpUA@j602!whOUwK z^l5AjAQ~n{2swq&x${o$9^bzAw6=c-yj=hFd+q1%&fbBb@JReGkid9239BvT!E=`` zcmxDCcXYlfEgPPKKyY<#c?BMDL@%DZbQx6KHfF;Nu+>N6KdPmeMqqnHrVt+RzaD?Z zY=8%t05D-wq4y+0p4qvsKT~mxPWjl?KfeA0NN8ydX*Pc%C1-wl4QBEU1jt=e_-0*)<{a^U!QTZTq9wmS>-82t833 ze4=quTvb3)P0GZ@Dk4qU#`BT7p5%*{v@A!V2?oi4k{Z#e2ul?ve`rgIs1x)aMI8wr zn&!-%d)7f=#Vy~O2F5B{I#LVD5^{>(*R?iw4s;C9^iD0e_Dv+_z1K8zRM$1($Qu)Xd%NWmd=@u`++aQ54_soC+3<>}?c;hCASg@y5@ z<-xhd*`NPDxVRpbQ*7!H{9N1Q!X455AlLR1%q>J>`^onJQbR2c86$RP$Tdbi>j20* zmLrc|YKN6nd>)zXo>?B4S{R(18JV7+m|yLmnD3uj>6%!nY#$EHD%JG}J9|fzf{qC@ zC2;9sN+dwSJwk?3EBJ0|LV-_!E-Z(84$<;lyRBql8(CP~JT%@nJ>S^Y)%dmhV|{CJ zRb6p)LuqYOMf2C-GtvI&fbaE_JOvpkuTk&4IKlY+xv@Z zTh-0&aol(yhG_?NH-h-afFeF8k;a1!0VGrWZTrmM10`M`u>X*ER>&f40mly#4w;qOim#G2@YM#bl< z?xD~9V;?*F>pBKYn>yY!e#@+HORf8o{JABx;C*CXnUtFT5$==NS0YLq$PK~fSU@q~ zVtL(*evVu6B+{C@z2I)Y`5!SG3B2JRaq{vRSy^Qk6xh4DKbCn0*r1@SA|dq@S-aQ* z;i1BGi$4L&IyjBf=PzjJ>N)!OyfQK|wYIWzah6e#=RI`_gaZa5Rxa#AA=<&l3|1mk zdP5_kz)0YPD7Gr8szEOVODP(3QXztyii+*{F`dwxtradQ0Iq`0D_SQit09ffC7 zXajcb{N?kfE}rGTf9I-#l$hCT^{~9@e@gQuEqW{Ef$nHRp+CLzz0l~<@b^M-~n4PPue?;UcN{OJPRyX=b#@|;~ zN5;kjvq9nr4J{-b;Mv%Zb6vfCN6WydsJx44JRwEb)LQ8LIbb%JyntG8 zaUkJv_wk2|xwW%- zuB?HPtFEngbauZbEP``_qlP960!8p+vWhQ?%PU&|gjUg&`RB^U=D_e6u;rb5qPR8S zuZaKP*I=N>fKN(IuWxD@o1EG@=PH6|a`FovN=S0^@*Sq92TCVwb+k0c`S@fM6#^o{ z>f2gpSC)wY!;SUu*qHlbV$ib@BpdutY;3SO7+Kq<t=tEs({ z;6;?q*+3Q`5C)L!q|j+23(Lw+b)TEREUf)Ngd&cvf#J}oSfL9S@eQaa0^fp}1V3r+ z;86I!JS{JObY^C0;|Gv4Ff-ug+zD(z$#GmjR9eF^sH}Z(Yz;OFq~j2QjjQWF z*M9uMnK7ak);1^Sm&@v!UpaahxOh>svSXZpRXYqfB8mWHdkDsr(2_ud1mzf^AZI>( zS=!hxrlh)Ue0Cl_l63^2{#;yGU0&T>UjMbY_H%yq$ISBj*Pembwk}GB7MJfmLPJ(! zuZ`*(srNcK4M?!Ch#%O`h+_1CLx+!@IQLju+dJ^x*S=33BY8EgSsxoSD;v^3)TO+y zO)9I2Fa8)+SRR&FY7-RmK;h+02^mUyMm&Ir_V1=Tup3ergx}&(JU|UK=|21-%Kc=A zXz2y+J(9L@3Ml?)8lH4p&G3wz?kydMhqggCOucTJd*8M46|?hK@ru$5N|H9Px+X4j zgzF@zcepmNppa33vLj50s15^TQIbLX4R(x*P3XcSZ6oKjH(3o`T6X@YAFJ|-E1#59 zUIqyHEY&IQ0>D=K%4jj&{9EG%*c1z zBrGQLTX)OMV(-in*xJe2#qp`R@yWTV*_F|$rM`)!FN1S$8@jE7l9UWB*#Iv=sU84I zA(TES4PysP$oRoH!lZx_8oF<>9=jo^Tknv7_)N#ZXjAvVbGNQhF%WxI03yOUiv#jd z3^1T9*gXys8kn8rlyYwjED_&)rlt?zsHXjk7@d(X)Cp~<#^ zNh{9~OV7}!%Id7gj-VV&Owm~P|Fb?wLT)TjCF0pf@syM6hSYO&ztBdAgVujdtp1!? z*_>P6n3+dlDI%~Iun+n^I-OknLC@V!)7_8p2n$w5RH50Sesy_fWo2%CWo2`I{pTpoIk#N?z0WH(Pt(Qsg77^O ziG)|kvvFGB6B5;iN8lI>*unka$j;mmF>v!qEU)RDU+rC38(Z02UjDg0x4t;Nyt?tn z%;q0MD;pob_hnSodnM)Elu;(lcqFv;Pp>F300m87^u5 zR^R;nV}1L(+An#ZTC-}uq}6^2eOu+3{?^bh`uyGd0J<=<0Jh=B(TN7LE~Z?_)G;A! zuesX`?)Dqvd;YUBLYlg_UxC@U_yufST(b&`Y+YP|*_71O6;)J$A^@(SpduzKeBv!k z2v_&1Gv^dFUfQ_3>snY@J383Ay2!pz;t>!4)j$+RVG^dM2G0gI1DNgJ!$%?Ek-%&? zAxJj7g2!OvI0|dQwG{vfnFZzv60zvkx4;*A-K)5l_rP@7^D;sAAwO(hi#2RE^GHUnC8lzv8ridXEtWZXbvjGZX0RYHhVLy82!qt~rdg)pDO<&p@TEMsUy?I+|YH54<`b~s$L1GQl2V9Fx z>_?>K72cLt!X5%B*gZJXH#pM#_?6QdD9>P0V!lm4E(3hxO@AQeyFIa zYiMZw^0l+8^;<`5V)7l)`&=gw8cYYP6M#BKJ{>E|)jPK>9PCo_ax3dUH+^kGZ8RV( z6ge1h=+HAW1G7QQc8rTl&)g~@E4SivV{>~~N6$e2$VC6xR7uq*LulU%vE>j)86K8W_wkdWXjl;FA=zLc(dNiV{0MC@i-4d2FS@)&CW+;r)NZYy=p9 zv+MvJgct`79u~MLZRQ+RQqwp%IR?bGxe3q_G6vp5x6L&q3fN{G_o|cy0o_W6J{1vjTcvm z69O%x+zt|Nd402`yWiM1)IBnh;m9$>VqgV?l@980tb;^34{HmIihx@v#T}yN6PCEA zX%bsf-8}^(G2($X0g;zi;QrXa*=A9fU)xyy`FnJF&e$tZ$I-nR0)VdN}n>*t>T@tUIMEtwYr7p`ICQIYQ>(zZbW zV4^0}#1s_3Z2NaJQ$dJ(nCqIbgsH85bedUICjXshf=^UW0=7L?=Y6cfC9WnQqjf@D zS>UOftgV--v;Q^e7eY5h_d#Zc2MXLBWK-mOfZ3Sv+*08q9-u+xk(z;l{lrTP2e0Iu zjEef~^3Ul-6-U?ft`Via$Nf#)(^w(;}k^ z#XEv$gPegHCPC<=prE6KRrZmZj(vP~R%1us(%K|MuJcRiHnR-D=R7*dtPfAjjLs~L zE&WV?SLGa#s4J*xn2uk%<(gZR(=z~~ zW_V_Ca%OR2Zh3lPX>fRKZhm=UdSPIEu4{ausei^jI@2{KRq*;<3Tk?YErEOx-L#*a z5W&J$2O2W{fFAZca{0Y zRb{oUR_=jHS_YEx@`nz?JqZSklJ+3nmxK=mV-@*ylvDuiM4%80$FaLovd&S7F{Krb zVX-O(=29w}&t7UPX&b8OnkZ@-C~3hvU}fbQ9GH|Nqh&0u_JVOKH^^KH!rE})$#a$pmv0Vnf+6odOcs$}};ju-;CHZa&3eK~a6pXA~qEiOf{uo{U zF}|=uTvEu47nc!9KQ%tJw6wnTQfxe|5;KOG@tgruCUtGtrx`an{V|;nz`~0d$TApournr(S zJ1a9LC?G53r;%teyn=SaaOLJ;!Yc&>rfb3haP3u#|$9z|QR;j5o<8 zRe5#as(Qz32gWPfyFYws|J3lU?n}>mV73qSX=SwuWuId{G-?ONS|;X+Dk#%1(*1o8 z8s6;1Iz^y9G9p|H%PR>}k(S+UsJ8uvw6i9yxuo*eHf96=!hiOhXJAlv(OV09hx-ze zKn|#lf)InA4SXoX4XBNhmUZ}IdH7GkuwdcrqGxFh%x3HCB(I_j%m%6#e<$W)tY45t z6FeIWo5=kK!J*-@@(S`wFQjFk%gQT?Nj?T2g8U?a7RYGnSXeo@Pn_WA~Ior_WFx1z^)L zHp43OH$1jM=*G}YpP#i*?4md$v>Zzo(3@W5gWMpOKUnHkx01*p|+ymmm z$lQY5JCR6^-7e`y{GYGDU`SX+rVS7p2scznF%{qq4-XIC;C5q#;Cpb8eir}48;lT~ zob;7{f!Rpo=dZ6AOT<6->;RaAz!I3@I3Mp#QBie$eSI4nudoRJ$e5^<^pxB;3F%qR zo?hJi0svQ_u($9P4HG*o^4!udR4rXS9Q}e^0z<=+()}Y7BxRLO@bRLx8T2mLoC4;7 zk;A16Pe_i>%#KV>%_w}Eg~D;kd(`o72;Ze=f&ZQ8g9h#$p1`I4TQsYg(NUqo19dfMCfW$wN{S8m*3=j3E$MM4H0T1Dr@P6C8WIlQ1!m* z^P9J2CFND0n%Yuw3p5N&gsxoU;^QU=TZkuU4@1GOpr#R%oc8X+$D;QYu(Xs^Ru`0( zJ9&D8fjk76H4`lS3`m1L!Oth7tZZas;~N&9`>wdUv8nOvH@I3-vvcl=i8He>k?Nr& zdJUKjw+|?S;9|k1U>N*M%!X#+hbR%Gu%Cet(!gtdMas-2vbefwU}AK33210#6SLqi z$k^}(2j0xDu7T*wscv$PN>S7?LDm}fny9id5-Tf=8&GkfID}<50F}bm@y12BlF}=71O9jq@vw>$rr5oBm9H3;~;xc?<(vI?+A~x>(p=3V5NDGq( zC5l-PPXn`|{WnZ-6o(mv9zMJNLMN`cYH$iJ5+bh~@Nf0UCVH|=FDxQ}2u@qn@gc_Z zNzO6z4HK4<+Y5U45G5-e;vb-Y+y%86SR3#cI3XKK#0P1PAm2?v?S->X+`CT&B@G2t zU-EHOf61$9%c*Kjd0(GY`Z=krE}`_ZMPS@H2?aw}UzBm7MnxHj7GW0zAx6|P(G>|U zJ*Gp4=nhcsA)`F=L{`k&NzTddo|*~2s63B^ny9hIBm2<1wn5j-eJ&fj-86BPwDY&m zDCHBAyRWQ$N%#R|7^pTLB;Q4jqzHm=BerY%DE3ev*aJ%N5G{k?!zWK2y;MUICCxp# zZ^|6G^ORRogD1L0|u zAbe@zL8ZlF4kn9{{kWjMy^nuteoAq5URiB!$)~h;)oE`l-jr4KK>l?GHn^Wt*i$1jkr5D zAW_Yvq@(BHzx~iQ^G$Z&z_i4`rgs-oZ{G$ zn#&KLQqp6aOel8_QlMZB(KsdCEeLkN>`s2*;4U(1t_!#2jO{}5-&c1HxA%{?w{^94 z^;b2(I``#s!?%yMEqO&BvfqCE)YfP37o}tE^vc*232V?R!q;*b6fQy8VW~tu9b~Ax z5zq%aHv=ojJ!u6E8<)WBA~jPxH9d26_z<=Ao~mfPG%!JZS?QI5oQAHUgGXR;?$sx9 z#!hx@yj=SUUgLSiD#DULhE2|)_v0#_`IRjl zFFHYn6ufuMe52qGqhLWELQqI3n#DhtSCEzgVndoQ}YGxc~ZyoPwo8aP*KJEd zooH(nV`>~>W*la25@BJAuOv9w#@JZmh_<%C7eh>qGCf`6?QKHMje|@L!vO!B>>`|O zJWce2?JRw)&HbJ1{hS?jG*nqw81TFxbb?5z!wkpBe3XYzTHyr_Kn`6Ka}6DR@NAEy zWZ)Y`Z4?&=-bAd+P$k_LL!^`Z<7ct}%pwoP?utH2Nzb%*au%0-jLIgiJke5i|8AWA zU+`=gu8^*Yh=_1-a3I7L`L2++v9q(^y?d9yY+Ge?;tpAh^EYmYJ%6rhXrOOvXJqGKi#D!d5x!v&IwmH7ULcN$1P{n~sHm8ZaB}er zN-L`x+B=!KdRlq<`bH&qhsKCWD}aVVmJ$jldr&<xvGYLWOQImoUNCSe{^hQ zYI;&mzLAyn`D@px=#agH%m89f1T2A6gDW?LEp45Q%&Z+p^DmidpA$tpwPtBjMVgOS9dRz5t&&Klm!I`F$o|o5=5Vr>~kO= zXAe(HJNwY6=(q37z5D}Enq)6U1%yZWhJ=U5CBn>tQadxpQ5r@j9KdWqr0iVBu8WG^eDJ_C7!zB0X;n3> zsil=46VoyT&tG6>VFqTyvyZs~J4e!lKw{nqYtuje2H5s5c(%QSzj+Vc!M)6&nWz~K z3tSa9bO=|zWnp&*vu?2 z8-#ywfh;bqbo327geBVhMV!BKi=CMbL2d9N5(!{im~Aik7MQc(q(kN>;^Rc6?x-1I znjM>7T3gzJe?NaAFA*OP;y@gDgO80@&xA~4&!7jgN{H=6+BJAKUV*)d4Z>z zH?$pY8hbu;iV(36xn=1iV&(nJCDf<*lYo?pw4N2AMMuT$5IMpZ52EyqOkHU02zGHV zs!lX}_8*|4J0&J1f!efdkf6N&bs2r`hYCWnulS`kj!UTUJ=5ZPqH#<@>4J)$l6%lI z8+SfY86`s-3K}|sYCzGJ25M^}PJwLao?UzY0eC>di^(p@D6GsZ zu8A+Hi3et@u5IbXl>_R2{0fxe za4^wQAzcI~6;af3NP6?Ob9i`Z?T=LyLzib)e~!;Djm*x>Z>-L5{1}*>?_XG{{MMUL zQez*Uazp$X=ymb~d$3_5Y!V0e?b(6;>3K){)W4_4SG6h2F{0!P%Li#g)%}!vPt2i65G-ia!S?1vsHX&5mLZt}3>@fP^Si zAdLiT?5_PZ=k7jHxAh8tQ(5tKptW4=Pc7s@iYXKcrL?>|%4uy*rG%$8Kql2z7L z)i!#et1tKJH8^=i4J|cYV?sk z&Qs0IT2)_rFZLB^$^e-to^(_~Av3^VPELl%Yxrb#QPA?=5Y=(@56XHwvifU!c?}2+ zcV~QkX?zLTdK$dg+UDBW;!^AARA$|mr{?x*hPupLM}e(T8znSW`}ZN-g9O^K|H1AE zL3jr_c`d>dlB%1&%`D8UZ6L1mkCl~f^l;x?UD#Y(T3T41oBR3W_sHBzK~sliOop76 z{?#j&;IGHxg`G9lJ{+VsxFEbIj$z?Ae(timjZ0!>eMR>OM0Xp@8|WsE2&SR6<-vvN zRj_zJe;~jU!>qP*Aib(Nv8v_5Ki75`Nj#p=9GuWi5i*O=|p`3rtw;qZ+bT38}c4X_QE4Tsb-*|QhV zGceObDoP?A5jM)garCKzB6zkJ+B!&Pv#_&OdG+$t*|R`vqyt0~U>g=&=z`8&xab!U z2(*U41O=rRh`PFbY6jTJl_Y@QEq-7r*Ban^q2XQ&flX%cH| z5ou-=VQLs>Ynkfim;r?5>GH4ci<$J(05*q8(6CAru~*_Z?1rMlRs*jc69SiW&~NVT_4w6jWav`w zXTh_fFp8=)3?R2eL@!^vmHVa;o=V9lQUF~Tme@_u(Lr1TCDA|k8zn(6ys|JeqQMhd zETMOjk&%(LwY9Oav6hyWtE(#@9M)?LX6$Xj+TojVP7;bEv2EMC>=sJl z*j+=1O6Xc>>2ZA|6_kw}Tx@*;9RkAqVv?NvLhe77<2cGmhwODck7(XbLyMBn{U_2e z(+0%ES-N=y#Ky;FW~by87+6|juYqsCs3W*Lm=B@mpkcgu_koRrtGcGHlbbh4HgjtS zk%yA3M~@?kn7 zVYR|XWjewk{NN#S3*iNTw>K;%_Cw7lzu*u)q0{Ix2M+)$JO~#BbOdI*c=Lv{uXk`< zjH|ydl5l|89Npcn-M)n+9FS}T6GTl-kJx;EL1i6-khrAS)J!`UPdA^yl$-+Zu&8Hh zulO%sI?j6n9~EREcsBg@yN|?Ny#0zRs_fjo>^;0a14Dd*!*q;I8Q72D{{pkovoOJb z&B4ueO;q%ejEt+le@0CR#>pje4n z^j}~$AR@{GyCG-3r3Way_u`0ubiCY*>E5|m_gAe}%YBYmCoIG@-P71w~QPv3`U zA!+_Gzwrwdk_8mT)>i)f^G~ASy7p^x{mK#C#woltWl zOAhg;gfE2R9~6gJuHAfSY!z7WvA%D9WZ~x+D4d@^p*Ea@Gj#(+-HqjSxLj8jf2`_y zcv%F6K33D%P2_?fMnV^)Vu-2*DTuzZlt?{;xQmt&Y5NmQ`J! zRaKi^-H=n=oLE{DS6mbRwj%spMbf86=fsQ~PnCj_vvxq)j(RJ2hW&fU_v}Of0v0iN z9ufS7y&mGxchb?_R#X;N)sZvz5LPnbx%>R2gu=B~CbulyFI#wAvG%#`5Gd*p@X*rB zr}(qb1KHO$?&9*QI4M@aJv;x`VX6ZRh!4dBMn;Zsjop9$H#%0P9n@6EuHSj2XQAL2 zcu&ibLs*Gj^cn9{H6H1g#~-V6%V=^+sPam`dY_WX@SU}(*EfH~u2)sJZE2(1y`ZPZOLt1`i>YIv`lFInPlA`MRx^Laxqf?`c zE2GP+?Guv)wV##rO{G;|ojh}XKdi^750Zlgf|hH~e)tE_$QrhegXE0Vj1Y<4QrEIb z%S>|mR3=0UETZxHj?t1_UMea=3f3+?u#9yLJgb@ z1xJL>!{LkFErD3zaNe_z`T#Wx2d~gWDXpl4l+NDfvAKoWjrsY_p83@Q=-U@oM<-`S zCuSz+Rz~L5K6j3UWtL`D*If~NOvQQxNgfcIQK20G**&sAPnI@m`hO25=o)X-JYH+g1gB%$$2 z%>%RTfLQv8{u-2r_WtAV*bQNuNyH04H$`#i zZwF~)buCPN!jem?>bm<|dwRb0c77R|to`2G(m(j6zrU%gt7B-SrEjF_Yp<@ox4x~D zj;RqgQ-4Po3-*iFC{RSaks}FkA8a`L57Tqs5K*@E2+S!NS^G7$IJdS8R%~f% zeG}~E*!=wX+&rRwkk8XSu~gC8Z{!*Z{S+?`H|8AN9k|tz zfBu3-7Mr-0iN%#q1EcYEE&dgs(L9%#i2>6fAq(6JC&3$9sPDk#9z@>V0eTj;+cI+Q z=>^$edWyS-KXmq1eQB?1Xw0kcc>k?Gr@8@gH@Tl0(rOwaKYUj54wLo_e`aobLFDe= z50L$1&rWcF2N10cY6q=o$dJ@e%*LbxQ}I6?q@|WLOOw8b^c8#?_GLnsFF1I*C1j*p zI@mmr6uTpO_kqMCF-ftb$2p-B204tG23#prY9JN3A+(m01H-0mps#1BZ)|S*O6%2) z+cyxMfu$33F$!CFMF0(qHz!XExp{etOG?T-efnHl=H4A)K{T~Ea+H;korMK)YAiJ9 zd%?!c%X9qJ#j{$nQa+}j*9^kU41ltdoo#`vaHP38q`5h6y*j+{^T_dXDe(8q^Krvb z5a5;N;etnigcbHjLBbG%7*vWc^^NOH2lX-Q|!@^Zlm zV{FWl9Ia#QEFx{qqU|l>ooym)Oq1Ol5?$?Z#5r1pTNx)fSf#q!r+Yf3c{(R~I7YkL zhT2;M*_(wpSooQu_G;r}VWl7`iH3JV88|?5*oJ0|Nqlyu4m0D)F4) z24dP8?}&52K@>Fq#{;c8%uP*eYtXE?{C#O@MR|E+ef{^2j;M$T7G|{jAq)tl13yl} zX8&}aZNP>%+n8+|q;0>!C?Xx;XCVIF`Hvlc-@S`VP(bk7mGi=PlytRm=vZ5tIy*TB z1bBpmnAzLkzW)G)3RKr%6eF@=(9(sL5e%!eqO!i7gNd7mnWvX?Xqb0I)Lrq%2+@U% z94i@+5Wp4k9M0dkY3J$b9T9F|XXg~)AD)tu_NEZQ&Ol8-EZF@JMO129v;%`Y>W1(= zgfqX=(RXn52#$z0G_|~P^A0r~1CSVzqKrImv<5m%$HjM2K~=52rx#vbO#@^9i0Fuf zWL;x3uxcPb=@IvV3LYL>-m*_JL&SB3Aea2`e996Clcw82~jVuk6k;tTKa z$cW@r3uiaCppcBBcPJ=JtElmwIfGW3$P_@x3=POqwj+1$Kk^HStoYPq=kDv_7a9;2 z>mM4eZD>lz$_~djJv$4-5f+A{%$UQkh&~XLR}4u=O3KZL$06%&arWC{8&`MOUXF8d z;Xy{k3+mxuH@C37xcc+w3aq%ZOD3Mdu2CtPW;Our=m8!t zG52FDOC$kPz>SEoSt19U90{Gb?n;^1g}kY19ax!|hqd$P52E+P`uaMgM<`@$K#+z~ z?Az*kb#uG8+#*~7%x1uB$mM{|bIU@AQv+WSXq9fsT@$0au5RW&{^E)+b`dZN7FQ~4lNb*l0_jUsG6Aem zfFrH~86~2{uL(2ror>kn$ilKmVYl8YZ1WX5BCXVxp?rzDjm zE!^&yxZbr3c<34~V(WL;%W(t7eL#R0tB~57hP!|TB zg?7~ccHqE?tGDi|YCkn|H3-QRe5TJWp~CxE^@N1Vu}3OAk6)fsFyMNiD5_}Y90sWid{JGZEu(l?bY`IU{C zWmP%vYYIMm`r0$xJv2EuIX^PD+}c0n8Y8a?S_;Qif z3dt%|f)u;RckVePqN-_`oDuV>p?!LBW%<{{;`-j56=uwtV~R< z3{1^KJK8fiO!U8=nZr5z7uM>BCS4M1vYWmjtz5jD_J08-C+NQS^wTbz~wcUe`;jtFp zeim+S2k8g{6rdl-Tewl-oTZ^Xw3i$?c=gE zSz<2@<5fv{Sp%!k?6=kMHh%AJ?dkf~HQdoN(%wDry>F;%a0Dqg-^Qj(Tf1~!{9l?` zE2^u25dzN!ogoRcLC;16eUKkuqd^`!n8!mLr?1Ew+dIc+exF;LK`J=Pma7OsT3uRM zUdGGM^~t5hVdN1FPNaUQHS>$oe*Nm$Q9|K^19Kk`5jZgdzd z5d5b6Q~v}ybI&d>t|1Ha*Y6P+MON2-tgeE?o1a@Ao?FfR{KY%FSl!b0<^vHf0X_^ZyVZ6n>w>U)JEmKi!3b9XzG-*^LpYKAgN~}c;h-UK43$@*7(4l zU3jdJ|FCoK4uJN5f!Tn~u;yZ^#Ve|!_)gM4@dh)-=}YGg%}xD7gAC1#A4;M&clVCS zoqP9$j~_pJ7}o+!0;*XUTj&i(OUo}PC@U{-YGtW!VyvyF1K6haQcd`tFeeu$;4Xqz z@C<=V#9xbuA6@|gV^h;7l8@zNo+-;KJQTSn$jf(vor47l@{BB~4>Gf{a&R8uJ;8a7 zk4s+kj^k@}kZi#w`r#JFAhn`x&Ep)bQ(WyqvY`f=?d_K5>khb;>*JQ~<$^akK5pr5 z4mbetqAX1!EsSGr%%iPLli^cvwfEE2#1Uew7oe||U}u@+V4YxRg#!iF6eqg`TTAeG zan|NBR%ZBF{8YTHCCIcy2kS(8>tsh;9C0=l$##~>c261LXSYdJZcJ0_n zV79+NuWbxQdc(%T{7OS3H#_@XQBgx(T~Aln_~_{H;9zKQ@DU<-=f8On{t2y-{`vnE zv!SH656!FovEy&Mck!GN61aTv(7NY9>w&mTs<2{{8?kAjEEn+=KE8yczW2 zkc#0U!;?lw&m=DMT;JB-%E#B%KfpOS#LCS>=+afRECfx9m;x9OcJ3$Jd4T+ckdUs0 zg@cceu9c;=yE`yjLUzvM=W<|~2>K2i33QNyq6O0x6)g~&wS%*U7Sgty!=mG~^o`D5 zx=KUO2=Wt{4YAb7R{?B;j8H~Fv9ax|p0UYmLlb2A21Uoc)YWG>%8Abj=Px#d*tmgf zV_{}RKuv01zO{#kzO9XK6dZvc`~rixj&Y$Y9g*t|5V)m1Ll~>rvu7T`!N6?xKHlCD zVR6}+dY0xwmoHK?GQdU-Z#95AALi~G@=DhbWm8_E(=5k1*tt15c#rX( z6}lxRA^u#!FDfQBJu@*YH>02^<4vKZqYE(GF|HH%y%+@;MHo(K2%eXfm64KSYhfw% zNDNK4r6nc)Z-5P7hyIo*5|ZskIRmhdl9BbSi1{3)5=3H{ z3{iXEN3jnvph(pKDgv55z{Y+-TK<)LU}#}=b;sD$G!}th>p%X4&23_K36Xy@8$Wwy z=K|Byykp}H>>MxO5y66oJp+2{014pJLRkrh61G7E2%rxF;3WkE!?80L?<;9)xdcU) zHb&%EB)qFheczZ`)|mLVF0P-Il9T7NvS3zCf$zQ`QT;!D{=k2E=+BP?J9qyQUirV-;vhjWH6y%!z zPQ}{8Eiy&+l|DNm5<|?_0bE0TJe2N0vA`{XKOBw>6v5FqmxWj0hP0xBwa06}ghv)W zC&ZL_#8mhsHTWc7o|1ZfURLL{q^fB^yuL@sOItVe^MZVH2fCqQYlWKvdI6>DT{{qd zg9024h*&hlK*@!X?G6Hn_02=l3IJ2n%08tOeaLuM`SwHIm+ylEV{;?ZOa0?>4V}IE z)()wKZ*M=60I!ZG1s)`1$U{(p#|sb;-BMx0MQ2a?1JwKWQeBaFrt0SFnP1!r+vy~T z(6#A#$ff3ImKI6e`D>>or<%YejSG_rvp40Ta7z{KhIAUB2z z?ST#u6azUm6OW)#XpAT9MgvpdCsszLR;O{_XXg8dM`1!An4W2$m};J!DeoUPj))CO zO+R(z8ggg$?AeD0m5rVb4X2h2lp>>Fw7>hGFa3eI_F5geysZhiayT>=Nb%Gct=BI8Efb4lh{}QOXc_rF^UHHHD@*h9EAz8!%Ofi*Tfp46ePRY{QJSeufxodp+C)_7cA1+}ph@60x<&Cw~m9@3$ z)zzNag}|JGz=F~j#wNU{1z3(9L5l)>T98GM$U@78kRKLCdda5}hp^IBu24}lY>PW~=#}0vLBU;UeoVHP$ov3uBSM*X@7VqK|M!@U1no$)3Erbjd*URItb&}C zjg`KEzJj8>tgOuc=I%Yfqd2nlZv)CXPtG%%ppj;jvrq<<5J_YZIp>^2&LDEm!31N# zU~B`%;Dn8F!a1!Iws&ouaMP-?yh?4J?Ffq zuC}_WV`X}(i~Og0%y=3tunkK&DIHM+?bEN{W!$CfUle4uI0K_J=U z`NtP8IJU6q$bxxC=Fi*48d!|p_KYPZZxw8+>nR%pX&Y?Lo*|~eh)SWY??3_7u z*PI#q7R=qhc>eB1i#9hcm^)@{RdIWGHb`3VD!-i<2p<5WB@x!FarlTqqcD$-8ajH+ z=m`_M)ORf|D9Xvo*6R%+*c!sZP|fX9-=${*`Kx*jA3l8Mj2VqU;_1@?V4Z7flarjh z(Gq48#;bpZUcRsmQg=YVe#ed+x$?*(Z@>BG7q@Ql%zyOZhnqKUOho!skQ#sI*(m&8 zm<>JM;6Tjt!I|v~^D4{Jii>&-8Psd|(0Qv?EZwjH^s;=z#!0hhlb8%wdBL-R|IucE za|p-&sHv>2A2Vat+|_FruHU$5{l-yKrsL$M*6MKyWZndf1%wj07j1L9M@*W$VD;)5 zixv@-y8GC%y+@DLHS{EaMc7Y0m<>4wk-s)UkzZUkeNNMasWTQVT>)l;aLdXslB=~~ zHr#+Q?qHAREIoIpZ@&jFUYb3B;pEx#)@|FldDmWi4h>cteFxA>E+s|FPvV7gf`d)nr;wDQ7@l-O> zb$c*dr_SA$u3mrQ%tI^JZC$rz_vW1kR;}MUbj$=CCLO712|AUAT;fhJTV`2Zm+FSz z%QkExWaH4ir%#-HfC!6O^A}|zFO!@?at=gbL|9a4m|CfvFlOwrLx)csIl6u0#^#kP zP?Nq5W+Q^0$&0*53K2~i0;)B+vkDsq3|i8>=G27;uD|m7t#97`;yVDo&h_8vcY?*kL2H@P!%5tBmaQ%2eXOqm#+nY745gKlk1xZ0C7k_;*dpFaBf`;Wi<{*xcR|Km?Tz4_%AkG}cFo`=pi-+grFv6GqYOTqoZ z7zDD4!YwKmKVNEvWr$|V#;c7ioFG)0!dh5bKW^IWop;}T`T9$5eDvuzfByW3|M~Fq z?{0qeJ5w6Zza8B zJ5qXtgut{YgmwgpO^C-7|6yhjk*GYyq;%I9I`kUYW73?Ft9J}vwXJc2xks!@%cLS=Uqr8lMUc}_tQtXEp?u|9g4t7Q zGRvz6%v{uS&dTAN4^>ZEQZ#r*X77m^y~Y;~oLVt##;7G5=WjhYef6fPOV>=8yC__y zM*bIvE^>8~-a0Eg16g%uM&wgOUQoPs@xzN(y0Z$%{Iy`yu8sGcJ#hZ9laE|Ge*W=? z9)JFsSKfW|=I3wSymjs6w~n8Cc;T8&>vrr+&dfq8P7v(4k_xjpTBpdUp;(KUDuOEE z`e+$uSW8-d=h0IZ-+k)T^T?lm@yD;RV4`^Z&8Odg_xWG{^5GBPz54m*=U;hk@57f@ z?A|wM#OOdz9y%H8zYw8Vi%Ar_V{ip=KQG}Z$J6&XRm+q z^-Tg=Z+-RASKr?J`nxx7eR=J}j~{sT&ApF5we;kfQPXA^9Z85klM(LkAdG^LTPhNZZv8P|UboGV%uUvcJ z>hn*%`w?&KvctzGuUJ)4S0}hsjCWy(kO==n{3N++$a5-W+-}~;{Z@&BCyPKbX`q@uEym9N+@y8#Zw{!QF`yWb4P6GBw zfDItTAj2pA7<>|QPi`|mB-xefivGiAZrFYN%JmoD`|Oi1fBNF?V z|LxqRy12BueQ9wf3GZDg=sno&sY&)U1_yiMh;H?}mo7q-J|4k zuRgVY?a6g(POM#ZYW4{Tb0e(R<8 zjpsM41Gybt&~$Lltiw%njxCyhY~lPP3!3hpKlf16+(Yx{9pX=mn)WYj+B1L7&bhPJ z&z!kr(vRVgwuVbc2TtukBPrHm-u4 zyd;|)b2BguKvh{@(XGA3Q3I&#>sN#n;4X&h8vTbD<6V6%n%he&-R*Kr%3 z4ZQ~ly8V0iUVY+;58itZ%=V{GKDqJ23riO-#_g&F*!vwZ8}zMzU?6^6rFAvAmE}DK zH+JsZd-RNHvlcI&yKEVe0*xa^lKeuc)iKyZN#Wj)JrPrzOs;ZghaNcUo3%-+_Zij2%C5>WrpEODMZDv*YASQK#?&7tZvsZODBPYqNU&#&MIUjF>Qq z@R0dSSM(k@7{`8r1DTyfaskwtViGM@a_{asaB%v91>$%0kan^Ua)dy)AHpjH*Q$9dEi9GlAH^HjGi|vYGUT#(w>0Pn+H}Yu3U!v!_lNe;dq(JO@rP81ghc+hD%H;3$QL zmX!|~J$PyJ)J?k%J#qcY+c(hzXKJ|g@;gY&HXpcW$B75G?mSphT*+`H7u;od0zrQ;1BiJ!7y!iIDcR$5P`o)hvd+fFM4xfK?=Gskr&t6!xd}V5CT1a3pHwh;z z_#Z5c0$`xtA0MrXiNXy##2*``XnmYkpIX|Xe%QEfW2UdZ`@yYepWJlcvi$ zgMxXxGHL0$1siv+*>#}L&=CRQk$!=};770-t%GF<4)8;OFx+DyQWBU+5^YxEL19T* z`F*C$?m2t$z{MMuAAfk*>fIfuF6}(8dElB|Gxnccc<^N3sdIOqIyY?Mbfd#10z6q8 z6Mh)tFY;kA-LP~)@h38r)UNz?*bVTfiR==+8|x>{8NKzuoCEjwTe!7sWK;3bS@n~b z4w$!g$GIyb7p#~|zM)mkh2oZ4STOIqy0~lKIol5`I(+K>S3kJ+-p8oczxvr% zZ+!9XTVH*TB=VIv-`#fK0|zfXHgD~E)*zmE3n&M2ib357K2RS-zxDiM$F9ACp5Ehcet7i{AHV+P4=?=j%j+M1e(BBk_g#K!(V-LDEo=xv*t+)ksS&g065Ade7LJEJZyi9DmxyN`>0_KEal(ak zC6PT6Q3|82L*F4|R%~iM@z9pjmzV53I)1_GQFE7$nZIJL;-M8o5!z&LSo4jVj z-B+H(p$H5hO!$zr_}#H47c47KlQ7aqOtFaQ1h z_y6_HpZ^qNgrn})C5msQ;jV-P+Jm?wDtA=y|~ z^85#f_!E^Z5oi)51C_PdBx5MFh_qkg*|3uWPyt#QY3}lp_MIxr>#92TsIRLoFY8*> zsiCg6vKTL=y!`AOlP5$Dg$}pd-M+ZEL#Iw%yLB5ncu+(4u6XW|V2TVlnHgyr>8Zrt z@*5Qi364Z-NkL)HE?s-qcO60)Lf7sMRW%Krs{7S-sVXWh&dAPAc4Z_bWhB`%NC=f= zAJV06&zwrE#H9ZHhV^LZ)48s^upmDti;Xpf*{H|I62Nb@*()kL z)Yf8+-NY-JztsB(IQ!4O!_K4x3%0Qmd7!^whKtL;BrYgI$C(XH z65Qg!Y|OL77Z5jOS6VvxoWV$VB4Uwe3C$9Wr5l+D$YBkCqDqLzC5G4bmo{-jKwKgzd9;$g3~5x58r=z$i(Tfo+Wlr7?RHZ!h{WY5m^94CU+)T#6FM#V2q6o2@#$|bqn9<$TEBhc;ggqNcx}S$MHaJ}X`1OtG?l#AaOTWW1Y=@+ zj2CWKxT0Zm#JUj#up>)=&X|;6y!q&1T^swa+&Xae_8v{E>!!>bvAp@xYi|viIzyLe4+!Sv3u2bR4<*RIEkFpL6c_=3 zFgHu5Rz#ARjHo&~8QEn=N|!NH8kel87(2WBoK+*5_e|MweA1Rf^%Lin3>dcS{)blV z-CI~y)uyeVe?Sm{&A|Z-HJAXL6`d+fcJp1>aZuzSj|a?hSR~RPau`#&X268WQ`f8; zxp>8Z*$d}x-;Yc5s)Hw*Ht(9abWPKS?WExBJ!%5n2lOpB8xRr`5XxUvCTCgC#%&K=UUK*8=KCK$apSEg{`k$+Prg0#!rMf4%vrbdfu~+t zux_V2r+r|6KNB=)4Xh&W8h|J=#2;>nL{RZz!udKhASyVJP7jQV$*k_W_3XntFFdjB z;?;X@{Nen2xAr~p;)&kobUU z!Z45!i7h3pT^kZiDAbzvHT7c`Enj~4_`xerAGrGb(dS-0{qox66!N8nw82 z>YAO+_dayssTX!$eroTdPw#x_%8G->C$Cz!c>A6s=O4);2ZTr6ONx{fmOB>zm{C0D zS7Cf-Z5kHrhr?8?Qk#@Edd}j_$Ii~*x_{4uk3Rb0Cs*FRdG5v=7hZYi;aC2!?(oTR z^OrsT(wn2E&&3S`lcji~c%#Tr2Yn4EEF2qYZDe#{+a$9dAahr{fJl{|7@XZ_E-u)1 z;J&9{y7BoBumAWzFMjpsr$7Gkhnv-h27!>(qJc&o@5%@%hhxdhy%;di>@W8%|xA zyMEV|Yp->zY7oJGauSG%YAHzliudwI>-hni2Ho4sXcTcws3N~=l^1HJS zp01s`sQLcKI*gmc)D?hZ8eYU6%tmL5Q6-#c&VYX#v*Bt8N0jbP$<4|r$j&Os&#Njg z>sZ{rwxYa8ZB56LlG1|0_PKc$5`V z62>FW#`O0~fQ|itE6B0v2$41&?g`N6}W|i)&N2{oQR14iixR;pU5pGdNd(QMe=0~XHaLbmx=a- zyt0hG!@EvjG<^By=^OSx`hn55O*}VJJLX4h>U{T3qd3^RByH46%?LQ(y=R&^>ddDX<9LI zY4gmDJLhlOQB>beft@`zrk!6~0gDA_pZ5t8Mrfu8M5RnyyX`0p|n?aXy zy4XP1_#OJUHEZO=}+|Z%|gUM5Z&l9p^`5mi<&JfPf z)7Nk9KV#nH)$3R6JG}M8>BXD3=XI>{k0EC+THoYKgR+j~mI=)wTn!- zG^vz$4+>@6$e4JoAu%g|@XV&=ryg2#{Opt+ho^79d&8-R@452AzLOU__Z+Oy*aCyV zC&B!1VGRda;dDhd-OxZ%_F%atIg5-$mTE$3qx{;o#TFYLFSBLk512G-{+=UCPCmHw z)I)3Uzq04i=gz+H&hbZ{oxOZ>W?n^LPz;p{`9`5xB_2xw*gRSYe1%+Px>m}>#uWpC z{9#VCc4zH?!65VT+x9dpST=C^n&~_DuDkd2-49WZvCdQtJZPL&OG_-O)sfjz31@kwOd9kT|0Q?#v!XVP1>}7#-{yuUwHb`Gq0^&zsqV% z3&kDT!&Y%3&lP3bDWM=n6$Sp5;Sq+|7=uF2V@f=RyS&4=Rn1$^Uz)w|NYmaE3lH75 z;Lw@*2Tm_ObY{z`OAkN&N=8O|IfPJ@Q1$?-Q782n^jZ)|c2)-Sugz*shzv3)P=kM(cIs)lues_&?YDC=H)_5H(7ys-V!)s2^)*z)N0IY-Zq*u1ar z@(ul#tOdsRm^3ri;`HYo4JI{#phH2bybC<5y#67qFv56uE; zS!rcKenDDlW|AY#W=%1hoO-?6Y<8QBsb*t(qS?D;(mbn$oymHwT`hO&RLOdEn#GV| zHKivS`Q)oZqewAmImTtwJ2WabeQdNLF2)!ii|lEVR-I`vyL4K%G^2ryLW)+yr&Fym zt8gHa8Pp1^QD@Ss_|zjnqE=Y+8p>=G*b)s|n@MlC7_DZK3*qCZG-}iiv&rSK@x$$j zW;P1+1F^=estj5+D?t<^NFSM$l9XSVmzAEHk&;}Tm06IL4Rw~CjuRgtv>KyU2PDP- zos*GS*1mXfzy8$~m9-r@cB`#}rR1{=4UL@KEO)93B_+3oN1~??W5RF1Z3Ox)t&yKK< z36jmTB`8%OF3^s2qy(jK48tnQ;4KgfC`)qh2dsKF>X8Z@EZ8sz6>?EUllceZ4T*Y0 zUMi_VE_zoxf66pK97eT~(Hw(j6(_QhQxX8yHYm6a{&*mOz>v1+=0MeXY_c>AmszI3 z7$|qL4n@ZT^ZtG!cn?H}u?I6Nb~#=|-bWEvCLHj%E^l=^|3GlvUEmcGMFa=aKXeGw z0MH5bd#JWJ#HoRcGBHwd78ix43&pM_LKDS`nbwLKjOZ^k41vD!34S4=cLfCclj9zV zxv+5Rm->xX@iR$TLQdSI)HHnj*dGuQ+SWg?tzQ7XNdl<~qj0nzLb?F~3>gB!A!|DASKct0e*~8zqENKL(HS-qy&+MQq0%{e-K3g;~x~-4x4F`Gg@zq(wgE8R&l);$*TYl4c^r6_G2AC5S86r=J2n=WkSn)6-_=kiF$tUt|$A-p*3dbHqfJ5WL z;(-F8fl4MIJpKVmn8VVBtB)JXlOqIn3lHe(3M%E|^J&q-a z2#*#FO)R5Ww=-yCDvuSa?}p!(-z?7r-YWkBu{AOgQ~1VK(p^ zK!|$>67+A^js#YOXDT5cMc@Mh9x{#1VaO@WtnFIdYhZcrA!Q8%b2`-9QgeyS=b>ZX zr@Oczp`reW{Be&6#3LQE$Y%;%=N_UH&XNM1mINWQ0o%q&TC>AdP?A^Qt!nV_Zeu1@ z4;fY2yD_)2#+;PGN>XGfkRl|bc@bHTkXezIizHU`Gj9t+6{9Ny7>6O-gK-n(HjG-^zEcc` zc=m-TB180YJiy}v!$Q?K*`#IWcC76&YT|^&D|?TdOs@Hg?hQF5Wyz_jJc!{z0r0>O z$RvHjF^qX!2#C>{=--OSsW74&@Hz#%0>5|_fCzY5q~_+A)^#2}uW8Q4ElYRpTd;Y@ zxTYmt`wt=iHBv=FGXuAW*l0wKa5JQ-JW;$-Y!c6gyc(-JE(w%HQ!W8VGI@eMGqqK9BZ+1hG7~k8Fz6A49M+CSw(g zc-}bDq#AY3f`YPM{YETUI(zf3l?P8O+k0%$_Jgz6Y#TCZc6v^GBr)+NfDGq3fnQ~K zk*uOHMQYrGFhG-G0sSWw>WG6B8bXm;bShk_9fu4Xw|4!q`|jWL+b<<|2l4z zbv0WH%*F`daM&Ofok@0wEfMsUosm|Qms47hUs>F~BtIX3k(-_Y^imS;rc_x?fD@}N z(VFZ?vYL$?Po_ek8dybwZ6FrnZS}ZM>%lh06uYA!Gpo9^yh~-rhU(hhwe>x#Yr9u> z>{ivGQ~N@wwyb1ldXgj6W=#UNS}B1I!w=Rj0LR z)JCO(PmRX|4XZVpgpB-Zh9_{kk#!CiyLY%22 z?7;BLe#ma$gMSyyhFR3V9ez5&Z36-vaI9IG&`P9#i^bxDLkN>Aq5U3s2CK$bkOTg` zxOU)18N~WRDC)Da{X4z{W%89VSB%BLHdrzbZoy0`AO~g4AY@!XlsZ0v0%!!ZB3W9o zPI7z*o}DaLL5qUV5E*?E6f$8jAhb$MU6J4`t`5in_F!^_rvkPyxQD@6;rl@t9~Xj@ z1JQ9h-2XYf`dOuOVkTvlq_ER3$h|Vr0b%7Y!(3O(B9E6D_+K2t<2;PO$bN z^c)`Y$glk(W+Q%sNLm=v(3p@A(k>D2789n9jWR?>>mo_0jp8UXC?g(*E`Sbkd(j$_ ze-Xe4V#Dt&EKp3-v56@SupbiQt!DPlJ^_A$Z-yg!{*Z21S$IGE7Zw z94R!FIEX0h+32kx5y6yKW}b*3ba7h-J z4J8d$EyT@)2QmZF!&r-10SK2TVcLLQby8=gsOv(s&MrRkHLN|QN8#@(X_xFV*& z5M0jL0IIAKBn%AIAlxJQr6QV;M)Udx(oss>@&V)?b#`cBHQ8k>HkHXHH(Fy#sh@t4Y=HRgl4fsiFgdcXn{pxv7y-IflnfJo<^&*CfRg$ zo6hM_CYn)lp?_p?q3T$Y)gqpY%|49w2p$Lyk#P*gE`~uK zBuz}1E}ox2W*nr4@yR5fNuTUU&(AA!r{$()<>@U}xeBxb#T$U>Q%=?!;SK7+7%XDA z6Wn)}Nbuh=WGq1bE0Bkgpb6rJ;9Bwb!`(urR=P8?ipn~acC0NZuX1G<>C6tCNO=J8 ze-t^zNG%5#4GvQB9^=R7L%8uikYtL1nY5cE9D_W;^W9HCTyVM9($U~%T9q$kS7J+8FGUKMTD>hl(DMjp2iamtWX-vDcSjH z#bxblyR@(Fl3!6xqf^qea5SXnWilG@cRVScc~A5K6|#W_BN@)=g;>U&#LbK;a*p>e?@idDzM+DR?+0!!vfsVq=|aBSm+ z6$7%yo|Iiv*Llp?K?|3RTCs8P;&qLSn!8SJDj6^`tEM|EIIwh_(2YdW20b1Tc0~O= z`OJR6Y1Y3HC^Y{oo~<=z1N?#6;E7nHgYK=+L=IcJhjYuz%50yXTb!2%;>u1<%SlUD z#e1kTqseATv|DXRhb7q(*)RttJJ12OQGjRy%xGD9>U2hf5vw1y=4EDOx!h%W1$E_> zP;DT$u2mg6NXD^z0H5*d}TEuPXLp{rmEq> zL~m0BkzgHXSYTGzLaaV>IZDCcW4o07X+xcHpJO zY%>~gtcAOSjx(8b$R}cSuqGmLqDeLzG99)Qn+;YCgeEa;ux+>tg52zu#3ZYYt_C4v zl14sDFmjn$?15@yC!o?7dbKD^lNUa6VpFs1P%@W+-2OwD4XqC;06}0jw<{$xgPsip zConxTFNy#2d}AdQmQaB`z&svMB;2|f`9+{-lmJk$(89I_xgpZAv1|sGFo=U#I0bAb zpbHzXJBvt+SP61bm4}9+THq5$cuo<5)k0@R;6PD18)flT02r<%I5(I#aWH@fziOnR zfRSV?B(or+d~_TKwDk}07;U2spF1wMrZhov}Q!|5B39g+#cV#|q}(DCGBY5Awk2g1?IVs;jTI20DMHS=b;GB#Qt7i)-%BPTO>f<6ML%42bM zVhoPvuX5pI#!wu>S|8Yh!3|n~CV7V0D0F32R7r+!Fb>jJm|SDR0av*9FgB`*O#l&* zHz6`Y1?CXegPEw|FK5L1cJRH-;j=0%k+A3?fgc_w!u}2NdxK@)4Pb^BkNo!>>@)w7Zlgz;Skt^$(mLHgBZtA zm_T6zNlOSG;wi&~!WeMTlR%vFAc6$iBC`WriU*b985J!m7oO*$bC_8ev14m-Arri5@X;KEp4p75e<*K42KdN-O3qrf86| z;C?_v+$K;Jn1|nvizJ9e1P(-z+e>5$030!~^Um|&iv*C|d*K8K{l$|2QxQN1lEGLq zHgWf$?)sz;qjRuM0vQ4QfTpMrrHuQ9yMf5n zg*&Z)CzwY;l`&DsXo$pRXc!7P1pIIz!)ZP$O5THo7L+*u0$ADil z!&*3oX_0Fle8qamGqs6fhMEPN&F!G;F|c^7uKZF`oAC+=U0AVp7f~ue8`dl=s<{H= zrx>jSp5%E$*&~u(LE>7Zf$S`@oyW%!93kwsY+`uf;q<(#(%i~dh8uzASsQqsJ-#tqa18y()p(o`A!o%V*8U8* zB6gYKHiRWRks?Ak2>ZS8;Uu7gYq36N9fr3wO9lE1Scsc0Ip~4y+;oxFjrUv_7_eJt zjS8hMGA02N1%n|u4Z~HXr75Wr9jH(>pQSfjy`otOx4K_{w zr_!qMTVsEU-JX}5lboF7blUBSCK9sf0j^q=9I zO9$O&GMb_93_7d9V5ht20&}7ZgK|zT-JYM3k(Zv4>2{ZwmZZAfgjit)Vq;l_fm{Fq zVQOR8iPYs!8(0X&4tpk35z*j8rv(r*$t9zsXeushevu;LTD&{} zKb$(SJO*PY5-%00_xzy3LirI1e8Q_SwSmpU}v{8IOtI6Z0D`Q^@f=W^e&fF>^DJ;T=U6P!G#I8U`l?5)@Jxywh|J zxFIGkFgzSPr}#Jx~}XQMB@n>3C|qb?(ucaugoF`#+IH-$^Ok)NxYJhoyr;hJ zEM2~I&rxfR;cdjTI+NVzkc%+Q%!qm(x zr#lIJChVvdgDDY$4hV$+eS%Jpvev@63r95$%}q;(Vv?!kW}KP1k4lwrv{q@s^7vTG zqvLIfwu+*%!t@+1k#Hi1g-8}DyfRoE35+Z!-vew8#_uGDy;DVb*ScE0AlRU!H1NPI zKXE&bP{eD=v5s&s(L!QQ1Lw!P5)-lVn1JRQJ!GC<3#%pwKYZWRI%I)WM%@1O=2S;Y zr_y_y}1t9Ontc-&a zYcQgFPuzEwoZugScI&I}zDJVq{SQBS=Go`ZU%cc_O=qeA+DTB2PbO%lX&wgVbioU- zEc1+eKZn^k?4SOLiT)q|c(4R!^G9_Pw=c3%V_O1N2zo*|$>XXT8y6t1CtT}6o35pC4;7D0qAOI|kb$5)+!&2}ASetPlS+08m zoR|c;(a=Xx{=5Sm3|@y75eqj#*?H(D+9JH2!}0o-M+d}&`G*BzEd~DY3bhLgZp*SV z9P406phtrge=pXrA!HT_3-gNzWs^8PU=kZG#QX*|*De^NX%yyX&=H_9obyAdIU+D7 zj&Pu$5I8-MWK3XG6qpd&9b+j36%H|4jWQSuEwU}FZUwFLcaJ{FN=waziv)xPi8Uo} zW>6rjSK=%1gD3io6I)*4%m||2JxDeTujK76mSczYYB$jmf-UylB$UEp-k6!*~0aJtkdRI_#G| zTQ|>lkJLinJ$F(k*J^#re`1ff18-Bg^o-GsQfKlh0X7~y&T7#uE$Z>s|0@gs3)qBp zv=wHfNz!$hcW4-2rQ6z~-&(Y-#b0UaowmwnJ>~nJQih~x@ssbc+SX_J?(uCHzwQn< z-?RQ@xka774A=ypc88daI$K<~^&a1!`P<7aZn5|6=H2H{G=@)}5DBOGPP+^dcZk`T zxLMIBCE5#e@{95dQ(bQOE`W^<7-UP#${;YIxU8hCTbFJXrR7jbD4)QHiSS6XAvF=6 z&7No{{2&?grpub-&>HO~gTrY<^#b=cf!Tx=)oC`G9X7155Oj&TS(zod1v##?tRz=X za%yI>+i9_xvjEDlR77QM;i zx2V#HWDg?33bi|A6JX;YN`V~^I`JwEcoJ}CHCotkn$zN;=GjaJbD}lTYO&b#=4694 z#gg2Kw@)nG}BxoW_m%)rIfFaRkvKw?JgVljzRr|bRXCnP#%}92* z?dDV`5gaBnD#P?IRxTQul3HC-(XYOHpU&ON@(L^4m!`Q==Af!TyVo1dQq)tLDCDnN{YSoq@Lup=DxF*qb(*@Kk|B`P!6KMcBy zw_bR-3A3fZY(jqnumRbHSCMekjY}YY67!`Fs~^rhWGLhZqvRhICk&dAQTXI@3VB_H zA9rk=KWGFka15g;f55H5vvV=RIz4y{HzD-9+65A(9vY3|9PcYECtN!+x(&|RGzziQ zAmX;#1^5H0@Nf~PN{Bd=G^8j4+V*#&Djxn};Y2R*i6a>d8zBdvFi4bk0l4-Ffh&(y zP&5T2CL|l&KFBUI2o1$RbRb!u zZy;zk3a=btHWm0bHV)`Wl$lbl42O0j)BxNagJiD2Y&hBlfcBu{JpoH}5>Cl{;YRR_ z+1P^(7giO5PgtFy>31=qf8!|H;&M_WeRuxG`lZu-EA%bX z1H4(@e&FiN=}<8MIX3U5Ilw!%Q zr2n@toAg$CKW~fHB=YSSF`IyM9(K-Kn^f@jEnmH5snFsE{l>2??yvOv^RiQ5N+s0- zPY7jT8wgE$hNb6LnsB|ytu?*o-NS5!gnm|LdQnk(S89e*Ym7#Z+n!=dPERn}h`iF< zlB>Ej3`bCY+N|=*s?3b+baz^^ElG)pl+cxtheRu)l_rJOiaj&Wokb9V*`W6LcO@Dj znV51(EksT=tuaoi4~tbr%5*>%m(!iQk5i;$dBrZA{=ST-?_ViqD39^Mb+nZyeU=EW~8!VhQ>2hGDQ zj9C?XtQx=u&n9hLNEt8J%eAsdxqm>E*6P;UT#3$9S8{5qEy+o^3Yj7FhIoEcY=TCv zHXAH5ojF`*v;uYUfKwVX?QoS=3kFuSc)^ZZGJ|V@h-QsG*=%zsCZ$@P>GqVIl#H%b z^_@y9P{#$QNj#e%kMKl-Od{q*F0bs^@n!On{OQxrzy0ou@4o-~habQD@z0-s_02nf zc&~BL5R9<@i_kpC4e%yy(qqG?^yIX7er}K1Kxp7JDIgL2CY2@378!yVSF{38Vy2*w zNJ0aNlate7GNtHzP@3?u7S8;_djq)-ER4cB85`*r8XJhC3$g&wettnX8q1>N0ZxIq z{lv!*IEjldK?Qyx;qBN$Bie+71w=;Q1y~V2AfiGMu;7VWm7)niL;#gwkt`&rEspFM zI7xLF7KH`}t}i%t5zOd`;wRse8^iYEOZ!E90w{LA0PVZNKUGk>}8e+IMhtny4sJwVJ}eqIh> zgLj`ja0Sxj+hWd@*fuXhYh7SvuhFTp3vzP{3z30xq~-J;Hg43+g}YB*Sbz6@Bj+q` z7&dO?w7E;0w-l9jEG#T5%qwvxx%En&PN~bvE*Uy;&e#R3C#~2tVA9;w{7RL^oSNcx zILJOq1c43u&Sti%)VhqEqJql0jtzsV`j5`8>4WTPdUipoE4?VEutWQb!puDA6s^uc zWE^Qy)GC$QoG7z8BaHUIXyU-+Y8CEUdI+#Yoe?+(3P6NGE)al%xze1R9w^fWL<>3X zz_2LPCKGUl<#iTskC=Rc0ue|zF~ur0F$!H+f+{3N9!54g5UN^d(h&|T2iD;#>PJ#w z%(5h|i;)Gz$^8aC4U4KEYZ7FMc4t{dO+(+|h1I?ES)~a{ zSt>`mIVlZuak_&j3Zh}{B5*>fG#bpdDgCa zec|;t{_yc9pMUrLw}1Z2XJ38&+M91bf8*t4D_6VRE(xJwD5L;>6ZDz~yfI(kz&1!Lh)G>N*Nrdj+ATsNb!LS9`K34vp8Xw#77Vpvv`#uPG=5P z=>p^`ArY1!htCo$od>W9&vFkA#L)|x+yu3bG&bQXUE7%WHjqwWFZ|;08OC1>MFLN{ z79Ks6wUrukWP;8wFuYw*L=ev4*faStM7(-X6Lc0#Am9qXhIKw7UhNktYZDsNHYAD- zkQp8XIur&}oUbAA)CgXv^$L|fB2Ezy&eIj`C%o-NXd{?S1fmL%CL~Qn0ESF16z$^W z?fh}Hi*6eP?G}Zt7Os#e1%l@A<44Ma1ii%3Tdc`R?yNQ;QFlRJBKk=JoIprUoY@3H z%u_E+M8dr-2Ih~oPrD#w<>LH;qgmi^b1X zpDlB)w;rj`dQXc3e80B1wD%Ie`+bl9x68g2`j)AX4&l1YKJ51*3TZ!oVyADbyuC-^ zHjVK;tabS|C-Nt$d99CWT~CWWtxx$+?D6*AZ7OFTWXO^jEygRpaxf?INk8)`wY)_Q z-kSfd!tF2{caUq*9yV?ss}H2eWw}?>j8~GEVb#Z~NDn zje36RiY>a@dkcP-g73|x%<~{UuG0R>@>1d%rS+PZXX9aRG41lF)=(AGyB$%*8Fo?_0KYPfgE(g(V%cv)gB+=AXrj!0-n0%P~)tnJ%^5yYxR~Sf)#MnGFtRz+`tIdEG+AkTUp;@%*@H_ z_YGUJxzEV)mGuoNY1uiM`5lWpl;xLTJ=CG^6c;a)HB3fhMrLEv;^evpLvC3{d5y)D zA+-F|O07(d(T#9mk;E3Jj7Z-Yc~$R0dENV^SJb8Cmzq-2$d@J}6VWCWWCPJKggZyV ziI6HyXG>NjCWmV*!7^RE)~wZ;v3TO5hOL5_88i!!%0#IK6QojaF=rMeS5!rDOh&E@ zStqSYuQNl5!L}K624I^SpE_)&X*pd6jUBgQ%Ya4e1}t3Nb?mhKsxDTCE6w3b0+gjV z`DGfd#%gsWrDY>hKX}o~e)EeKRy zI`rtuZjU%i34(iywcenn79LXsd9wlzgmuCaBRoB+O^YJH8ZEw8)!OhQZee%VZ z?|$_03$MKT?guxoK6AaQx(XjQ?lqraHi8HMZ<2-dw_rA)8i)qWM*1r3p}4ex#n?b@ zC{?rgBoN1wozd>Dte3fSHJOFF^t^b34O{_c1F#A71hMJCY}{g%(UjS#TUu=|dxv^^ zWu3jKJQQzV{I~=!%KeUwQpgaA4GE3LJut1LV@~HD=`~#n>$~e5DKTVh2d)rr;?deg zESEU9NL&E5I(vF{Y0pMyWsSYOlR2+_g4q@l84Gs@6-5f9fH)Ge2#PO8p*1)&+?93e zv|M9Wf!>uxI&3f-P!O3j0Gou_V8duI+2pe;J3C8jG}-M{nfd0NqIRGo!osMTNC6@r z;z9Mw1i3~>pm2V%F~1}(CDYNqlOZ`THbLal0<*!80oXvT*!l?~kZXw_PO`c3qP5oe zM5j4DN2WCi@l>LlBBT9@9Ep$BTP${`E6J6aURV*Kw*@NnQA$0zkC2v!YJ{8?WFvGA z@Dlt;kY}vYm0c2NaL4LXWJYJ4+C+pb=2Q{lfKWm(vi<}m{BD@d7nZab8(V+SV>S{1 zu}L?Swn>eoCBE17ZJ4+0djLN~+I)AmF1PSu^Zok&D}Ofc&$*MrouRcmwT*gfYklb! z{pr0Cze}O@8^kjS1_PBLYfBCSgHFSP%HttDu6(k!z-)jzFG6cwV7Nv!w$H$ReFhG6 zq@*UL<&2-bD6OLNq07&leD2LFZ-02-)$7xjH@ovov-3;yas*~ecW1*2#V4p529Gur zbQrsNfAb^HZhicvjprU8w`g^g3g!s=XrkGW2w!B;8P#%CX@{Dm{Iag&X05*O%H~VY z9y))yapLsk%zTFHHJZ=gp$#Q1Q)195po@+ zK+G~hZOh27>^r2#xanO-P3|#loZf;0FnSw$Vv3>SVie#u6s7PNPtYVL7j^G9a#{1J z1xqI^Se9Md(d=-G&`-IFp99sVQmE8MLyT4%YqI5c?LX(hsU1(hy5q?g$FA9uSJT~0 zvLz8s>vSY15d(`4oXwU*4aGeMPDOa|+~v(rJh$<}qZ8L`$SA8cIUMws-9ctilS-{h zaXF(DN>_1NpDDBE?>f|c@42N1j&&O`uDV~N!<9<7ffRS(nU^UFS2Be{QBzm<(HCC= z+ur=(L#Q^kH{N^yNH!6%4 zbm#E&!@w)TUHR{Cz--b0$iOHqZ28L2C(WBJ#>UoPTMwt+Jyi0uHG3<+%>e6rA#a7g z1>Xa1Q_r3M$+tq^G8d&=7@rxp*)MgGG+gs34eu1BvUD(?cYfV}<4CD_txs${*RTN5S>BGN(4s$E z+>zh-wZ&V*SDr~Q7|&;3Zg!eG1qBTD@aXan&n$kAi6 za|@HxvImWwoS5By-}%Qbz5Vg)-~M#p)o1#So@7hSPR+>6OwG=4XQjC_EmlXITvgq* zr!lW|c=L|!*IvK>=6CnK{>jie%Vb8Y&SEiJ92TR)qPO5?Z`5duN-K1(td7Gbt~>wK z>32VWe9Lo5_o`UE*nWJn}JIYjf81cb+x4;Z!W%Ck>=^wrtxuZ*3)EQX9Bh)P7oD1=%N zI@SpJ#OUN|3~J_#!ttv%9em>XyRW{m_2h%9#3YPiYOJnG1-jw%gNz(Xgjhz#DlEwr z14pg7@8VM*eR}Shm%0ubiPabeQ6)pyS4T(%E=OvuN~Tj2DPhPfAGv<-{U3k#;74Ci zT(={&q@&%L=CY-@l3ht)HZmsYb*_|Dt;yjouOGd7`;P0cpZVykolid3W6}&wl8fX- zPV%m%r6xHXDy7otv_&hF_M*~W)0@_wxp?laj~;sK=HOWi${YG7xzli6lh7KU`~!IL zPbQOfs;d6r*5{vm_4UnLpMUt-tq(r^?EOD|ihJ9a-~WJz+t~5r3c}u5c;bOAF;AHRiZAlbjHzhbIx8~dGV>q+YaS* z?v1cN_}q)x0Bk{kqS!cv-r%V3KW5LVy*J+5_~^6M<7Qxdl*@HOOr6*Q9Qldqg^xFvXIr#GR0+Zq6dtWJrxbS^IBfNnksEgc>AUnF8WpENiVMs};IkC(PP|5NL|jO; zvbeVQ*ye-t51iX@^5F$r_a_~s)MEGwLYcwT+?Dt>r?&{d%V4Oo64nz(Opb-^c#Ih znaPef1H~$8kk0j1B^5ZP#hzdD^>&y|dOj1;Nk}wHWnKgtDc#W4*Y*8r-ZpTU@8;eA zvxWa>Fq`zi`+oi`;_^MfQ~uYOje1(0^>=G&i!SxO9lyQY`mNy+<;mn_$1sXA7_H(M zcG3*?OB+wJM74Pdx7PI9|L!4yZ(LNjhHj%rjVdKOhAX|cdoNdE>Bf6bKk)LK&wTXh z(Ti7lj~J^mTC+0q!C*<~tvg+q1QFaQ%F9p8%pJ0%dBY>mo_y=py)V8$U}BTrER^2N zrX-EZtW)Y!5^ZD~Oi4>qI8qAw44!l3zC*8k@We;AdQF^Za_7iYCbgU-uWEw=^kz*! zhgMIhrAh6|C?7p#_cO0uc>mK`8+YfF)x^tH{8qVK%XANChQl}UfAC#?p)sbC+Sx}Q zIQjB>2QEL|Z_4a;F*4l1(fgB;V*)`tp;sDX)|uM03yHD1hb&ol=-Jm#zwzPji;t7m zf}GU&9Eoh>II*cbdAWt~Wqgd@o?hQ?=DvF$`|#6K&)g{M-cMsmmdSN02p(c%t#;lo zgGO#P>f}0OjKx(teCp0?ub+A6PZL*d&Md0Ta%a08sYKnnQe7B(v67Y*l~`?LjVbOv zdC{he*U!KI<^C(rRu34iOGL)lnQV6w&FV^V^V`!LR;;ehqVnp|Q<@H+KKtg!PyOk; z!Lt^&ukGe^r>RsbK$=9aVJ(zIKZqMGudICY=0{)r_|w;a`Rg}-{oA*m?fbv}?YqDH z_0~7v&X_fW=w3h?rvlr6YTzFr9FGB?EpWaU>U+@sFUE~Zm<|0jETjl&Vi*-FDIUy* z!8C;6Th===wM=bQxQb?Mc*cxcbV|%TAoF>Ng}JPKi$;Zg2Q;5Qf1z1sEC_8he*tggvKn*oI^C?|pR76ECg5 z_nb1>byvH){K%PzVhNcTK;FNNXJZIrAi^-jxTI3zXDa;d8Ic$O`ShKMT9jK4s@^@+ z$>|)=*vq8M#-G?D4R;i7vw6ql7MJsW^&TKK@-|i7;h%gf^exj`ZXDyY^ed#sV;rgO z)M4?$1(_LXM8UHH;S~NP{aA0;-QlHw?O{^$TAxJ&ZojoY5JKTn7y#=_B0mA)_EpYf-9<8r0KNdN3Q8wy5H5x_?=?8MK}#=`>Ko?&C$mYmQOPjM zVUrNKn%VdoV>pYxR2zZJ&MvU&%rkKlPTg93BVqRbbFKT1gi_!i5hY5ECv2TExl}1$ zPSWOvUF!9m*ml(1u9FtF9Wtq=fhCG5k`Wb$jIHGc_Esoerh2kYgfh=xKXApCp3Bxx z+q%czJH$dpyIq(_fgYeuf#*>cz<=b-w=X4V8p zSW_BaUzaq?3jF_T8CdAaTztYp2aW2#Zu|U`m-|L9Qn&>GSGdVx#Kf5m^C-+F9X55? zUBcV895s8`x;>Gb_O=~8RVH_|)-$&v!3<#q7G~4{RTx`1ncLYqdO1e442zsRc+-Jp zr|vfCGS8=jd82d{|kLl<1Rx8T;J#b>Xy=r>H)Oo61w$)Ten_Xt52NR5UTw*Szva1U+X zbNSv02d~E7f3fE56@6!yfBg18qVf>FkvbxYo5XB?>1}@QugF_W@HY;6r0k~@hqZ}; zjm(Tl3N2G>bGH!RR=s*nSr|EY&9K?4hR{al)MZZ&2`uLY}nFIv@a!SZesqwBZrK^YU%nj+6L85;>&H~6&{>CwrS zE{X);mqhj$4CGpx@z-3Bx`?7WgD78W@=HzqTGrNH4O=$vJAB}b1!ESk>pFgB+hG$L zb?wU}Ld)0!+-46%Alu?^L4^yRHL6p|OnrPj#zqcq91*G@lRlaMDPTw^{%b7-kyVzq zdU6|GD%#a;)N=Tkwqv83kDS%)AlxrdtKm7wfmilHE6b2;aWtX1K2M%vGWK^>uWBl89HS_TMO;oiK zspOfwTTw^y*I#iy5c%*4sx}fe(=Dl_K!SSg4=BB&qP+pNa{0bm(!Hs(i4sPDb$uHE@%8qDcGDDM>&_rL0GU$}IFr+98(b94=YHpDV2e(UdJ>$J% zAtM8{Hs$2as4t;sUc=Dze`H2l4sK2jS_O9O9n`t6XNyi&0d;Gb$O&-LBW*bcEHl~%qm}B9VWUg;zK_xY^OAz5ltyK!^;oOO8poh~E2~o+? zphbsjYD77286|Y}sNrSE1?7ZOo=Fcw4E2MB2LZVoWTYUV)Px1klQ~ydBT7^FfZdow zA|eq!@8jGu0}@VAa^}yLwlXtI>T&4laPMJ0lTr1WT4QtWi7KaH|DGhcA~PP zoQvL}nzjuW4+BgS5=a%}{1Tu^G;Y zxuH2}%d~#^#m1b%>*AubAEpx0K}wv)KBaGA1wxY?-lW?@8h_dHmsYK_@dmV=)~(wh zvV{cK3Gff3xw&~zw2BrQUN5*#n4f>3r-CQZ(2IEYv*WWPQ1vH%LOnuqlki)joez~{h}N*J7GIJ!3)TgfKmLc zG;iix5Ggc;HTnFAq$g?rx;ZWt+3ByGKML%1g8ki)i5M7wG8;fP0g|j+2Qk)eo0KZy$s= zcOT!t(6IVVn>TCIu3_^Q!Qu7lHEhgRO2k!d;*_K_#I1VuBa+kJ8a{*sN>Uf5Q)eZ`>t}S8^C|g9lfN1#4YvMhn^cNI9 z!gXJhMnwP^3?eR&$oBR}d;z;9=#z*8Q?9j@f>2Xj_bKI0&?gnuQQ@c`W60&!l$B@Q zL?$4Tg%(WGbos2P&hbI=$a(DWEZJH{x#B7yLdSVga@=} z-)h*HiEB4a-MFp$#A$Bzo9f7I{`WL$j#*p=9s#+Pm9?E?a2=n<&4QY>^a`(sn*j+= z2(3V+r3V!jaykvo?2m4wx^ah8H%<9)vDYR>W@)8=;>KGEGfh!RFzY^wUgYz+OP=(g}zperNOupZY3>mapq ztjtX0^lwyJbn$98V9fA2tD@HJp0)k(+}+1#?K(Pk<>tY&mJFCOr}L0;!A;sA>S5Al zTsFt3C{pKPEzp%SF%%;sC@92a5@nI`$ApR&M*7yyZb6OPwHq{U;M4_CYqw8Yw|(5& zt^H;#>NGa0*Vw7!qZfvRH`8M{9Z zEgdmrw;VXI-^3ZyS8u_ecFwj#kqg!|?LVq>nHwMsLzBY zYY9A{a1!y!f|h{?k#XPN*`43meZ=?yQ)YJ>Hhy@_;%+0R444=*I(mNpk>fl9g7|Hu z-l3|O6}Y5HtWEMlO;IjUaf2FH+ybJ&E5%05M4lQ^&C=Y?DX>nP$RRVa z*K_joZ`ZTWgjw^aFI(GX#Q1h2CUhD%t^357HiJj`L^RO_LFxQCg*<}vE)3*^h8r6a zkA@2^vjZ?fjQU18X8JX4nS?+#%rzbC0_)ZvGJM?P*sXKcZ=Sbd>!Qs&=dIf^HfFwO zP$+oFr~;WuId}zGY3?NsP=W!@4GuZL33ausC~pk`>eMo1)==A}QQJ1y5SDD+wqR52 z^yRDPuG>6vYD}Zn?d@y3n&WTHLu9Oryud{P1vx?yrX@0T6MxQBMa10+v}Q~*H4?R3 zj7{bCP9A}w?RpLv8WkNmWA?bYi^tAhGL0Cc>q zxJKf^G^HRg;pNOOsPf2c3qzEtg$3Ti9wdHm*Qw{ov18{giC(>Fc=Un^^OiU7(#OHW zmuVELfZR;f*b-ID5X?D9Nn8SA0XT?D48MFEd)BwLq!1jwBrCzcXmrt5GuWO${q+MWqsaf+kIjO}gh3XChv8=`+;EDzs(b00+8P_NrP8m%q$5Q}T zQQI}5ZQE``hYg!FWo-29k<(^2>)1o?;0kqf&)72e5k+ps~S&^lp3fx%&+;Z%la zy-r9d&D+P%owOA0o-Cm_cQ^je+k+IkwcXrY-94#0>gG|KT)ey# zSw67vJJS%*2uUC;l#*0(Ya%bn+kxl5pfx5a%x7t=(AYvoHye9kNgxuHp`bOvO127! zjFR6nhG`9GX|PRPa##x<<0YJC!gx=Fg3OX;Wl7B_3S3#iRN_yN8@}0pHeO1|#}*9| zh{|iM(D;*Z%(AlPV8n4++e!^uQxGevX>6gofwV?>Q%wvbwqtVCSd&U z&j2fK6;VX}Pi*^7!L6F@rImkUHvDolzy{TE&0XEy=}rZ$VXqYhwMBJNK_*xd$!I}v zs7z)km!pk}={G~ypRF2)q!lhf^<|P)r0b$#Ho<{_4Gq&O@{}-?GwM@FT!5Kq60@TpI+|OB`-H&| zNW+QF%v=tz31-8g4i`!j3wy`f^_#R{zDoBb3VfSdh`Fnb+$UrgB(50+L{vcF=SaX- zz2tPExq*&A0kRt_*i5C2yP~dEEvhz{>6t0?t?Z5MT&z5NZT&;!?mqgK_T*8KZfS9% zq&#(^+Z6}T3Dh!U(rayEV`m_@`b|&&e?+1}Z5+6%L@M$e|2?xYSR?6>x7a}B7t+@= zx3&pt)O^sCS!)lRK6B^EwI?rbK25uy^7ihFH&^1HAH8~iLU)^}|=H~M^HGC zF>_ZOJG1HP{pq`pjoW^B$ogFqcN~k^dusCfoqZ?G>@;X3)r%?ahP_+_XPX$+)YUSe z)GK8rsT?XmK+i@YC!rup7$wxWQhwnLx(yqfbyzejKw)nQ4pXix9Sa6(}_k`;=Q*gVO#fMIsaNRBTKl}OQ%99%uy_v#nD ze9f-Y7f;{3zw6}1J!h`Q9yzyW_tCj)V#gE3Ga)J8 zFXo~Gq=6X)WsQhBhY(EV3YWl$mVGBoi@k8+c5>>?1xtlBtf z?xIF*+RJQhNs}W-w-JSEDQ(Y3IkODA6i?STVs3!CWvDNNMpKI#28K>SA%iDR+qm!W zsoVEX-hUK(=KO|}=Qf?byky_8>Fc)*owcAz?*Ur&j%Z=rNE{LeEchHXN#uP3fw*c$ z$eLsuGB?mdW^^We$(_@v88ug*Mrw(H`J^+!%mn7^b|uRgZk zUSj5;d1|PJA&veVB#o`&C3SF7SxpSAg*$=iKXr6G>(%cxXz2Vk8}?tka^}&KQxD@0 z-@d>1>g^SK567(8&~N-ikMOXXJToF!rKk|fMPW%21#VUHGjeBHh;*VF!I{#-;m6_@sp^ z2acWGpm`fq6m$L=qczb>3WVXd;#X4^hI2|Ufbd8uVI(*HL>M6DW1WLS8ujecKYG@} z1BbR;xUl!;&E3~-Y&v;%e(a8s(X-q2>Vp>(b38y7V3U}QGs%kNKJmv!Lp@t7iYZZJ zm0rfo(#18jP5UlmCyZIXa{kWUD-IrBy!YU&t-D4oTGn^swEFEjJGgm?abFY?6o)5{ zP-D=PXiC}w1o93GCYWZ1HMDCudAj!)GIZ9e_3ICwJb3N?(L0YWCcQdz=kdCe7w7Ff z5VdLprV=A-g(l44k5D7_CN<7;^*RGC>k=7q%Q3lQ3x^>oZ`Hsiy{yJI!cc8(>;eOV zqz04V42ZyXovi@>*+AA4=rapj;Is^)s`H{JWr< zhQ3&rXbq+Uq9j2~T0(AU4bnTM(VykdFd(fn(n$jx10UbQ!9bNT8z+Ybp|SjV&#bd& zmiGKQ4ZoqhNxaGlL5SoZh~=XB2fXo*RhB4kRE}_Rb#sR1+yOLb7;C7ohhlg3^AeT5 zIIEmVR=nBBIvc!w1x0&#axwrmQ7@RjfGZBbbElaa!)#BUrtRUGXq$%BBPA+#B2^g8ctaX5&8j|H8Ife=-{yjl}8I%*HW^%ELla zps=P11|gD`k=YC&fk1@gmh{&@u}z|&>Z?UXidsJ0>260|9=NIiP^a8xaA}~V_8jZz#HTt z;DgDDqf1Tv2TdukCKE*pFj~s2SjX8?vWK$dhx`TG=no+@lBm%Hq-mP;k|l}TM0z-V zkQ7IuIfDQ1XB7;Vj z|669GW8rpVbU@!gx+X~2BfP<&sk646x$@x6r_cGtxvKI!RYiX3_x$o7xuxGf<*VY7 z(k9JWGG^xdrk%ShTu81WG*`_HD9oA!XY&w>&K4&^gmCg&nVHF)TUGJfsm z0n?(r!XpeIY8}J@W1bOad+dsV%nAwKm^2PLrX=$=#fE2Y>EczlUH6y`ThAsXCBFUq zF!kfr#I#fQlMmibI1=}C@6~&YcN`cqcX5}YBkDA5hI6His`UC4mq*sc#w7sQ48h6- z=)$(k%?$_vaF*T;n~h$$eA|^(-v$ydoBKR z_WPWI_j$^U+``mv1xcTB&OUg$_0)wm`;Ls8v$$@{HlhSLxx@{y+cIQR99mRQ=O@cW zDkx#*<*X9kfjf-8t$n{K(+^&|{V?ra!u!lepFSpi`T8{TYy8`+3s0W!yMAx&sf&{~ z@9^x>!`PA%=U_Q0f;gw_596drr%t(dp}d(GVCS;LL)u7B=3q@_pgHT-UwrU5Ipfpy z=jm6I({8+cd+y20Jy-7@xb^Vhtp{^rceETZ*xuWl#}#Xc7?;Iu&n?M33I`Q>GMqlh zp{PYAcl120e+m!p?&BtIJa*>X{U@jI#qYXwef^1ZtB;;ud;I*yGnaQfLQ8FRj~ue8b`6L#Iu52?-H~K#`kCXiXAShyxa80|Oobb7K@{(L)0n z1~R!vXx%=eCam1K|LCGcHX>q?$w)%$}{90fi2P-v+e%U8hQRamp7P-+KZSeb+GvPJ2cMfmYdF+x^8_!?e zcR&7gV)D7fXGb19+IaEWn)6p?@7Onb-cmy8o!opyIlw>tZ`mj79Ido-zKAa&zf&r;7NygK#p+3CcTU3cQwUyfUM`OfC6amx=LcMGpi4h^of z1ZnKB8VFgDIFpSG!P2+zb*$qLO!P79KLeYz{u8rlfiz$SU`F%v^=BCz6haefTX3Ba zUO{wVo3G#s40%}b5QUI|z%z&fg$-ei2C?vQHUe)Rl(TXZ?*ZG$W`=Fi!O@w_9|}8r z@@xGesZk0_;v$XgR;|3Tg6~^xSL()7S)F>Gwy0jzv!tfMl=ZkstMuek&XeHmoOV7DRCx9#y)8hoADLZKv?~a60=F?5XuE^ zK`cK%KY?eQ49!0Y-k>;4rLG>Hwb9k!Iv+pOOHMD?=Epjp0@d6-g9C!8t`)?e`~q19 zaOS;yG(iepc6K)0{Qw*DAi4s8jdhrBsEc*B`UqeaCXMF*72B|lVigruQY|fPqcr9}%=RUnP0XQrfefHg zGKE6`!9c87~-!dDw8~Tt1)hRHG8tUmP>{|{T zvF6yhyYI5z7psekiYu#rRDS=iLey1N6qQw>_h#i4Z`yrm($dxaCQlD+-1IjcZM;>n z5E^brYb2YQI(Zdd@rw3 z6_u+ieq`pCoVal>W?k&0RqGZG_5e#h#^V`BMxRWjUAoz*m@kQHmAwnrD@-x z>yDp~d;2Lpzc5=_peie`D6gohtjf!5Kg%n)`84JB)6`3kUmU-aaOP3U zo-6l{#3i0jcsXs&#uj}Cb{#sx-qizBs|Bf6#psV!S{tQVB(0I*)FX^ypf)##w!*IK z#HoAl#h-bZvGmlnjK)k3k-(MPT{XFukm>YA=jO?F605A;AfP{uJ* zm)m#;PFlA5!jq@ZKWD%C^f~!u>dUk@@y}8oK2Lr2HtS_p?v12Zb2sjszACnLk3LrR zPKbh-mH{iCVDOAC%Z&R^2av}f5YIFH-}GwP`v!F%Gkw#k>+zX+Z`Bpw3b{H3IVyEl zQOVPHnQxV)sd>e#_8(ui=jhnEOT2=^xRYguhSn&wAb{{kU~JU2Lg+Wu!Ohu%!!72_%!W&LduRyw`OnI-Ktk#GfNpU+EldSCWTJ`6{bHB7Z!H|)0$ZKAxx%*rnU~P z2M$}j|LFbqU#>k%-*Ng%^y)4BC(rCXamK_I8#bJ}wByR1wI?r5-L$>w&`}l&JXiHF z*g>vXGr99glg&LUh=oZI>ESs}BV%m~tI*aRqE~OY5dZW=c5d?L?3Y=2FEjI=z0ZzM z|Mck92bQzeZdrfiWS7ws9DV$RVh!`7gE6c?gN!UfztqDlY@+|GDg6!zPkwm+zz%~W zHy%EHKlSa~d{sta$(usum&&SlN_D2H>Uu&-?4fguHt(OfV6C-JJ$3^33PY_11z{E7 z3TkD$m4yjTa>&>CTADh#br?Kq;kE+c2u~5`w~h3b4U%kQ>7#SVdz60Zke}Ej6kaaK!;& zokaCwDXoB8ycukR$KZjVIiZ@|q>U_j4`0E-I3pgp5dizgPS`VS_OsN6;T3*kJMZBq z;|*A^ZUp)y%*JVf**rFJ8Ze*$~;@fBBa7{uBBK>&R~S zwk=+5PW9CIMUZ0keWzFh7!garwC}c=Pit|$msl2yQZ_5QmISx3ybp#OH}2*SN!-r^P6(`oW(C_kor2rZ~uHi}MSs)D>0bKT67ed{b9liccD|d~L4@Q^T6J;^I=P zRzql9R3meOaIw7VF%II4r>kYCW9H@_-g7|Imc0a(Cw$3{d!BmhY0A|nFVEb2cH~yV ziTls5JkL0GKXLi~V5a?mz&8pn@)Ng#$mSZE9ZRr&?um9v|8&_}bnz-BR$}rl3s-}9{S~c(q7M_RL zF@^ca%usF@(7NO56K5ZN{G66k@I3u(;*+QE-)BB~nwrvF6ququK zv2=9e88pEfh%+0yijWpz7$S-ckuE_O5>*>pDuzZ)J9IlPKI>~rZeik^kN2KsTz!yy z^GV9hgjeV9Jw1Il;ndxy$Knz;p13qLD#j}?hzS?ZD4i{)K)Eml@+FigAthA}D=Tg{ zLwqjnd;+Jg-E#cN%j>BhHXXY#ZSnfi(-uTdo;_jqlE~-;M9rPHDz-!aL8yv&&hX>GHfW7+fYH$#5z6cp*l3tV z*3`FDgtqCpVC$Y2*+tnEKe9?H@=D58s&b`LrB+vEeJ#k$Q6;2**?#8Muz71bPn?VP z#Z3bR(Ztbkq1vVU%b_Jbdo6cp`k2RU?J9x3~O21%1smslHvCrHEHL` ztDo|}t1Exc=gBXrDk&<>%*s{${(H)|!gr-rCmtrPK5~BAn(ej$^%)SWv5n)Dj#*mb z8A~jNxw#o7HG7Ypc=CSy^Mc~%O7+c*%p>=c4qdr>=tlgev$s~AzOgGV>H7QJEf;R@ zICUkYNn0^z*9d6Bq^0pe;s{aF{CvIZg@DY}k8I+h8^nHa9PCck;IZY%nl< zC!JVUaB3q&m*8A?FW`-3fVW?ukH4>{k7(ZBFdHxgtx1h_`T`y?iP_42{~c#GI1PI! zf*UJHZ7|!s#f!ZBeRNRRFsKr`1*&Q4prNz}7KIVK6) zU^YPOXU#{D4^2F0nkVDmu}!)J(o!O{pRtWC(w~Hn{hxd#Ar@FA89gObs|L2}m(?IA zSx6Z=_)|5uNz}wXB?1(XhIthK9jQPAWC*JK$!yYLRD%%PK{d%3`ZKNl?>aSh6}E61 zH9!G28qte1&6a<2W|OGwXEys8*r2uQM)!n?fl-P}scoQJQ(vd19^#oUb9hXz9Gi5a zSV|{fvW)_A!fj5dbt2XR+aFU~hUS_`q$JoQx$fWjvzg$eOr|+QEt#1Pb}~g!ONy0+h04;h3R*EYUXi-A;`_I}!szweCal=lZNzxyycTHVMurNg zin#_p-DLAKw7~P(%1nph&@P}(qyA%~HXnYLtI8}@sw&HhiVKSi3#-a1e*f`%L2f~A zZb31WP@NUtSLp}aD z<#kcX*GhGERpp0*g0de!Dp2oK<&~<63RUITuld-Wu6R}BXw?sGS)xaX<7#h)Z_=K?=cb`gpb@5?*+>11vudcEF_~psFNqaBf+jZg2 zo=b7NuiTlnWlw`%L%I(e%jX$R006>Ti7P|FL-Euy&;i~Qrnt{p$ZVW~I`XG@7}#&HRn+X04ic@N(D> z>*(;vnc+jHwVW__(2`BVmTc%Sa&pryeNe1~#Z5$v;&_I2Uk5K9$Uqp!$wFmgj9<8N-sasAtvgvN z>@YVgs1K-H0|!r37jpyr*-)bm^|XE=@|A=uTJ>orh+wjy1J$La)Me9cH6r5LpQ^4O5?xC%# zyqmV!aQ<4{hp%b*#hH1^Xb==#BXGhtJ2X+}LCA5aQy+gNd;f?j=CnSeH<017eWPv>2S} zU}Sbq^*i)jcJR#Q^sKqt4vd(&XxPM6O74uW#<}`t1irDtY6c} z3^CB!GooRi3DY+nzwrDs#%sRX^)_ulJ+i>voi?> zK}lYA-q+lM{L1eS-+vvsV$+oEhg$U+0M$s$hA~mvEt(a~hU6}z5Tca@Y>Byl=jp4r zlU^5<{;TL)NmW6G@Q3)O{9gWDnN##7M_Ew$J>kQb?U&-F#vUB8JeIx#6qE=P8k8D4 z7yH-KrS7<$ouk~z^?2N)I~kcb-(;RjNZEJm(f;cX4ql1de;KdKxNYa}?7IBm=-p?# zFUBFd_8&jP#nVSpNZ1KSD4`$+kIse}l9vp`{E+JJ1?R~B!8#J@k7&EDP-5JGrh#KhAF=?o!DVlZjROEyZ98c_#?l-k2VIP7C!_4IM~@MeXV zyiGEXN>Uq38WJ2k;b0`WPvSIKixuFF?GRVB&IXwMrAd&$MraL|cb>!` z`1tw<5cd%h8eS(XG`J3CP#_H}Ba};nim`|C*N~tPv`w17zaK_OY@+uFh43QT8p$^z5MxZk+MMi z%xu-zriI63EovX>U>mh1Ox@NN!w*f8+6aik!U%_eA0P+H4-~Z3vi`zsU>Mg-Qq@?gZW6QoWyxP9Y{R9E{eUwprN$NxnEgwt*U!wxA#tb@3rRv2 zp4d3K(uCXZPw@zV9HS9^JsC%cvWMA-FlC)B2yUYNWEibRHO>-WjhIFdJu7VI7+6Z% z*+L^Zz%RA5e#2m@NoR+e@T;!gFWNf4>QEy=|1W3qXKVu&u>P{dL@lrx&SM&fLlHLv zVJUydY{n*pWE#ngYFS$7=$f0@)os&r#+rRM6Vr3@3d)L+M9QkZmsNf*ul%7Zt56oJ zii%a=fBarq^?k?r>$79`bdMZw=}?=V4_AB}Irc>@=#q*eWP>Ijg2GHBrf>;u&~$Lr zr1giNeJ#o>Q)0fXEUzjl5yD+jX+>$(ccr?tNL{8buXy=BYu>)o`!2;P99$`jqOe35 zM-erkqyup&Mn-a+Toq;vG}2(y^_af;$i3(9mBodX>YS3Y;vZbd~^QIUG?_QTWH?QGv?D6ZUyY*tog+IqD(Pjm-}@1mdtsrPhhkR#H!dAm+g zbEj-SeEE6CqvSN)gf2WzJaa$c(&LvmpS?SFJ8|dPn@4WNUrc

      d4u;y@pO(zTOz( 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 RF8pQ8Px~ATq(At<{{u18&KCdx diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/BTN_UP.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/BTN_UP.bmp deleted file mode 100644 index 1b023ae02a567379cfbb0ab18b2d33c87cdcb6de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14132 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 qoH&mj`b~zo%aQSUaQ1sJ*j>< zga82o1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk f1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+z)#=;rh*Mj diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/LED_OFF.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/LED_OFF.bmp deleted file mode 100644 index a93ebd571bc859fe97a8dee3fa0f3cc85bf34774..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 784 zcmZ8f+m6yu6g|c#-+VO25AX~8025<;@Jl9|_yHPY9Jx%PP)e^*+5#=~!n6Yvh8Y<~ zpal&&j82RX>aV!kDw%k4&dy2JUhAyA+J{eX-z3R;fO;S27S3Iq8{`gZx?bEPBtHMv z^Sx*LZ{BA2vs8{sE*YUJyngxW$>T@ls6Sk-kXfR&16rKZ@nL+Uj}d8T#tQnRX*k=@5NY-0#=t5$8i(hHBIo)ioxs@LlFOI0(0;kkRDTtHPhh|UKyC{ z_Tu?=Gwi$ovuxxdNNkzSCq6;l`D_~|smV&U!cj?PJ04~*+XiVgbWxD#0*$HD+2K=F zRIAe=hSAZ~W*RAAgpM@KwrR9lBnU>n=c^43;o)Jv%IjM5(CzVTg={ak)9KVZ^z5!} q8m418!7we*gM;xxI+O<@xOFbTUExxL(bsr-gh5zxN*kKdx#3 diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/LED_ON.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/LED_ON.bmp deleted file mode 100644 index 50036a29f120249d100c7526a77f3b19895204d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 784 zcmZ8fO=y!r5Zzk;>K}qwYgH7)pQ2EqCXrT42`Gw{D2R9{R8w-$mO=y%z354b7psTf zyr>6Jdhn!2Ay`mIF1ELt^dw@@OOuo@yZg=ab+!?4+4-2^&AfRt`=zh!Y&Ck4{2r&Z z(K=}@ri0&b^81ZhwdT3=;^lauko`J$vs}qkD%Z;8;e~I*pJp#kJu#0fixbuAP!yea zF6I1L=Q7sis?}_Zh4<< zVgv$4nw0#5F`ZgiN=GqStxIS?&K9i;Qj;R)wqn%%AC@2|u@um*7@Gx7h6&aM&QSMP z3$dQSNu3NfYBRQ^LoHm58EMWyd4V%%S;IIx6T{9zKekA6_MG>WC_dc!5-2!aT)ocR}0sX9-aDEUtqVLCMT-$bi=L^o7No$9IQ@}1& z&jILki`-~5%ybmp11s_g4?6P9HYVri%!2qY-hJ?H26&}+M&!M-&r3zKWP{{XwN0@(ln diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/qp.ico b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/qp.ico deleted file mode 100644 index 032e1307b5a64fadaea08a03d24c25171a25ee32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10134 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 ZC2(V((^t25{9Yk&%3Om4B=CO;`~m9RnhgK| diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg0.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg0.bmp deleted file mode 100644 index aff47d19749ca9e086f8841136c7e3cc63f26e88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg1.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg1.bmp deleted file mode 100644 index 168b85ba8dd770412ac24cf349925d02c8dea8c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 zcmb`Ke^69a6vrXh-#^*i_x3G_A_k*Y#!O{1qDah`R>Mpb{ZX2lPC7b3IG_VcIZ4zw zhNa?KrvD|5{g@#qr=}3J!Epu~{VV@~1hoke31uR1ci*yo&%MiIae;lV-g#WkyL;c~ zopbNG=bTqinCDDjZ87@!_?v~lCHPBBkkBV2=)=FWn{X$(B$q>s`$|eomPC)$WQ%0R zP2&%~_2z15WivlAW@W{WP$<;Ua73%oJrX_l)Yi7Nw1SDYdD9k6(gZec+pDUoLG$^1 z=)1eGivr&>(lUFm;o^5fDHN9=H@t<>9c0fos(&|If{yk0D;j#)&h*#+1Z)qNq0J2Agj0CVRN_~ zf=;7*<)xR$LZM(#CgfO9mV0A~@YMGes9oz%&TxabzqeOYV}Tqobpw zstnU{K@1HK4?nr^DTm#eDy7ZL6r2;s7Ba{-i*0`Pg2BOmh#8Q-yaCEP3Q3XPwQ1O$2XDIQ*eoJCrz^M*jL9H(+|5L;MAk{dcA6x z90(e`-Q^?~^@yp6?Vo&HHN|8iot|`axcPv+;(+e zcR2-3vUc)Qlgw0pQdR&=w_=9U!ulxN{J2nXI(7{6ny+Nz)C{6d?veL5t{#&5&OnUKR zJCdM5Z<=m?%<=v8pNGbfk3;?dyotiy)jzIEZscog%x9w~-~g_8aTOr&cGOF#9C+2# z*V~gZJHu+WML!aA1W&D6xhfc>dWkX|(mYE^ckT>kWo5_bPFAxuXHm|*(GjQ`8Ae9_ z8+rb@#m*Gh%vvF-MNhCzT z=X7;-5t9XE2tZYh04ku$OXtRF_=t4 z1bIFUG#o%^a<-)vOzuSx_}1^QU;lroHEPq!y2QS({-{zxX*^XSnp zk*{Ov2?&&oWKxz#HL`10O(c`A=QpQLsbEqqhr~@*J3uD$J#G);d0A;Wn0&h-;L`^E z+2-acUHU%F!6ZEiNK6ROM5ooiy=EO_^1KnQ#5y}W)G+B4v_TBW^aK<6apj7YVDj>Y z;QRxmuPdlWfVe6KX+x@qJg(Fd{XKs&u z#41HkRyhJy4>x$3s>FnV!~`bvG#ld2O7POZdwK}V&U;5kC->xsT-5^y4uUx{LScXJ z-g@%k@eeeW_C`-DEh+21aRWenac5*?ay`*QRkP8Yo;D}?k(eX2s)xOPpD%COa--ge Z)4{N$E$V8!#U7I|UrD*5k_d0&>;%93kM{8r_G&auMj5RW;+|@zged`h{=R@3N&Ig z8X=aSpZDda&9G`BAo|{NpPHI~AfVIf^aha8WHgO%5(R8*Y>bJHvp}P_^XD(PeXAar zMw3ZzfH(oz=7mstAJpZojn^96Ssfg{vnkLk}#Cp10y5EKMf5H@$m{aOr2H- znWDm?kl@fiE?-6;cEVgrrk4p!y{8@)you2n*X+8p@#XYLgXn_M*0!~86gqV6~*?Zht+@p^N9|M!d zkGTz8^#QjQ_h?&d8)GL4IXINUuKz5ETZ?=2_U&6hGaAU!gXqd`-?p7wi+l9ywZ8#{ z1!5q_ItdEac;-fxX$5*=W& zMMFbR&1e*Jcv!P^$uc$-UcT?FH@drfEHH64t^If%uP&Rwbe|cmEhLRFN2Upm)i9^Y z=1swDD!hEDhpgew9R`yen_3-7%XjbG4GQ`^B{@0kkW!icy)r#rnUQ`-nK6EWmlpQ* z7B+C9KvZ2_4IHgjM>l(EX-P=Pme$r5FsXadnMjoRXyDPVUAuCB%$tmCZ|89C+|WFTB#ULF?ujTzR>)g9H2z)2tyiRaFpS6oy88LSbq6ETCYAc1RO zFjQ{V*DqSQSS%7_M|(--GO5h`h=|CjpMUy=?kNfjc@BaMMp5HML`0R9l_eiIC=$AO zddQp{9L<=tvtvj2y?c!ihRV1vC;k&Asu2VUWUf?I1#b?$S$~5*I{Rq0vy-!for47? zZntgSe(YE-HG>LUZF6#RBO@XQ21wna(P+@t)Z9SvIT?_04rgU<-1vnuLz$M6nwFZD zmWp=lN=Zr0$WZRw8J?B-!{`X9Ux?9++4t|=mwS1?a-RI~qct!Lp#@i9`=P~cUvH1^ zOkXxTdHHKruR%nU@`Z^IdWfr3PyGD@5Kg@6Rs|L>T&&d$!!{anv>kpv{PvQi9&S>r zD!fd8zktEPK{F;2FieG4VL!r&SKX?>%o(%V+DJkp8J!_O!o65KtMXG}!WdNG0HdA+ zF72R_pNhIw8KFR2RsAP0&0$QJJ}D{5+sntQ3NO>yQF!6v#fg}B6~b*wN{U?eikJ>| zj)esz=e)3!345hd$!iarz%*O?!}ByLa!Ih)MlQ+bXr#VDML;;g7H#$gHXsfPV@$$5M1GS1Und#`@^i^;ugE8j^X+-CW%! ztMGDcZEXGL1mL>?Flhoo^@9GeMuWL~xLNuB0L=aS4#dX9ohdz2TvUXY+~Q&^DY?)u zC@3s1Kd(?IPMtgj9KBwPQ;ZO^`7w7~&Q1ag!@@#BOG--2^Rnnr!|;`3=eOY~9x#eP zLZH%EMJkZXMiJ?033qQb&sIl1UChaNfg za4-QAc8Z*Z6f-0w>@xEfk9lBUz#h~Fl+5c(Q#&#n#xz=4M~t+0;&Isz@N3F@4rG`dw)J3&z;YS^l&-GOvnD z6{rXFI^FX3SD;ez^dNJWx)W=?WO9jEg3wCbySJ^q9qwYW?gg95;5!yRG%a{@fzVkb H_w@cBzF!+7 diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg3.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg3.bmp deleted file mode 100644 index b5212c2b73b1be8b13faf8343aeffc1f24d6ecb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 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 diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg6.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg6.bmp deleted file mode 100644 index 78988eb3c83899a15edb18a8e958f6d45567510c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 zcma)Adr;KZ6&Bq0gI)H$AcFV^F`}KRCN^4Q95s#BiCCS+m_Z~FCyJJgXo0E?Zk51_ zZ5l+KX#a>-5zq$B1bjq|Le*GNXUw!!0pEyLkOXCS*@b@Ro@HHFQSaQn+}H2B=XuY$ zOqwyl*iV#K(I((G0KeDq3+rb?+pnL(zb*#;#$vMRBJ>8mDRX(|>C|3rAwDGm#@T!MMaxsQh6|) zBSs|Fo;!;rug~Y{z;*(}@EHZ?Vs)*{-2PO-=PFbi7`Y7dpwwDFOB|^mu6U*6rIXR%B&o<=ks(!tkjQzzJA7bLMPL&L7a} z=Msw2QA8!$;_}dWbZbedr4g3-$eG z)@)$HKA8sm#jw8Nn#pLEN@Sx(j%scFkw_Isa{Ksk`>SKdYLr^s-ei-0O_BXuEjFlc z!i0&iWNhaB+%`8i4}bX;I9gonpxd|a^uh!I)83x0RqLW`1Hi1^Vn@prR|M!EH}02i zj|VIVW8z{N{d39#qN8H!uGRw+swZB2zIG8!=FNQ{t6)= zqqUk4aV!y9{gTB?s!vugU6!%!i@&i?F>D`L{%Pz%4>{h_rT*KPkrgueyYJ59O~?YB z&VogY(tr5j5@zs8w=9GI(j;yV7zy?q`S#lYh1^jplro8I!Gct*x?Cr zlPE%=f@dN$x{-;a9zLW*k^PriA&Lp(C&IPa<;m-k)trPABqqx36~ac+8n^7j*#ch z9XpY2+RS!9iSY5Fm@p3rtsuVuP%K8#Asrp8tW?S=8zD@}LjB00%=Vh0cpWaqof&|F zLv@H(L-mOhDg|XDf_F~v086TWc7ZYD7EKi{@7Gax+JEulMWG#_fygJAAo#hMxb0`n z64{6k*CyE~KP4I(>IcTe8FYxmRs?RLcOb)}oWLx;SC zv>%v6r=gov12PBuGe`xdMx`D5+So^rCs#2jkeCQA`8L;x3%9P~!Wo2cU zd1`@hFpvLoEdD6H7a)eP4M+)ootx{xHoRDouV(!|tMP6lhByKRw1a*Kgo{WUJdedw zu4MP_O-25cI{*$$(5X?Xkv@SiJi`x)S3Fb?DUe~2Wl;%4d$wUn9c%3_*Rr007|3kN zkSgS#G&8BgLr+?ehEE6wgT4#4VDTUOzWVI5zXph8-kDT9(1r{icJ>TCrV#QdS3?93 z5Z4DXB{*Im9vT76xVU(x6D>&9s5CLru_yWeLS&*;1mAr&E;sQ7ogyD#SY%4@4gpIJ n0)NqK@mx2qS-rZxp#kFRgSscvyayil-rRYKuO!k7-E99qQ@Iz< diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg7.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg7.bmp deleted file mode 100644 index 8e7398846b64f25603a756dc9b08699b0947939c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 zcmb`Ldr(wW9LGWS{bV0^A0UG0l8-cJDw`2SbH+zC&PdrGr3vYzqa%bP8tXG5Y8=Dz zg=P9*@(3-o%q)DBjuSTeSN_2!s7-=sD8tI`-o4BAJ?AW!mDgT3&)hwnd+xcP`}>{q zJHOxWFnd9cC4rWysK?zR;_|X4hmbf=x zy?Tu@gJ23l0qtKJ8scE4jT|*PJu}&8&dtpQ1WJc!2~wuV<4JX@50!P%qBo^6IjTFyS#S|KiFVG^8#n$U%ut_@xGgFwlE|dA z2oqS&%oz>Ijg42BoTyQlobD3$6Em?)W+JLusrl*D&p<(Uii8aiflIfSNn>KsnUI{7 zu9uy2sFa$cb;khV`CynXI)hhyS|O3yyNF~yIjarkB$p`c0KCK%1S9r z1_TY(ZnY2-b=p$k+duiZ{Bb6kgsQ4)DNIW1Gf{lPVM~!E%Ga+a-k9i43!Bdq$4^LM zVnv9kbS8=J7NWaCrd+XNC1bKp#F!T^UXsG>olGVwSuBUmp;D;dczqF=uuo=1_>0@- zmYY@!CzmN6f9o+d#Yf@{fN8fmv}$cm&Mdei02!0j9UUDL#!tjX6JH#(k>VJMey7bT zK81@g>XWmxX9Rd2Dn~QnSYCLZ@0 zFJEp%5LBzQLyeEwzpLW&a1Y{fm=D65h`YP~=XHl2@!Amc-GKwJ0q4w}4+yLs`4Tb* zmNm7t-pLr1VbB=|z7n$sZ_S@KKNKSQ5{YmK^E4zqc+lZ;WyNPs2AyHbUwUz>#bg~`Dg?EG1B?cfYfRSt`}ajA;u1u~tU`X#Hx7J}^?*sokmP|}G;=T+ zO{3D%o12>nlR9KHfW-8!UcCmPP^-}o1r#~75y7&6f)8E0MzT;gli2U9QCz$Mu>kQU z29rt%C(nj~h7AZw&YV35CbJ?m*wSy?w#{izk&TeYWQyvefeU9MwNm@T$&=AcxKZ4e zmzN{9#sp#jNAgcXqk*2oBtyIEs;X!v3?H{UckUdXsp;EgVj4!Hr`?&9DF3WtS2UB! zdGO$uh}W^?1O!4xGf9+3HnM5c=4d9H&u?mLV=~P~C~QaICR&?8Ch9xwPWbb}f+8^4 za-)Hx4eB!u4TGArD7kCwGf4ZvBytiUVWI&^lnT{5OY$g_#f?ZN=J7NQ&jcLX5P1Sj zJp!b1f{FMzZ_Ye0S$ad@>;Tf%1{sh8WVyzPvh{1=pn*IApT-4aCN*b=1;U}dJZm;k zVqu4xhn<}`dt#%dr;qN3ioV6_E9GhgS$3%uDve5)n2_iio8|5Dg2~(nOYggVK77|= zvJARX+dnK_U%cVi(POnWH8s^WwY6AMa-oe>^Z4=a-EQ}huaAJq^M2y&Q0V4|?zq&d z{>elB(!9F5I#I8F4JMe^`)Kv5HTT-@;VBG>_uCT@SnjtXMKy$7_hW3sONP7YK40L|4fIim3mf+St!SS*AJ))cnfx`kVh$CHtf z$>c;0QFR(!T59@lGy{ZQYyyeeLl=L5=ymGHQ~UQ<@_|6kjF}ph2D^h|iL}@+$@*lN g*48asnp;|cC87*l*qE-aF8rfu(!@zfXdRsMKRwMp=Kufz diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg8.bmp b/examples/arm-cm/game_efm32-slstk3401a/win32/Res/seg8.bmp deleted file mode 100644 index 0de55b3d8da7a405ad02a94fedbcd359e794aec9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4926 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 AWdHyG diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.rc b/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.rc deleted file mode 100644 index f471e8b2..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.rc +++ /dev/null @@ -1,127 +0,0 @@ -// Generated by ResEdit 1.6.6 -// Copyright (C) 2006-2015 -// http://www.resedit.net - -#include -#include -#include -#include "resource.h" - - - - -// -// Bitmap resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_BOARD BITMAP "Res\\BOARD.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_BTN_DWN BITMAP "Res\\BTN_DWN.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_BTN_UP BITMAP "Res\\BTN_UP.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_LCD BITMAP "Res\\LCD.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_LED_OFF BITMAP "Res\\LED_OFF.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_LED_ON BITMAP "Res\\LED_ON.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG BITMAP "Res\\seg.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG0 BITMAP "Res\\seg0.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG1 BITMAP "Res\\seg1.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG2 BITMAP "Res\\seg2.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG3 BITMAP "Res\\seg3.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG4 BITMAP "Res\\seg4.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG5 BITMAP "Res\\seg5.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG6 BITMAP "Res\\seg6.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG7 BITMAP "Res\\seg7.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG8 BITMAP "Res\\seg8.bmp" - - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDB_SEG9 BITMAP "Res\\seg9.bmp" - - - -// -// Dialog resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_APPLICATION DIALOGEX 0, 0, 568, 433 -STYLE DS_ABSALIGN | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU -CAPTION "Fly 'n' Shoot game" -CLASS "QP_APP" -FONT 8, "MS Shell Dlg", 0, 0, 1 -{ - CONTROL IDB_BOARD, IDC_BACKGROUND, WC_STATIC, SS_BITMAP, 7, 7, 552, 411, WS_EX_LEFT - CONTROL IDB_LCD, IDC_LCD, WC_STATIC, SS_BITMAP, 51, 80, 171, 158, WS_EX_LEFT - CONTROL "USER0", IDC_USER0, WC_BUTTON, WS_TABSTOP | WS_TABSTOP | BS_OWNERDRAW | BS_BITMAP, 160, 315, 45, 43, WS_EX_LEFT - CONTROL "USER1", IDC_USER1, WC_BUTTON, WS_TABSTOP | WS_TABSTOP | BS_OWNERDRAW | BS_BITMAP, 70, 316, 45, 44, WS_EX_LEFT - CONTROL IDB_LED_OFF, IDC_LED0, WC_STATIC, SS_BITMAP, 278, 324, 6, 16, WS_EX_LEFT - CONTROL IDB_LED_OFF, IDC_LED1, WC_STATIC, SS_BITMAP, 255, 323, 6, 16, WS_EX_LEFT - CONTROL IDB_SEG, IDC_STATIC, WC_STATIC, SS_BITMAP, 252, 206, 97, 54, WS_EX_LEFT - CONTROL IDB_SEG8, IDC_SEG3, WC_STATIC, SS_BITMAP, 261, 214, 19, 36, WS_EX_LEFT - CONTROL IDB_SEG8, IDC_SEG2, WC_STATIC, SS_BITMAP, 281, 214, 19, 36, WS_EX_LEFT - CONTROL IDB_SEG8, IDC_SEG1, WC_STATIC, SS_BITMAP, 301, 214, 19, 36, WS_EX_LEFT - CONTROL IDB_SEG8, IDC_SEG0, WC_STATIC, SS_BITMAP, 321, 214, 19, 36, WS_EX_LEFT - DEFPUSHBUTTON "Quit", IDOK, 461, 19, 93, 25, WS_GROUP, WS_EX_LEFT - CTEXT "www.state-machine.com", IDC_STATIC, 226, 421, 103, 8, SS_CENTER, WS_EX_TRANSPARENT -} - - - -// -// String Table resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -STRINGTABLE -{ - IDS_APP_TITLE "Fly 'n' Shoot" -} - - - -// -// Icon resources -// -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDI_APPLICATION ICON "Res\\qp.ico" diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.sln b/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.sln deleted file mode 100644 index e4f1c294..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.sln +++ /dev/null @@ -1,23 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "game-gui", "game-gui.vcxproj", "{79027B25-0949-4F66-9765-4EFBCBBEFB94}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - QSpy|Win32 = QSpy|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.ActiveCfg = Debug|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.Build.0 = Debug|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.ActiveCfg = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.Build.0 = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.ActiveCfg = QSpy|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.Build.0 = QSpy|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj b/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj deleted file mode 100644 index a6fd8fbf..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - QSpy - Win32 - - - - {79027B25-0949-4F66-9765-4EFBCBBEFB94} - game-gui - - - - Application - false - NotSet - v120 - - - Application - false - NotSet - v120 - - - Application - false - NotSet - v120 - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(Configuration)\ - $(Configuration)\ - false - false - $(Configuration)\ - $(Configuration)\ - false - false - $(Configuration)\ - $(Configuration)\ - false - false - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/game-gui.tlb - - - - - MaxSpeed - OnlyExplicitInline - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) - NDEBUG;QWIN_GUI;_WINDOWS;%(PreprocessorDefinitions) - false - - - MultiThreaded - true - - - $(IntDir) - $(IntDir) - $(IntDir) - Level3 - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - %(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - %(AdditionalLibraryDirectories) - Windows - false - - - MachineX86 - - - true - .\Release/game-gui.bsc - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\QSpy/game-gui.tlb - - - - - Disabled - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) - Q_SPY;QWIN_GUI;snprintf=_snprintf;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - - - $(IntDir) - $(IntDir) - $(IntDir) - true - Level3 - true - ProgramDatabase - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - %(AdditionalLibraryDirectories) - true - false - - - Windows - false - - - MachineX86 - - - true - .\QSpy/game-gui.bsc - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/game-gui.tlb - - - - - Disabled - .;..;../../../../include;../../../../ports/win32;%(AdditionalIncludeDirectories) - QWIN_GUI;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - - - $(IntDir) - $(IntDir) - $(IntDir) - true - Level3 - true - ProgramDatabase - Default - - - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - %(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - %(AdditionalLibraryDirectories) - true - false - - - Windows - false - - - MachineX86 - - - true - .\Debug/game-gui.bsc - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - - - - - - - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - false - true - - - true - true - - - true - true - true - - - - - - \ No newline at end of file diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj.filters b/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj.filters deleted file mode 100644 index dd56f78e..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/game-gui.vcxproj.filters +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Res - - - Res - - - Res - - - Res - - - Res - - - Res - - - Res - - - - - {c8d4d732-dcf8-4466-ad8e-3f15ab6fe204} - - - {22663e12-dd09-49e8-b222-67a2f17d770d} - - - - - Res - - - - - QP - - - QP - - - QP - - - \ No newline at end of file diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/main.c b/examples/arm-cm/game_efm32-slstk3401a/win32/main.c deleted file mode 100644 index e645385e..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/main.c +++ /dev/null @@ -1,126 +0,0 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example for Windows -* Last updated for version 6.3. -* Last updated on 2018-06-23 -* -* 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://www.state-machine.com -* mailto:info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "game.h" - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main() { - static QEvt const *missileQueueSto[2*WIN_FUDGE_FACTOR]; - static QEvt const *shipQueueSto[3*WIN_FUDGE_FACTOR]; - static QEvt const *tunnelQueueSto[(GAME_MINES_MAX + 5)*WIN_FUDGE_FACTOR]; - static QF_MPOOL_EL(QEvt) smlPoolSto[10*WIN_FUDGE_FACTOR]; - static QF_MPOOL_EL(ObjectImageEvt) - medPoolSto[(2*GAME_MINES_MAX + 10)*WIN_FUDGE_FACTOR]; - - static QSubscrList subscrSto[MAX_PUB_SIG]; - - /* explicitly invoke the active objects' ctors... */ - Missile_ctor(); - Ship_ctor(); - Tunnel_ctor(); - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* init publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize the event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - QF_poolInit(medPoolSto, sizeof(medPoolSto), sizeof(medPoolSto[0])); - - /* object dictionaries for AOs... */ - QS_OBJ_DICTIONARY(AO_Missile); - QS_OBJ_DICTIONARY(AO_Ship); - QS_OBJ_DICTIONARY(AO_Tunnel); - - /* object dictionaries for event queues... */ - QS_OBJ_DICTIONARY(missileQueueSto); - QS_OBJ_DICTIONARY(shipQueueSto); - QS_OBJ_DICTIONARY(tunnelQueueSto); - - /* object dictionaries for event pools... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(medPoolSto); - - /* signal dictionaries for globally published events... */ - QS_SIG_DICTIONARY(TIME_TICK_SIG, (void *)0); - QS_SIG_DICTIONARY(PLAYER_TRIGGER_SIG, (void *)0); - QS_SIG_DICTIONARY(PLAYER_QUIT_SIG, (void *)0); - QS_SIG_DICTIONARY(GAME_OVER_SIG, (void *)0); - - /* start the active objects... */ - QACTIVE_START(AO_Tunnel, - 1U, /* QP priority */ - tunnelQueueSto, Q_DIM(tunnelQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ - QACTIVE_START(AO_Ship, - 2U, /* QP priority */ - shipQueueSto, Q_DIM(shipQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ - QACTIVE_START(AO_Missile, - 3U, /* QP priority */ - missileQueueSto, Q_DIM(missileQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32/resource.h b/examples/arm-cm/game_efm32-slstk3401a/win32/resource.h deleted file mode 100644 index f0325343..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32/resource.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef IDC_STATIC -#define IDC_STATIC (-1) -#endif - -#define IDD_APPLICATION 101 -#define IDC_BACKGROUND 110 -#define IDC_LCD 111 -#define IDC_LED0 112 -#define IDC_LED1 113 -#define IDC_USER0 114 -#define IDC_USER1 115 -#define IDB_BOARD 120 -#define IDB_BTN_UP 137 -#define IDB_BTN_DWN 138 -#define IDB_LCD 142 -#define IDB_LED_OFF 144 -#define IDB_LED_ON 145 -#define IDB_SEG 146 -#define IDB_SEG0 150 -#define IDB_SEG1 151 -#define IDB_SEG2 152 -#define IDB_SEG3 153 -#define IDB_SEG4 154 -#define IDB_SEG5 155 -#define IDB_SEG6 156 -#define IDB_SEG7 157 -#define IDB_SEG8 158 -#define IDB_SEG9 159 -#define IDC_SEG0 1020 -#define IDC_SEG1 1021 -#define IDC_SEG2 1022 -#define IDC_SEG3 1023 -#define IDS_APP_TITLE 40000 diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qk/ti/.project b/examples/arm-cr/blinky_launchxl2-tms57012/qk/ti/.project index 222de778..d2588096 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qk/ti/.project +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qk/ti/.project @@ -39,7 +39,7 @@ QS 2 - PARENT-5-PROJECT_LOC/src/qs + PARENT-5-PROJECT_LOC/src/qs blinky.c diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c b/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c index d02ab7a1..84737976 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c @@ -49,15 +49,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c b/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c index d02ab7a1..84737976 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c @@ -49,15 +49,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/arm7-9/dpp_at91sam7s-ek/main.c b/examples/arm7-9/dpp_at91sam7s-ek/main.c index 623cd2c0..1b71e023 100644 --- a/examples/arm7-9/dpp_at91sam7s-ek/main.c +++ b/examples/arm7-9/dpp_at91sam7s-ek/main.c @@ -49,15 +49,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/embos/arm-cm/dpp_stm32f429-discovery/main.c b/examples/embos/arm-cm/dpp_stm32f429-discovery/main.c index da4d73e8..777f4625 100644 --- a/examples/embos/arm-cm/dpp_stm32f429-discovery/main.c +++ b/examples/embos/arm-cm/dpp_stm32f429-discovery/main.c @@ -53,15 +53,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* init publish-subscribe */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/emwin/demo_no_wm/bsp.c b/examples/emwin/demo_no_wm/bsp.c index 443d808d..3edadab8 100644 --- a/examples/emwin/demo_no_wm/bsp.c +++ b/examples/emwin/demo_no_wm/bsp.c @@ -1,11 +1,11 @@ /***************************************************************************** * Product: BSP for emWin/uC/GUI, Win32 simulation -* Last updated for version 6.2.0 -* Last updated on 2018-03-18 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -134,7 +134,7 @@ void BSP_init(void) { } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ } /*..........................................................................*/ void QF_onCleanup(void) { diff --git a/examples/emwin/demo_with_wm/bsp.c b/examples/emwin/demo_with_wm/bsp.c index 7b299639..3edadab8 100644 --- a/examples/emwin/demo_with_wm/bsp.c +++ b/examples/emwin/demo_with_wm/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: BSP for emWin/uC/GUI, Win32 simulation -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-16 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-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 @@ -134,7 +134,7 @@ void BSP_init(void) { } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ } /*..........................................................................*/ void QF_onCleanup(void) { diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c index f86ac9ff..3f15d3b7 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c @@ -100,7 +100,23 @@ static uint32_t l_rnd; // random seed #endif /* ISRs used in this project ===============================================*/ -/* NOTE: only the "FromISR" API variants are allowed in the ISRs! */ + +/* NOTE: this ISR is for testing of the various preemption scenarios +* by triggering the GPIOPortA interrupt from the debugger. You achieve +* this by writing 0 to the SWTRIG register at 0xE000,EF00. +* +* Code Composer Studio: From the CCS debugger you need open the register +* window and select NVIC registers from the drop-down list. You scroll to +* the NVIC_SW_TRIG register, which denotes the Software Trigger Interrupt +* Register in the NVIC. To trigger the GPIOA interrupt you need to write +* 0x00 to the NVIC_SW_TRIG by clicking on this field, entering the value, +* and pressing the Enter key. +* +* IAR EWARM: From the C-Spy debugger you need to open Registers view and +* select the "Other Systems Register" group. From there, you need to write +* 0 to the STIR write-only register and press enter. +*/ +/* NOTE: only the "FromISR" FreeRTOS API variants are allowed in the ISRs! */ void GPIOPortA_IRQHandler(void); /* prototype */ void GPIOPortA_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp index 9b4ea71e..ebfdc843 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp @@ -11,7 +11,7 @@ General 3 - 28 + 30 1 1 + + @@ -359,7 +367,7 @@ @@ -2058,7 +2074,7 @@ General 3 - 28 + 30 1 1 + + diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c index 5ec12aeb..d1352aec 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -66,15 +66,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c b/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c index a18348ee..73f56f27 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c @@ -66,15 +66,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); diff --git a/examples/freertos/arm-cm/dpp_stm32f746g-discovery/main.c b/examples/freertos/arm-cm/dpp_stm32f746g-discovery/main.c index a18348ee..73f56f27 100644 --- a/examples/freertos/arm-cm/dpp_stm32f746g-discovery/main.c +++ b/examples/freertos/arm-cm/dpp_stm32f746g-discovery/main.c @@ -66,15 +66,6 @@ int main() { */ BSP_init(); - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* start the active objects... */ for (n = 0U; n < N_PHILO; ++n) { QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); diff --git a/examples/msp430/dpp_msp-exp430g2/main.c b/examples/msp430/dpp_msp-exp430g2/main.c index 4d749c77..1b71e023 100644 --- a/examples/msp430/dpp_msp-exp430g2/main.c +++ b/examples/msp430/dpp_msp-exp430g2/main.c @@ -49,15 +49,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - //QS_OBJ_DICTIONARY(philoQueueSto[2]); - //QS_OBJ_DICTIONARY(philoQueueSto[3]); - //QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/posix-qv/dpp/Makefile b/examples/posix-qv/dpp/Makefile deleted file mode 100644 index 60cd35d5..00000000 --- a/examples/posix-qv/dpp/Makefile +++ /dev/null @@ -1,242 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, DPP console, POSIX-QV target, GNU compiler -# Last updated for version 6.2.0 -# Last updated on 2018-04-05 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := dpp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix-qv - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -MKDIR := mkdir -p -RM := rm -f - -#----------------------------------------------------------------------------- -# build options for various configurations -# -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -CPPFLAGS = -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -C_SRCS += $(QS_SRCS) - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lpthread - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/* - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - diff --git a/examples/posix-qv/dpp/bsp.c b/examples/posix-qv/dpp/bsp.c deleted file mode 100644 index 69b0ca01..00000000 --- a/examples/posix-qv/dpp/bsp.c +++ /dev/null @@ -1,549 +0,0 @@ -/***************************************************************************** -* Product: DPP example, POSIX -* Last updated for version 6.3.2 -* Last updated on 2018-06-16 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2002-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 "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include -#include -#include /* for memcpy() and memset() */ -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/* Local objects -----------------------------------------------------------*/ -static struct termios l_tsav; /* structure with saved terminal attributes */ -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - static uint8_t const l_clock_tick = 0U; -#endif - -/* BSP functions ===========================================================*/ -void BSP_init(int argc, char **argv) { - -#ifndef Q_SPY - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -#endif - - printf("Dining Philosophers Problem example" - "\nQP %s\n" - "Press p to pause\n" - "Press s to serve\n" - "Press ESC to quit...\n", - QP_versionStr); - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); - - /* setup the QS filters... */ - QS_FILTER_ON(QS_SM_RECORDS); // state machine records - QS_FILTER_ON(QS_UA_RECORDS); // all usedr records - //QS_FILTER_ON(QS_MUTEX_LOCK); - //QS_FILTER_ON(QS_MUTEX_UNLOCK); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; - QF_stop(); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - printf("Philosopher %2d is %s\n", (int)n, stat); - - QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - printf("Paused is %s\n", paused ? "ON" : "OFF"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3*7*11*13*23); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - struct termios tio; /* modified terminal attributes */ - - tcgetattr(0, &l_tsav); /* save the current terminal attributes */ - tcgetattr(0, &tio); /* obtain the current terminal attributes */ - tio.c_lflag &= ~(ICANON | ECHO); /* disable the canonical mode & echo */ - tcsetattr(0, TCSANOW, &tio); /* set the new attributes */ - - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* the desired tick rate/prio */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); - tcsetattr(0, TCSANOW, &l_tsav);/* restore the saved terminal attributes */ - QS_EXIT(); /* perfomr the QS cleanup */ -} -/*..........................................................................*/ -void QF_onClockTick(void) { - struct timeval timeout = { 0, 0 }; /* timeout for select() */ - fd_set con; /* FD set representing the console */ - - QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - FD_ZERO(&con); - FD_SET(0, &con); - /* check if a console input is available, returns immediately */ - if (0 != select(1, &con, 0, 0, &timeout)) { /* any descriptor set? */ - char ch; - read(0, &ch, 1); - if (ch == '\33') { /* ESC pressed? */ - BSP_terminate(0); - } - else if (ch == 'p') { - QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - } - else if (ch == 's') { - QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - } - } -} -/*..........................................................................*/ -void Q_onAssert(char const *module, int loc) { - /* - * NOTE: add here your application-specific error handling - */ - printf("Assertion failed in %s:%d", module, loc); - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - exit(-1); -} - -//============================================================================ -#ifdef Q_SPY - -/* -* NOTE: -* The QS target-resident component is implemented in two different ways: -* 1. Output to the TCP/IP socket, which requires a separate QSPY host -* application running; or -* 2. Direct linking with the QSPY host application to perform direct output -* to the console from the running application. (This option requires -* the QSPY source code, which is part of the QTools collection). -* -* The two options are selected by the following QS_IMPL_OPTION macro. -* Please set the value of this macro to either 1 or 2: -*/ -#define QS_IMPL_OPTION 1 - -/*--------------------------------------------------------------------------*/ -#if (QS_IMPL_OPTION == 1) - -/* -* 1. Output to the TCP/IP socket, which requires a separate QSPY host -* application running. This option does not link to the QSPY code. -*/ -#include -#include -#include -#include -#include -#include - -#define QS_TX_SIZE (4*1024) -#define QS_RX_SIZE 1024 -#define QS_IMEOUT_MS 100 -#define INVALID_SOCKET -1 - -/* local variables .........................................................*/ -static void *idleThread(void *par); // the expected P-Thread signature -static int l_sock = INVALID_SOCKET; -static uint8_t l_running; - -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel - static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel - char hostName[64]; - char const *src; - char *dst; - - uint16_t port_local = 51234; /* default local port */ - uint16_t port_remote = 6601; /* default QSPY server port */ - int sockopt_bool; - struct sockaddr_in sa_local; - struct sockaddr_in sa_remote; - struct hostent *host; - - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - src = (arg != (void const *)0) - ? (char const *)arg - : "localhost"; - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName)])) - { - *dst++ = *src++; - } - *dst = '\0'; - if (*src == ':') { - port_remote = (uint16_t)strtoul(src + 1, NULL, 10); - } - - printf(" Connecting to QSPY on Host=%s:%d...\n", - hostName, port_remote); - - l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ - if (l_sock == INVALID_SOCKET){ - printf(" ERROR cannot create client socket, errno=%d\n", - errno); - goto error; - } - - /* configure the socket */ - sockopt_bool = 1; - setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, - &sockopt_bool, sizeof(sockopt_bool)); - - sockopt_bool = 0; - setsockopt(l_sock, SOL_SOCKET, SO_LINGER, - &sockopt_bool, sizeof(sockopt_bool)); - - /* local address:port */ - memset(&sa_local, 0, sizeof(sa_local)); - sa_local.sin_family = AF_INET; - sa_local.sin_port = htons(port_local); - host = gethostbyname(""); /* local host */ - //sa_local.sin_addr.s_addr = inet_addr( - // inet_ntoa(*(struct in_addr *)*host->h_addr_list)); - //if (bind(l_sock, &sa_local, sizeof(sa_local)) == -1) { - // printf(" Cannot bind to the local port Err=0x%08X\n", - // WSAGetLastError()); - // /* no error */ - //} - - /* remote hostName:port (QSPY server socket) */ - host = gethostbyname(hostName); - if (host == NULL) { - printf(" ERROR cannot resolve host Name=%s:%d,errno=%d\n", - hostName, port_remote, errno); - goto error; - } - memset(&sa_remote, 0, sizeof(sa_remote)); - sa_remote.sin_family = AF_INET; - memcpy(&sa_remote.sin_addr, host->h_addr, host->h_length); - sa_remote.sin_port = htons(port_remote); - - /* try to connect to the QSPY server */ - if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) - == -1) - { - printf(" ERROR cannot connect to QSPY on Host=" - "%s:%d,errno=%d\n", hostName, port_remote, errno); - goto error; - } - - printf(" Connected to QSPY on Host=%s:%d\n", - hostName, port_remote); - - pthread_attr_t attr; - struct sched_param param; - pthread_t idle; - - // SCHED_FIFO corresponds to real-time preemptive priority-based - // scheduler. - // NOTE: This scheduling policy requires the superuser priviledges - - pthread_attr_init(&attr); - pthread_attr_setschedpolicy(&attr, SCHED_FIFO); - param.sched_priority = sched_get_priority_min(SCHED_FIFO); - - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - if (pthread_create(&idle, &attr, &idleThread, 0) != 0) { - // Creating the p-thread with the SCHED_FIFO policy failed. - // Most probably this application has no superuser privileges, - // so we just fall back to the default SCHED_OTHER policy - // and priority 0. - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - param.sched_priority = 0; - pthread_attr_setschedparam(&attr, ¶m); - if (pthread_create(&idle, &attr, &idleThread, 0) == 0) { - return false; - } - } - pthread_attr_destroy(&attr); - - return (uint8_t)1; // success - -error: - return (uint8_t)0; // failure -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - if (l_sock != INVALID_SOCKET) { - close(l_sock); - l_sock = INVALID_SOCKET; - } - //printf(" Disconnected from QSPY via TCP/IP\n"); -} -/*..........................................................................*/ -void QS_onFlush(void) { - if (l_sock != INVALID_SOCKET) { // socket initialized? - uint16_t nBytes = QS_TX_SIZE; - uint8_t const *data; - while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - send(l_sock, (char const *)data, nBytes, 0); - nBytes = QS_TX_SIZE; - } - } -} -/*..........................................................................*/ -static void *idleThread(void *par) { // the expected P-Thread signature - fd_set readSet; - FD_ZERO(&readSet); - - (void)par; /* unused parameter */ - l_running = (uint8_t)1; - while (l_running) { - static struct timeval timeout = { - (long)0, (long)(QS_IMEOUT_MS * 1000) - }; - int nrec; - uint16_t nBytes; - uint8_t const *block; - - FD_SET(l_sock, &readSet); /* the socket */ - - /* selective, timed blocking on the TCP/IP socket... */ - timeout.tv_usec = (long)(QS_IMEOUT_MS * 1000); - nrec = select(l_sock + 1, &readSet, - (fd_set *)0, (fd_set *)0, &timeout); - if (nrec < 0) { - printf(" ERROR select() errno=%d\n", errno); - QS_onCleanup(); - exit(-2); - } - else if (nrec > 0) { - if (FD_ISSET(l_sock, &readSet)) { /* socket ready to read? */ - uint8_t buf[QS_RX_SIZE]; - int status = recv(l_sock, (char *)buf, (int)sizeof(buf), 0); - while (status > 0) { /* any data received? */ - uint8_t *pb; - int i = (int)QS_rxGetNfree(); - if (i > status) { - i = status; - } - status -= i; - /* reorder the received bytes into QS-RX buffer */ - for (pb = &buf[0]; i > 0; --i, ++pb) { - QS_RX_PUT(*pb); - } - QS_rxParse(); /* parse all n-bytes of data */ - } - } - } - - nBytes = QS_TX_SIZE; - //QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - //QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - } - } - - return 0; // return success -} - -/*--------------------------------------------------------------------------*/ -#elif (QS_IMPL_OPTION == 2) - -/* -* 2. Direct linking with the QSPY host application to perform direct output -* to the console from the running application. (This option requires -* the QSPY source code, which is part of the QTools collection). -*/ -#include "qspy.h" - -/*..........................................................................*/ -static void *idleThread(void *par); // the expected P-Thread signature -static uint8_t l_running; - -/*..........................................................................*/ -bool QS_onStartup(void const */*arg*/) { - static uint8_t qsBuf[4*1024]; // 4K buffer for Quantum Spy - initBuf(qsBuf, sizeof(qsBuf)); - - QSPY_config(QP_VERSION, // version - QS_OBJ_PTR_SIZE, // objPtrSize - QS_FUN_PTR_SIZE, // funPtrSize - QS_TIME_SIZE, // tstampSize - Q_SIGNAL_SIZE, // sigSize, - QF_EVENT_SIZ_SIZE, // evtSize - QF_EQUEUE_CTR_SIZE, // queueCtrSize - QF_MPOOL_CTR_SIZE, // poolCtrSize - QF_MPOOL_SIZ_SIZE, // poolBlkSize - QF_TIMEEVT_CTR_SIZE,// tevtCtrSize - (void *)0, // matFile, - (void *)0, - (QSPY_CustParseFun)0); // customized parser function - - pthread_attr_t attr; - struct sched_param param; - pthread_t idle; - - // SCHED_FIFO corresponds to real-time preemptive priority-based - // scheduler. - // NOTE: This scheduling policy requires the superuser priviledges - - pthread_attr_init(&attr); - pthread_attr_setschedpolicy(&attr, SCHED_FIFO); - param.sched_priority = sched_get_priority_min(SCHED_FIFO); - - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - if (pthread_create(&idle, &attr, &idleThread, 0) != 0) { - // Creating the p-thread with the SCHED_FIFO policy failed. - // Most probably this application has no superuser privileges, - // so we just fall back to the default SCHED_OTHER policy - // and priority 0. - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - param.sched_priority = 0; - pthread_attr_setschedparam(&attr, ¶m); - if (pthread_create(&idle, &attr, &idleThread, 0) == 0) { - return false; - } - } - pthread_attr_destroy(&attr); - - return true; -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - QSPY_stop(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes = 1024U; - uint8_t const *block; - while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QSPY_parse(block, nBytes); - nBytes = 1024U; - } -} -/*..........................................................................*/ -void QSPY_onPrintLn(void) { - fputs(QSPY_line, stdout); - fputc('\n', stdout); -} -/*..........................................................................*/ -static void *idleThread(void *par) { // the expected P-Thread signature - (void)par; - - l_running = (uint8_t)1; - while (l_running) { - uint16_t nBytes = 256U; - uint8_t const *block; - struct timeval timeout = { 0, 10000 }; // timeout for select() - - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - QSPY_parse(block, nBytes); - } - select(0, 0, 0, 0, &timeout); // sleep for a while - } - return 0; // return success -} - -#else -#error Incorrect value of the QS_IMPL_OPTION macro -#endif // QS_IMPL_OPTION - -//............................................................................ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); // see NOTE01 -} -//............................................................................ -void QS_onReset(void) { - QS_onCleanup(); - exit(0); -} -//............................................................................ -//! callback function to execute a user command (to be implemented in BSP) -void QS_onCommand(uint8_t cmdId, uint32_t param1, - uint32_t param2, uint32_t param3) -{ - (void)cmdId; // unused parameter - (void)param1; // unused parameter - (void)param2; // unused parameter - (void)param3; // unused parameter - //TBD -} - -//**************************************************************************** -// NOTE01: -// clock() is the most portable facility, but might not provide the desired -// granularity. Other, less-portable alternatives are clock_gettime(), -// rdtsc(), or gettimeofday(). -// - -#endif // Q_SPY -/*--------------------------------------------------------------------------*/ diff --git a/examples/posix-qv/dpp/bsp.h b/examples/posix-qv/dpp/bsp.h deleted file mode 100644 index b30214b0..00000000 --- a/examples/posix-qv/dpp/bsp.h +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.2.0 -* Last updated on 2016-11-30 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2002-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 -*****************************************************************************/ -#ifndef bsp_h -#define bsp_h - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char **argv); -void BSP_displayPhilStat(uint8_t n, char const *stat); -void BSP_displayPaused(uint8_t paused); -void BSP_terminate(int16_t result); - -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ - -#endif /* bsp_h */ diff --git a/examples/posix-qv/dpp/dpp.h b/examples/posix-qv/dpp/dpp.h deleted file mode 100644 index bf90cf75..00000000 --- a/examples/posix-qv/dpp/dpp.h +++ /dev/null @@ -1,72 +0,0 @@ -/*$file${.::dpp.h} #########################################################*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM tool (https://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 - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -/*$declare${Events::TableEvt} ##############################################*/ -/*${Events::TableEvt} ......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t philoNum; -} TableEvt; -/*$enddecl${Events::TableEvt} ##############################################*/ - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -/*$declare${AOs::Philo_ctor} ###############################################*/ -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ###############################################*/ -/*$declare${AOs::AO_Philo[N_PHILO]} ########################################*/ -extern QMActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ########################################*/ - -/*$declare${AOs::Table_ctor} ###############################################*/ -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ###############################################*/ -/*$declare${AOs::AO_Table} #################################################*/ -extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} #################################################*/ - -#ifdef qxk_h - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* qxk_h */ - -#endif /* dpp_h */ \ No newline at end of file diff --git a/examples/posix-qv/dpp/dpp.qm b/examples/posix-qv/dpp/dpp.qm deleted file mode 100644 index 1ca304b8..00000000 --- a/examples/posix-qv/dpp/dpp.qm +++ /dev/null @@ -1,445 +0,0 @@ - - - Dining Philosopher Problem example -NOTE: Requries QP5. - - - - - - - - - - - - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)e; /* suppress the compiler warning about unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - /* 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); -QACTIVE_POST(AO_Table, &pe->super, 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)); - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QF_PUBLISH(&pe->super, me); - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - - uint8_t n; -(void)e; /* suppress the compiler warning about unused parameter */ - -QS_OBJ_DICTIONARY(&l_table); -QS_FUN_DICTIONARY(&QHsm_top); -QS_FUN_DICTIONARY(&Table_initial); -QS_FUN_DICTIONARY(&Table_active); -QS_FUN_DICTIONARY(&Table_serving); -QS_FUN_DICTIONARY(&Table_paused); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - - - - Q_ERROR(); - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QF_PUBLISH(&te->super, me); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QF_PUBLISH(&pe->super, me); -BSP_displayPhilStat(n, "eating "); - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); -} - - - - - - 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->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - #ifndef dpp_h -#define dpp_h - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -$declare(Events::TableEvt) - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) - -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) - -#ifdef qxk_h - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* qxk_h */ - -#endif /* dpp_h */ - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) - - - diff --git a/examples/posix-qv/dpp/main.c b/examples/posix-qv/dpp/main.c deleted file mode 100644 index 897e36c4..00000000 --- a/examples/posix-qv/dpp/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-10 -* -* 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://www.state-machine.com -* mailto:info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/posix-qv/dpp/philo.c b/examples/posix-qv/dpp/philo.c deleted file mode 100644 index ae022b4c..00000000 --- a/examples/posix-qv/dpp/philo.c +++ /dev/null @@ -1,229 +0,0 @@ -/*$file${.::philo.c} #######################################################*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM tool (https://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.c} ####################################################*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} ####################################################*/ -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - QTimeEvt timeEvt; -} Philo; - -/* protected: */ -static QState Philo_initial(Philo * const me, QEvt const * const e); -static QState Philo_thinking(Philo * const me, QEvt const * const e); -static QState Philo_hungry(Philo * const me, QEvt const * const e); -static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ####################################################*/ - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo_ctor} ################################################*/ -/* Check for the minimum required QP version */ -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 6.0.1 or higher required -#endif -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ################################################*/ -/*$define${AOs::Philo} #####################################################*/ -/*${AOs::Philo} ............................................................*/ -/*${AOs::Philo::SM} ........................................................*/ -static QState Philo_initial(Philo * const me, QEvt const * const e) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)e; /* suppress the compiler warning about unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - - QActive_subscribe(&me->super, EAT_SIG); - QActive_subscribe(&me->super, TEST_SIG); - return Q_TRAN(&Philo_thinking); -} -/*${AOs::Philo::SM::thinking} ..............................................*/ -static QState Philo_thinking(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_hungry); - break; - } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Philo::SM::hungry} ................................................*/ -static QState Philo_hungry(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ - case Q_ENTRY_SIG: { - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::hungry::EAT} */ - case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { - status_ = Q_TRAN(&Philo_eating); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /*${AOs::Philo::SM::hungry::DONE} */ - case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Philo::SM::eating} ................................................*/ -static QState Philo_eating(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::eating} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::eating} */ - case Q_EXIT_SIG: { - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); - QF_PUBLISH(&pe->super, me); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::eating::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_thinking); - break; - } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${AOs::Philo} #####################################################*/ diff --git a/examples/posix-qv/dpp/table.c b/examples/posix-qv/dpp/table.c deleted file mode 100644 index 13ff9e5b..00000000 --- a/examples/posix-qv/dpp/table.c +++ /dev/null @@ -1,300 +0,0 @@ -/*$file${.::table.c} #######################################################*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM tool (https://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.c} ####################################################*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} ####################################################*/ -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; -} Table; - -/* protected: */ -static QState Table_initial(Table * const me, QEvt const * const e); -static QState Table_active(Table * const me, QEvt const * const e); -static QState Table_serving(Table * const me, QEvt const * const e); -static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ####################################################*/ - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -/*$define${AOs::Table_ctor} ################################################*/ -/* Check for the minimum required QP version */ -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 6.0.1 or higher required -#endif -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - } -} -/*$enddef${AOs::Table_ctor} ################################################*/ -/*$define${AOs::Table} #####################################################*/ -/*${AOs::Table} ............................................................*/ -/*${AOs::Table::SM} ........................................................*/ -static QState Table_initial(Table * const me, QEvt const * const e) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)e; /* suppress the compiler warning about unused parameter */ - - QS_OBJ_DICTIONARY(&l_table); - QS_FUN_DICTIONARY(&QHsm_top); - QS_FUN_DICTIONARY(&Table_initial); - QS_FUN_DICTIONARY(&Table_active); - QS_FUN_DICTIONARY(&Table_serving); - QS_FUN_DICTIONARY(&Table_paused); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - - QActive_subscribe(&me->super, DONE_SIG); - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); - } - return Q_TRAN(&Table_serving); -} -/*${AOs::Table::SM::active} ................................................*/ -static QState Table_active(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Table::SM::active::serving} .......................................*/ -static QState Table_serving(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ - case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QF_PUBLISH(&te->super, me); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } - } - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ - if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; - me->fork[m] = USED; - me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(n, "eating "); - status_ = Q_HANDLED(); - } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ - else { - me->isHungry[n] = 1U; - status_ = Q_HANDLED(); - } - break; - } - /*${AOs::Table::SM::active::serving::DONE} */ - case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ - - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); - } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); - } - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::PAUSE} */ - case PAUSE_SIG: { - status_ = Q_TRAN(&Table_paused); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} -/*${AOs::Table::SM::active::paused} ........................................*/ -static QState Table_paused(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ - case Q_ENTRY_SIG: { - BSP_displayPaused(1U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused} */ - case Q_EXIT_SIG: { - BSP_displayPaused(0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused::SERVE} */ - case SERVE_SIG: { - status_ = Q_TRAN(&Table_serving); - break; - } - /*${AOs::Table::SM::active::paused::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused::DONE} */ - case DONE_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} -/*$enddef${AOs::Table} #####################################################*/ diff --git a/examples/posix/README.url b/examples/posix/README.url deleted file mode 100644 index f9b4a10c..00000000 --- a/examples/posix/README.url +++ /dev/null @@ -1,3 +0,0 @@ -[InternetShortcut] -URL=http://www.state-machine.com/qpc/exa_posix.html -IconFile=http://www.state-machine.com/qp.ico diff --git a/examples/posix/blinky/Makefile b/examples/posix/blinky/Makefile deleted file mode 100644 index 83aa6e02..00000000 --- a/examples/posix/blinky/Makefile +++ /dev/null @@ -1,239 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Blinky console, POSIX target, GNU compiler -# Last updated for version 6.3.3a -# Last updated on 2018-07-27 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := blinky - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - blinky.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -MKDIR := mkdir -p -RM := rm -f - -#----------------------------------------------------------------------------- -# build options for various configurations -# -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -CPPFLAGS = -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -C_SRCS += $(QS_SRCS) - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lpthread - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/* - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - diff --git a/examples/posix/blinky/blinky.c b/examples/posix/blinky/blinky.c deleted file mode 100644 index 9a49158c..00000000 --- a/examples/posix/blinky/blinky.c +++ /dev/null @@ -1,152 +0,0 @@ -/*$file${.::blinky.c} ######################################################*/ -/* -* Model: blinky.qm -* File: ${.::blinky.c} -* -* 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${.::blinky.c} ###################################################*/ -#include "qpc.h" -#include -#include /* for exit() */ - -enum { BSP_TICKS_PER_SEC = 100 }; - -void BSP_ledOff(void) { - printf("LED OFF\n"); -} -void BSP_ledOn(void) { - printf("LED ON\n"); -} -void Q_onAssert(char const * const module, int loc) { - fprintf(stderr, "Assertion failed in %s:%d", module, loc); - exit(-1); -} -void QF_onStartup(void) {} -void QF_onCleanup(void) {} -void QF_onClockTick(void) { - QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */ -} - -enum BlinkySignals { - TIMEOUT_SIG = Q_USER_SIG, - MAX_SIG -}; - -//*============== ask QM to declare the Blinky class ================*/ -/*$declare${AOs::Blinky} ###################################################*/ -/*${AOs::Blinky} ...........................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - QTimeEvt timeEvt; -} Blinky; - -/* protected: */ -static QState Blinky_initial(Blinky * const me, QEvt const * const e); -static QState Blinky_off(Blinky * const me, QEvt const * const e); -static QState Blinky_on(Blinky * const me, QEvt const * const e); -/*$enddecl${AOs::Blinky} ###################################################*/ - -static Blinky l_blinky; -QActive * const AO_Blinky = &l_blinky.super; - -static void Blinky_ctor(void) { - Blinky *me = (Blinky *)AO_Blinky; - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - -int main() { - /* statically allocate event queue buffer for the Blinky AO */ - static QEvt const *blinky_queueSto[10]; - - QF_init(); /* initialize the framework */ - - Blinky_ctor(); /* explicitly call the "constructor" */ - QACTIVE_START(AO_Blinky, - 1U, /* priority */ - blinky_queueSto, Q_DIM(blinky_queueSto), - (void *)0, 0U, /* no stack */ - (QEvt *)0); /* no initialization event */ - return QF_run(); /* run the QF application */ -} - -/*================ ask QM to define the Blinky class ================*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 6.3.0 or higher required -#endif - -/*$define${AOs::Blinky} ####################################################*/ -/*${AOs::Blinky} ...........................................................*/ -/*${AOs::Blinky::SM} .......................................................*/ -static QState Blinky_initial(Blinky * const me, QEvt const * const e) { - /*${AOs::Blinky::SM::initial} */ - (void)e; /* unused parameter */ - QTimeEvt_armX(&me->timeEvt, - BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); - - QS_FUN_DICTIONARY(&Blinky_off); - QS_FUN_DICTIONARY(&Blinky_on); - - return Q_TRAN(&Blinky_off); -} -/*${AOs::Blinky::SM::off} ..................................................*/ -static QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Blinky::SM::off} */ - case Q_ENTRY_SIG: { - BSP_ledOff(); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Blinky::SM::off::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Blinky_on); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Blinky::SM::on} ...................................................*/ -static QState Blinky_on(Blinky * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Blinky::SM::on} */ - case Q_ENTRY_SIG: { - BSP_ledOn(); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Blinky::SM::on::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Blinky_off); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${AOs::Blinky} ####################################################*/ - diff --git a/examples/posix/blinky/blinky.qm b/examples/posix/blinky/blinky.qm deleted file mode 100644 index ed23b0ab..00000000 --- a/examples/posix/blinky/blinky.qm +++ /dev/null @@ -1,105 +0,0 @@ - - - Blinky model - - - - - - - (void)e; /* unused parameter */ -QTimeEvt_armX(&me->timeEvt, -BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); - - - - - - BSP_ledOff(); - - - - - - - - - - - BSP_ledOn(); - - - - - - - - - - - - - - - - #include "qpc.h" -#include <stdio.h> -#include <stdlib.h> /* for exit() */ - -enum { BSP_TICKS_PER_SEC = 100 }; - -void BSP_ledOff(void) { - printf("LED OFF\n"); -} -void BSP_ledOn(void) { - printf("LED ON\n"); -} -void Q_onAssert(char const * const module, int loc) { - fprintf(stderr, "Assertion failed in %s:%d", module, loc); - exit(-1); -} -void QF_onStartup(void) {} -void QF_onCleanup(void) {} -void QF_onClockTick(void) { - QF_TICK_X(0U, (void *)0); /* perform the QF clock tick processing */ -} - -enum BlinkySignals { - TIMEOUT_SIG = Q_USER_SIG, - MAX_SIG -}; - -//*============== ask QM to declare the Blinky class ================*/ -$declare${AOs::Blinky} - -static Blinky l_blinky; -QActive * const AO_Blinky = &l_blinky.super; - -static void Blinky_ctor(void) { - Blinky *me = (Blinky *)AO_Blinky; - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - -int main() { - /* statically allocate event queue buffer for the Blinky AO */ - static QEvt const *blinky_queueSto[10]; - - QF_init(); /* initialize the framework */ - - Blinky_ctor(); /* explicitly call the "constructor" */ - QACTIVE_START(AO_Blinky, - 1U, /* priority */ - blinky_queueSto, Q_DIM(blinky_queueSto), - (void *)0, 0U, /* no stack */ - (QEvt *)0); /* no initialization event */ - return QF_run(); /* run the QF application */ -} - -/*================ ask QM to define the Blinky class ================*/ -$define${AOs::Blinky} - - - - - diff --git a/examples/posix/dpp/Makefile b/examples/posix/dpp/Makefile deleted file mode 100644 index fcbabbcb..00000000 --- a/examples/posix/dpp/Makefile +++ /dev/null @@ -1,242 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, DPP console, POSIX target, GNU compiler -# Last updated for version 6.2.0 -# Last updated on 2018-03-16 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := dpp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -MKDIR := mkdir -p -RM := rm -f - -#----------------------------------------------------------------------------- -# build options for various configurations -# -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -CPPFLAGS = -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -C_SRCS += $(QS_SRCS) - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lpthread - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/* - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - diff --git a/examples/posix/dpp/bsp.c b/examples/posix/dpp/bsp.c deleted file mode 100644 index 69b0ca01..00000000 --- a/examples/posix/dpp/bsp.c +++ /dev/null @@ -1,549 +0,0 @@ -/***************************************************************************** -* Product: DPP example, POSIX -* Last updated for version 6.3.2 -* Last updated on 2018-06-16 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2002-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 "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include -#include -#include /* for memcpy() and memset() */ -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/* Local objects -----------------------------------------------------------*/ -static struct termios l_tsav; /* structure with saved terminal attributes */ -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - static uint8_t const l_clock_tick = 0U; -#endif - -/* BSP functions ===========================================================*/ -void BSP_init(int argc, char **argv) { - -#ifndef Q_SPY - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -#endif - - printf("Dining Philosophers Problem example" - "\nQP %s\n" - "Press p to pause\n" - "Press s to serve\n" - "Press ESC to quit...\n", - QP_versionStr); - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); - - /* setup the QS filters... */ - QS_FILTER_ON(QS_SM_RECORDS); // state machine records - QS_FILTER_ON(QS_UA_RECORDS); // all usedr records - //QS_FILTER_ON(QS_MUTEX_LOCK); - //QS_FILTER_ON(QS_MUTEX_UNLOCK); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; - QF_stop(); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - printf("Philosopher %2d is %s\n", (int)n, stat); - - QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - printf("Paused is %s\n", paused ? "ON" : "OFF"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3*7*11*13*23); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - struct termios tio; /* modified terminal attributes */ - - tcgetattr(0, &l_tsav); /* save the current terminal attributes */ - tcgetattr(0, &tio); /* obtain the current terminal attributes */ - tio.c_lflag &= ~(ICANON | ECHO); /* disable the canonical mode & echo */ - tcsetattr(0, TCSANOW, &tio); /* set the new attributes */ - - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* the desired tick rate/prio */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); - tcsetattr(0, TCSANOW, &l_tsav);/* restore the saved terminal attributes */ - QS_EXIT(); /* perfomr the QS cleanup */ -} -/*..........................................................................*/ -void QF_onClockTick(void) { - struct timeval timeout = { 0, 0 }; /* timeout for select() */ - fd_set con; /* FD set representing the console */ - - QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - FD_ZERO(&con); - FD_SET(0, &con); - /* check if a console input is available, returns immediately */ - if (0 != select(1, &con, 0, 0, &timeout)) { /* any descriptor set? */ - char ch; - read(0, &ch, 1); - if (ch == '\33') { /* ESC pressed? */ - BSP_terminate(0); - } - else if (ch == 'p') { - QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - } - else if (ch == 's') { - QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - } - } -} -/*..........................................................................*/ -void Q_onAssert(char const *module, int loc) { - /* - * NOTE: add here your application-specific error handling - */ - printf("Assertion failed in %s:%d", module, loc); - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - exit(-1); -} - -//============================================================================ -#ifdef Q_SPY - -/* -* NOTE: -* The QS target-resident component is implemented in two different ways: -* 1. Output to the TCP/IP socket, which requires a separate QSPY host -* application running; or -* 2. Direct linking with the QSPY host application to perform direct output -* to the console from the running application. (This option requires -* the QSPY source code, which is part of the QTools collection). -* -* The two options are selected by the following QS_IMPL_OPTION macro. -* Please set the value of this macro to either 1 or 2: -*/ -#define QS_IMPL_OPTION 1 - -/*--------------------------------------------------------------------------*/ -#if (QS_IMPL_OPTION == 1) - -/* -* 1. Output to the TCP/IP socket, which requires a separate QSPY host -* application running. This option does not link to the QSPY code. -*/ -#include -#include -#include -#include -#include -#include - -#define QS_TX_SIZE (4*1024) -#define QS_RX_SIZE 1024 -#define QS_IMEOUT_MS 100 -#define INVALID_SOCKET -1 - -/* local variables .........................................................*/ -static void *idleThread(void *par); // the expected P-Thread signature -static int l_sock = INVALID_SOCKET; -static uint8_t l_running; - -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel - static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel - char hostName[64]; - char const *src; - char *dst; - - uint16_t port_local = 51234; /* default local port */ - uint16_t port_remote = 6601; /* default QSPY server port */ - int sockopt_bool; - struct sockaddr_in sa_local; - struct sockaddr_in sa_remote; - struct hostent *host; - - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - src = (arg != (void const *)0) - ? (char const *)arg - : "localhost"; - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName)])) - { - *dst++ = *src++; - } - *dst = '\0'; - if (*src == ':') { - port_remote = (uint16_t)strtoul(src + 1, NULL, 10); - } - - printf(" Connecting to QSPY on Host=%s:%d...\n", - hostName, port_remote); - - l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ - if (l_sock == INVALID_SOCKET){ - printf(" ERROR cannot create client socket, errno=%d\n", - errno); - goto error; - } - - /* configure the socket */ - sockopt_bool = 1; - setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, - &sockopt_bool, sizeof(sockopt_bool)); - - sockopt_bool = 0; - setsockopt(l_sock, SOL_SOCKET, SO_LINGER, - &sockopt_bool, sizeof(sockopt_bool)); - - /* local address:port */ - memset(&sa_local, 0, sizeof(sa_local)); - sa_local.sin_family = AF_INET; - sa_local.sin_port = htons(port_local); - host = gethostbyname(""); /* local host */ - //sa_local.sin_addr.s_addr = inet_addr( - // inet_ntoa(*(struct in_addr *)*host->h_addr_list)); - //if (bind(l_sock, &sa_local, sizeof(sa_local)) == -1) { - // printf(" Cannot bind to the local port Err=0x%08X\n", - // WSAGetLastError()); - // /* no error */ - //} - - /* remote hostName:port (QSPY server socket) */ - host = gethostbyname(hostName); - if (host == NULL) { - printf(" ERROR cannot resolve host Name=%s:%d,errno=%d\n", - hostName, port_remote, errno); - goto error; - } - memset(&sa_remote, 0, sizeof(sa_remote)); - sa_remote.sin_family = AF_INET; - memcpy(&sa_remote.sin_addr, host->h_addr, host->h_length); - sa_remote.sin_port = htons(port_remote); - - /* try to connect to the QSPY server */ - if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) - == -1) - { - printf(" ERROR cannot connect to QSPY on Host=" - "%s:%d,errno=%d\n", hostName, port_remote, errno); - goto error; - } - - printf(" Connected to QSPY on Host=%s:%d\n", - hostName, port_remote); - - pthread_attr_t attr; - struct sched_param param; - pthread_t idle; - - // SCHED_FIFO corresponds to real-time preemptive priority-based - // scheduler. - // NOTE: This scheduling policy requires the superuser priviledges - - pthread_attr_init(&attr); - pthread_attr_setschedpolicy(&attr, SCHED_FIFO); - param.sched_priority = sched_get_priority_min(SCHED_FIFO); - - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - if (pthread_create(&idle, &attr, &idleThread, 0) != 0) { - // Creating the p-thread with the SCHED_FIFO policy failed. - // Most probably this application has no superuser privileges, - // so we just fall back to the default SCHED_OTHER policy - // and priority 0. - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - param.sched_priority = 0; - pthread_attr_setschedparam(&attr, ¶m); - if (pthread_create(&idle, &attr, &idleThread, 0) == 0) { - return false; - } - } - pthread_attr_destroy(&attr); - - return (uint8_t)1; // success - -error: - return (uint8_t)0; // failure -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - if (l_sock != INVALID_SOCKET) { - close(l_sock); - l_sock = INVALID_SOCKET; - } - //printf(" Disconnected from QSPY via TCP/IP\n"); -} -/*..........................................................................*/ -void QS_onFlush(void) { - if (l_sock != INVALID_SOCKET) { // socket initialized? - uint16_t nBytes = QS_TX_SIZE; - uint8_t const *data; - while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - send(l_sock, (char const *)data, nBytes, 0); - nBytes = QS_TX_SIZE; - } - } -} -/*..........................................................................*/ -static void *idleThread(void *par) { // the expected P-Thread signature - fd_set readSet; - FD_ZERO(&readSet); - - (void)par; /* unused parameter */ - l_running = (uint8_t)1; - while (l_running) { - static struct timeval timeout = { - (long)0, (long)(QS_IMEOUT_MS * 1000) - }; - int nrec; - uint16_t nBytes; - uint8_t const *block; - - FD_SET(l_sock, &readSet); /* the socket */ - - /* selective, timed blocking on the TCP/IP socket... */ - timeout.tv_usec = (long)(QS_IMEOUT_MS * 1000); - nrec = select(l_sock + 1, &readSet, - (fd_set *)0, (fd_set *)0, &timeout); - if (nrec < 0) { - printf(" ERROR select() errno=%d\n", errno); - QS_onCleanup(); - exit(-2); - } - else if (nrec > 0) { - if (FD_ISSET(l_sock, &readSet)) { /* socket ready to read? */ - uint8_t buf[QS_RX_SIZE]; - int status = recv(l_sock, (char *)buf, (int)sizeof(buf), 0); - while (status > 0) { /* any data received? */ - uint8_t *pb; - int i = (int)QS_rxGetNfree(); - if (i > status) { - i = status; - } - status -= i; - /* reorder the received bytes into QS-RX buffer */ - for (pb = &buf[0]; i > 0; --i, ++pb) { - QS_RX_PUT(*pb); - } - QS_rxParse(); /* parse all n-bytes of data */ - } - } - } - - nBytes = QS_TX_SIZE; - //QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - //QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - send(l_sock, (char const *)block, nBytes, 0); - } - } - - return 0; // return success -} - -/*--------------------------------------------------------------------------*/ -#elif (QS_IMPL_OPTION == 2) - -/* -* 2. Direct linking with the QSPY host application to perform direct output -* to the console from the running application. (This option requires -* the QSPY source code, which is part of the QTools collection). -*/ -#include "qspy.h" - -/*..........................................................................*/ -static void *idleThread(void *par); // the expected P-Thread signature -static uint8_t l_running; - -/*..........................................................................*/ -bool QS_onStartup(void const */*arg*/) { - static uint8_t qsBuf[4*1024]; // 4K buffer for Quantum Spy - initBuf(qsBuf, sizeof(qsBuf)); - - QSPY_config(QP_VERSION, // version - QS_OBJ_PTR_SIZE, // objPtrSize - QS_FUN_PTR_SIZE, // funPtrSize - QS_TIME_SIZE, // tstampSize - Q_SIGNAL_SIZE, // sigSize, - QF_EVENT_SIZ_SIZE, // evtSize - QF_EQUEUE_CTR_SIZE, // queueCtrSize - QF_MPOOL_CTR_SIZE, // poolCtrSize - QF_MPOOL_SIZ_SIZE, // poolBlkSize - QF_TIMEEVT_CTR_SIZE,// tevtCtrSize - (void *)0, // matFile, - (void *)0, - (QSPY_CustParseFun)0); // customized parser function - - pthread_attr_t attr; - struct sched_param param; - pthread_t idle; - - // SCHED_FIFO corresponds to real-time preemptive priority-based - // scheduler. - // NOTE: This scheduling policy requires the superuser priviledges - - pthread_attr_init(&attr); - pthread_attr_setschedpolicy(&attr, SCHED_FIFO); - param.sched_priority = sched_get_priority_min(SCHED_FIFO); - - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - if (pthread_create(&idle, &attr, &idleThread, 0) != 0) { - // Creating the p-thread with the SCHED_FIFO policy failed. - // Most probably this application has no superuser privileges, - // so we just fall back to the default SCHED_OTHER policy - // and priority 0. - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - param.sched_priority = 0; - pthread_attr_setschedparam(&attr, ¶m); - if (pthread_create(&idle, &attr, &idleThread, 0) == 0) { - return false; - } - } - pthread_attr_destroy(&attr); - - return true; -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - QSPY_stop(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes = 1024U; - uint8_t const *block; - while ((block = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QSPY_parse(block, nBytes); - nBytes = 1024U; - } -} -/*..........................................................................*/ -void QSPY_onPrintLn(void) { - fputs(QSPY_line, stdout); - fputc('\n', stdout); -} -/*..........................................................................*/ -static void *idleThread(void *par) { // the expected P-Thread signature - (void)par; - - l_running = (uint8_t)1; - while (l_running) { - uint16_t nBytes = 256U; - uint8_t const *block; - struct timeval timeout = { 0, 10000 }; // timeout for select() - - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t *)0) { - QSPY_parse(block, nBytes); - } - select(0, 0, 0, 0, &timeout); // sleep for a while - } - return 0; // return success -} - -#else -#error Incorrect value of the QS_IMPL_OPTION macro -#endif // QS_IMPL_OPTION - -//............................................................................ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); // see NOTE01 -} -//............................................................................ -void QS_onReset(void) { - QS_onCleanup(); - exit(0); -} -//............................................................................ -//! callback function to execute a user command (to be implemented in BSP) -void QS_onCommand(uint8_t cmdId, uint32_t param1, - uint32_t param2, uint32_t param3) -{ - (void)cmdId; // unused parameter - (void)param1; // unused parameter - (void)param2; // unused parameter - (void)param3; // unused parameter - //TBD -} - -//**************************************************************************** -// NOTE01: -// clock() is the most portable facility, but might not provide the desired -// granularity. Other, less-portable alternatives are clock_gettime(), -// rdtsc(), or gettimeofday(). -// - -#endif // Q_SPY -/*--------------------------------------------------------------------------*/ diff --git a/examples/posix/dpp/bsp.h b/examples/posix/dpp/bsp.h deleted file mode 100644 index b30214b0..00000000 --- a/examples/posix/dpp/bsp.h +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.2.0 -* Last updated on 2016-11-30 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2002-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 -*****************************************************************************/ -#ifndef bsp_h -#define bsp_h - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char **argv); -void BSP_displayPhilStat(uint8_t n, char const *stat); -void BSP_displayPaused(uint8_t paused); -void BSP_terminate(int16_t result); - -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ - -#endif /* bsp_h */ diff --git a/examples/posix/dpp/dpp.h b/examples/posix/dpp/dpp.h deleted file mode 100644 index b258597c..00000000 --- a/examples/posix/dpp/dpp.h +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************** -* Model: dpp.qm -* File: ./dpp.h -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::dpp.h} ..............................................................*/ -#ifndef dpp_h -#define dpp_h - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${Events::TableEvt} ......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t philoNum; -} TableEvt; - - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); - -extern QMActive * const AO_Philo[N_PHILO]; - - -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); - -extern QActive * const AO_Table; - - -#ifdef qxk_h - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* qxk_h */ - -#endif /* dpp_h */ diff --git a/examples/posix/dpp/dpp.qm b/examples/posix/dpp/dpp.qm deleted file mode 100644 index 4cc4237f..00000000 --- a/examples/posix/dpp/dpp.qm +++ /dev/null @@ -1,445 +0,0 @@ - - - Dining Philosopher Problem example -NOTE: Requries QP5. - - - - - - - - - - - - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)e; /* suppress the compiler warning about unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - /* 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); -QACTIVE_POST(AO_Table, &pe->super, 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)); - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QF_PUBLISH(&pe->super, me); - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - - uint8_t n; -(void)e; /* suppress the compiler warning about unused parameter */ - -QS_OBJ_DICTIONARY(&l_table); -QS_FUN_DICTIONARY(&QHsm_top); -QS_FUN_DICTIONARY(&Table_initial); -QS_FUN_DICTIONARY(&Table_active); -QS_FUN_DICTIONARY(&Table_serving); -QS_FUN_DICTIONARY(&Table_paused); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - - - - Q_ERROR(); - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QF_PUBLISH(&te->super, me); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QF_PUBLISH(&pe->super, me); -BSP_displayPhilStat(n, "eating "); - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); -} - - - - - - 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->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - #ifndef dpp_h -#define dpp_h - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -$declare(Events::TableEvt) - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) - -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) - -#ifdef qxk_h - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* qxk_h */ - -#endif /* dpp_h */ - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) - - - diff --git a/examples/posix/dpp/main.c b/examples/posix/dpp/main.c deleted file mode 100644 index 897e36c4..00000000 --- a/examples/posix/dpp/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-10 -* -* 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://www.state-machine.com -* mailto:info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/posix/dpp/philo.c b/examples/posix/dpp/philo.c deleted file mode 100644 index 67c2ac69..00000000 --- a/examples/posix/dpp/philo.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************** -* Model: dpp.qm -* File: ./philo.c -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::philo.c} ............................................................*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - QTimeEvt timeEvt; -} Philo; - -/* protected: */ -static QState Philo_initial(Philo * const me, QEvt const * const e); -static QState Philo_thinking(Philo * const me, QEvt const * const e); -static QState Philo_hungry(Philo * const me, QEvt const * const e); -static QState Philo_eating(Philo * const me, QEvt const * const e); - - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*${AOs::Philo} ............................................................*/ -/*${AOs::Philo::SM} ........................................................*/ -static QState Philo_initial(Philo * const me, QEvt const * const e) { - /* ${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)e; /* suppress the compiler warning about unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - - QActive_subscribe(&me->super, EAT_SIG); - QActive_subscribe(&me->super, TEST_SIG); - return Q_TRAN(&Philo_thinking); -} -/*${AOs::Philo::SM::thinking} ..............................................*/ -static QState Philo_thinking(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Philo::SM::thinking} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::thinking} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::thinking::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_hungry); - break; - } - /* ${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::thinking::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Philo::SM::hungry} ................................................*/ -static QState Philo_hungry(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Philo::SM::hungry} */ - case Q_ENTRY_SIG: { - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::hungry::EAT} */ - case EAT_SIG: { - /* ${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { - status_ = Q_TRAN(&Philo_eating); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /* ${AOs::Philo::SM::hungry::DONE} */ - case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Philo::SM::eating} ................................................*/ -static QState Philo_eating(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Philo::SM::eating} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::eating} */ - case Q_EXIT_SIG: { - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); - QF_PUBLISH(&pe->super, me); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::eating::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_thinking); - break; - } - /* ${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - diff --git a/examples/posix/dpp/table.c b/examples/posix/dpp/table.c deleted file mode 100644 index fe8b1a84..00000000 --- a/examples/posix/dpp/table.c +++ /dev/null @@ -1,296 +0,0 @@ -/***************************************************************************** -* Model: dpp.qm -* File: ./table.c -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::table.c} ............................................................*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; -} Table; - -/* protected: */ -static QState Table_initial(Table * const me, QEvt const * const e); -static QState Table_active(Table * const me, QEvt const * const e); -static QState Table_serving(Table * const me, QEvt const * const e); -static QState Table_paused(Table * const me, QEvt const * const e); - - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - } -} -/*${AOs::Table} ............................................................*/ -/*${AOs::Table::SM} ........................................................*/ -static QState Table_initial(Table * const me, QEvt const * const e) { - /* ${AOs::Table::SM::initial} */ - uint8_t n; - (void)e; /* suppress the compiler warning about unused parameter */ - - QS_OBJ_DICTIONARY(&l_table); - QS_FUN_DICTIONARY(&QHsm_top); - QS_FUN_DICTIONARY(&Table_initial); - QS_FUN_DICTIONARY(&Table_active); - QS_FUN_DICTIONARY(&Table_serving); - QS_FUN_DICTIONARY(&Table_paused); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - - QActive_subscribe(&me->super, DONE_SIG); - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); - } - return Q_TRAN(&Table_serving); -} -/*${AOs::Table::SM::active} ................................................*/ -static QState Table_active(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Table::SM::active::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Table::SM::active::serving} .......................................*/ -static QState Table_serving(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Table::SM::active::serving} */ - case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QF_PUBLISH(&te->super, me); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } - } - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::serving::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /* ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ - if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; - me->fork[m] = USED; - me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(n, "eating "); - status_ = Q_HANDLED(); - } - /* ${AOs::Table::SM::active::serving::HUNGRY::[else]} */ - else { - me->isHungry[n] = 1U; - status_ = Q_HANDLED(); - } - break; - } - /* ${AOs::Table::SM::active::serving::DONE} */ - case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ - - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); - } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); - } - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::serving::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::serving::PAUSE} */ - case PAUSE_SIG: { - status_ = Q_TRAN(&Table_paused); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} -/*${AOs::Table::SM::active::paused} ........................................*/ -static QState Table_paused(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Table::SM::active::paused} */ - case Q_ENTRY_SIG: { - BSP_displayPaused(1U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::paused} */ - case Q_EXIT_SIG: { - BSP_displayPaused(0U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::paused::SERVE} */ - case SERVE_SIG: { - status_ = Q_TRAN(&Table_serving); - break; - } - /* ${AOs::Table::SM::active::paused::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::paused::DONE} */ - case DONE_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} - diff --git a/examples/posix/qhsmtst/Makefile b/examples/posix/qhsmtst/Makefile deleted file mode 100644 index 206608cf..00000000 --- a/examples/posix/qhsmtst/Makefile +++ /dev/null @@ -1,240 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, QHsmTst console, POSIX target, GNU compiler -# Last updated for version 6.2.0 -# Last updated on 2018-03-16 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := qhsmtst - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - main.c \ - qhsmtst.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -MKDIR := mkdir -p -RM := rm -f - -#----------------------------------------------------------------------------- -# build options for various configurations -# -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -CPPFLAGS = -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -C_SRCS += $(QS_SRCS) - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lpthread - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/* - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - diff --git a/examples/posix/qhsmtst/main.c b/examples/posix/qhsmtst/main.c deleted file mode 100644 index a3fa8b0f..00000000 --- a/examples/posix/qhsmtst/main.c +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************** -* Product: QHsmTst Example, Linux -* Last updated for version 5.8.0 -* Last updated on 2016-11-29 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "qhsmtst.h" - -#include -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/* local objects -----------------------------------------------------------*/ -static FILE *l_outFile = (FILE *)0; -static struct termios l_oldt; -static void dispatch(QSignal sig); - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - QHsmTst_ctor(); /* instantiate the QHsmTst object */ - - if (argc > 1) { /* file name provided? */ - l_outFile = fopen(argv[1], "w"); - } - - if (l_outFile == (FILE *)0) { /* interactive version? */ - struct termios newt; - tcgetattr(STDIN_FILENO, &l_oldt); /* save the terminal state */ - newt = l_oldt; - newt.c_lflag &= ~ICANON; - tcsetattr(STDIN_FILENO, TCSANOW, &newt); /* set non-canonical mode */ - - l_outFile = stdout; /* use the stdout as the output file */ - - printf("QHsmTst example, built on %s at %s,\n" - "QP: %s.\nPress ESC to quit...\n", - __DATE__, __TIME__, QP_VERSION_STR); - - QHSM_INIT(the_hsm, (QEvt *)0); /* the top-most initial tran. */ - - for (;;) { /* event loop */ - QEvt e; - int c; - - printf("\n>"); - c = getchar(); /* get a character from stdin */ - printf(": "); - - if ('a' <= c && c <= 'i') { /* in range? */ - e.sig = (QSignal)(c - 'a' + A_SIG); - } - else if ('A' <= c && c <= 'I') { /* in range? */ - e.sig = (QSignal)(c - 'A' + A_SIG); - } - else if (c == '\33') { /* the ESC key? */ - e.sig = TERMINATE_SIG; /* terminate the interactive test */ - } - else { - e.sig = IGNORE_SIG; - } - - QHSM_DISPATCH(the_hsm, &e); /* dispatch the event */ - } - } - else { /* batch version */ - printf("QHsmTst example, built on %s at %s, QP %s\n" - "output saved to %s\n", - __DATE__, __TIME__, QP_VERSION_STR, - argv[1]); - - fprintf(l_outFile, "QHsmTst example, QEP %s\n", - QP_VERSION_STR); - - QHSM_INIT(the_hsm, (QEvt *)0); /* the top-most initial tran. */ - - /* testing of dynamic transitions... */ - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(I_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(G_SIG); - dispatch(H_SIG); - dispatch(H_SIG); - dispatch(C_SIG); - dispatch(G_SIG); - dispatch(C_SIG); - dispatch(C_SIG); - - fclose(l_outFile); - } - - return 0; -} -/*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} -/*..........................................................................*/ -void BSP_display(char const *msg) { - fprintf(l_outFile, msg); - fflush(l_outFile); -} -/*..........................................................................*/ -void BSP_exit(void) { - tcsetattr(STDIN_FILENO, TCSANOW, &l_oldt); - printf("Bye, Bye!\n"); - exit(0); -} -/*..........................................................................*/ -static void dispatch(QSignal sig) { - QEvt e; - Q_REQUIRE((A_SIG <= sig) && (sig <= I_SIG)); - e.sig = sig; - fprintf(l_outFile, "\n%c:", 'A' + sig - A_SIG); - QHSM_DISPATCH(the_hsm, &e); /* dispatch the event */ -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY -#include "qs_port.h" - -/*..........................................................................*/ -void QF_onStartup(void) { -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QS_onCleanup(void) { -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -#endif - diff --git a/examples/posix/qhsmtst/qhsmtst.c b/examples/posix/qhsmtst/qhsmtst.c deleted file mode 100644 index ed0c40de..00000000 --- a/examples/posix/qhsmtst/qhsmtst.c +++ /dev/null @@ -1,374 +0,0 @@ -/***************************************************************************** -* Model: qhsmtst.qm -* File: ./qhsmtst.c -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::qhsmtst.c} ..........................................................*/ -#include "qpc.h" -#include "qhsmtst.h" - - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${HSMs::QHsmTst} .........................................................*/ -typedef struct { -/* protected: */ - QHsm super; - -/* private: */ - uint8_t foo; -} QHsmTst; - -/* protected: */ -static QState QHsmTst_initial(QHsmTst * const me, QEvt const * const e); -static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e); -static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e); -static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e); -static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e); -static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e); -static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e); - - -static QHsmTst l_hsmtst; /* the only instance of the QHsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_hsm = (QHsm *)&l_hsmtst; /* the opaque pointer */ - -/*${HSMs::QHsmTst_ctor} ....................................................*/ -void QHsmTst_ctor(void) { - QHsmTst *me = &l_hsmtst; - QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); -} -/*${HSMs::QHsmTst} .........................................................*/ -/*${HSMs::QHsmTst::SM} .....................................................*/ -static QState QHsmTst_initial(QHsmTst * const me, QEvt const * const e) { - /* ${HSMs::QHsmTst::SM::initial} */ - (void)e; /* avoid compiler warning */ - me->foo = 0U; - BSP_display("top-INIT;"); - return Q_TRAN(&QHsmTst_s2); -} -/*${HSMs::QHsmTst::SM::s} ..................................................*/ -static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${HSMs::QHsmTst::SM::s} */ - case Q_ENTRY_SIG: { - BSP_display("s-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s} */ - case Q_EXIT_SIG: { - BSP_display("s-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::initial} */ - case Q_INIT_SIG: { - BSP_display("s-INIT;"); - status_ = Q_TRAN(&QHsmTst_s11); - break; - } - /* ${HSMs::QHsmTst::SM::s::I} */ - case I_SIG: { - /* ${HSMs::QHsmTst::SM::s::I::[me->foo]} */ - if (me->foo) { - me->foo = 0U; - BSP_display("s-I;"); - status_ = Q_HANDLED(); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /* ${HSMs::QHsmTst::SM::s::E} */ - case E_SIG: { - BSP_display("s-E;"); - status_ = Q_TRAN(&QHsmTst_s11); - break; - } - /* ${HSMs::QHsmTst::SM::s::TERMINATE} */ - case TERMINATE_SIG: { - BSP_exit(); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${HSMs::QHsmTst::SM::s::s1} ..............................................*/ -static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${HSMs::QHsmTst::SM::s::s1} */ - case Q_ENTRY_SIG: { - BSP_display("s1-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1} */ - case Q_EXIT_SIG: { - BSP_display("s1-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::initial} */ - case Q_INIT_SIG: { - BSP_display("s1-INIT;"); - status_ = Q_TRAN(&QHsmTst_s11); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::I} */ - case I_SIG: { - BSP_display("s1-I;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::D} */ - case D_SIG: { - /* ${HSMs::QHsmTst::SM::s::s1::D::[!me->foo]} */ - if (!me->foo) { - me->foo = 1U; - BSP_display("s1-D;"); - status_ = Q_TRAN(&QHsmTst_s); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::A} */ - case A_SIG: { - BSP_display("s1-A;"); - status_ = Q_TRAN(&QHsmTst_s1); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::B} */ - case B_SIG: { - BSP_display("s1-B;"); - status_ = Q_TRAN(&QHsmTst_s11); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::F} */ - case F_SIG: { - BSP_display("s1-F;"); - status_ = Q_TRAN(&QHsmTst_s211); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::C} */ - case C_SIG: { - BSP_display("s1-C;"); - status_ = Q_TRAN(&QHsmTst_s2); - break; - } - default: { - status_ = Q_SUPER(&QHsmTst_s); - break; - } - } - return status_; -} -/*${HSMs::QHsmTst::SM::s::s1::s11} .........................................*/ -static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${HSMs::QHsmTst::SM::s::s1::s11} */ - case Q_ENTRY_SIG: { - BSP_display("s11-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::s11} */ - case Q_EXIT_SIG: { - BSP_display("s11-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::s11::H} */ - case H_SIG: { - BSP_display("s11-H;"); - status_ = Q_TRAN(&QHsmTst_s); - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::s11::D} */ - case D_SIG: { - /* ${HSMs::QHsmTst::SM::s::s1::s11::D::[me->foo]} */ - if (me->foo) { - me->foo = 0U; - BSP_display("s11-D;"); - status_ = Q_TRAN(&QHsmTst_s1); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /* ${HSMs::QHsmTst::SM::s::s1::s11::G} */ - case G_SIG: { - BSP_display("s11-G;"); - status_ = Q_TRAN(&QHsmTst_s211); - break; - } - default: { - status_ = Q_SUPER(&QHsmTst_s1); - break; - } - } - return status_; -} -/*${HSMs::QHsmTst::SM::s::s2} ..............................................*/ -static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${HSMs::QHsmTst::SM::s::s2} */ - case Q_ENTRY_SIG: { - BSP_display("s2-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2} */ - case Q_EXIT_SIG: { - BSP_display("s2-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::initial} */ - case Q_INIT_SIG: { - BSP_display("s2-INIT;"); - status_ = Q_TRAN(&QHsmTst_s211); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::I} */ - case I_SIG: { - /* ${HSMs::QHsmTst::SM::s::s2::I::[!me->foo]} */ - if (!me->foo) { - me->foo = 1U; - BSP_display("s2-I;"); - status_ = Q_HANDLED(); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::F} */ - case F_SIG: { - BSP_display("s2-F;"); - status_ = Q_TRAN(&QHsmTst_s11); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::C} */ - case C_SIG: { - BSP_display("s2-C;"); - status_ = Q_TRAN(&QHsmTst_s1); - break; - } - default: { - status_ = Q_SUPER(&QHsmTst_s); - break; - } - } - return status_; -} -/*${HSMs::QHsmTst::SM::s::s2::s21} .........................................*/ -static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${HSMs::QHsmTst::SM::s::s2::s21} */ - case Q_ENTRY_SIG: { - BSP_display("s21-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21} */ - case Q_EXIT_SIG: { - BSP_display("s21-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::initial} */ - case Q_INIT_SIG: { - BSP_display("s21-INIT;"); - status_ = Q_TRAN(&QHsmTst_s211); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::G} */ - case G_SIG: { - BSP_display("s21-G;"); - status_ = Q_TRAN(&QHsmTst_s1); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::A} */ - case A_SIG: { - BSP_display("s21-A;"); - status_ = Q_TRAN(&QHsmTst_s21); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::B} */ - case B_SIG: { - BSP_display("s21-B;"); - status_ = Q_TRAN(&QHsmTst_s211); - break; - } - default: { - status_ = Q_SUPER(&QHsmTst_s2); - break; - } - } - return status_; -} -/*${HSMs::QHsmTst::SM::s::s2::s21::s211} ...................................*/ -static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${HSMs::QHsmTst::SM::s::s2::s21::s211} */ - case Q_ENTRY_SIG: { - BSP_display("s211-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::s211} */ - case Q_EXIT_SIG: { - BSP_display("s211-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::s211::H} */ - case H_SIG: { - BSP_display("s211-H;"); - status_ = Q_TRAN(&QHsmTst_s); - break; - } - /* ${HSMs::QHsmTst::SM::s::s2::s21::s211::D} */ - case D_SIG: { - BSP_display("s211-D;"); - status_ = Q_TRAN(&QHsmTst_s21); - break; - } - default: { - status_ = Q_SUPER(&QHsmTst_s21); - break; - } - } - return status_; -} - diff --git a/examples/posix/qhsmtst/qhsmtst.h b/examples/posix/qhsmtst/qhsmtst.h deleted file mode 100644 index a3e2b8cc..00000000 --- a/examples/posix/qhsmtst/qhsmtst.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************** -* Model: qhsmtst.qm -* File: ./qhsmtst.h -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::qhsmtst.h} ..........................................................*/ -#ifndef qhsmtst_h -#define qhsmtst_h - -enum QHsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; - -extern QHsm * const the_hsm; /* opaque pointer to the test HSM */ - -/*${HSMs::QHsmTst_ctor} ....................................................*/ -void QHsmTst_ctor(void); - - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* qhsmtst_h */ diff --git a/examples/posix/qhsmtst/qhsmtst.qm b/examples/posix/qhsmtst/qhsmtst.qm deleted file mode 100644 index ff0f1bb8..00000000 --- a/examples/posix/qhsmtst/qhsmtst.qm +++ /dev/null @@ -1,291 +0,0 @@ - - - QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. - - - - Test active object - - - - (void)e; /* avoid compiler warning */ -me->foo = 0U; -BSP_display("top-INIT;"); - - - - - - BSP_display("s-ENTRY;"); - BSP_display("s-EXIT;"); - - BSP_display("s-INIT;"); - - - - - - - me->foo - me->foo = 0U; -BSP_display("s-I;"); - - - - - - - - - - BSP_display("s-E;"); - - - - - - BSP_exit(); - - - - - - BSP_display("s1-ENTRY;"); - BSP_display("s1-EXIT;"); - - BSP_display("s1-INIT;"); - - - - - - BSP_display("s1-I;"); - - - - - - - !me->foo - me->foo = 1U; -BSP_display("s1-D;"); - - - - - - - - - - BSP_display("s1-A;"); - - - - - - BSP_display("s1-B;"); - - - - - - BSP_display("s1-F;"); - - - - - - BSP_display("s1-C;"); - - - - - - BSP_display("s11-ENTRY;"); - BSP_display("s11-EXIT;"); - - BSP_display("s11-H;"); - - - - - - - me->foo - me->foo = 0U; -BSP_display("s11-D;"); - - - - - - - - - - BSP_display("s11-G;"); - - - - - - - - - - - - - - - - BSP_display("s2-ENTRY;"); - BSP_display("s2-EXIT;"); - - BSP_display("s2-INIT;"); - - - - - - - !me->foo - me->foo = 1U; -BSP_display("s2-I;"); - - - - - - - - - - BSP_display("s2-F;"); - - - - - - BSP_display("s2-C;"); - - - - - - BSP_display("s21-ENTRY;"); - BSP_display("s21-EXIT;"); - - BSP_display("s21-INIT;"); - - - - - - BSP_display("s21-G;"); - - - - - - BSP_display("s21-A;"); - - - - - - BSP_display("s21-B;"); - - - - - - BSP_display("s211-ENTRY;"); - BSP_display("s211-EXIT;"); - - BSP_display("s211-H;"); - - - - - - BSP_display("s211-D;"); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - QHsmTst *me = &l_hsmtst; -QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); - - - - - #ifndef qhsmtst_h -#define qhsmtst_h - -enum QHsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; - -extern QHsm * const the_hsm; /* opaque pointer to the test HSM */ - -$declare(HSMs::QHsmTst_ctor) - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* qhsmtst_h */ - - - #include "qpc.h" -#include "qhsmtst.h" - -$declare(HSMs::QHsmTst) - -static QHsmTst l_hsmtst; /* the only instance of the QHsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_hsm = (QHsm *)&l_hsmtst; /* the opaque pointer */ - -$define(HSMs::QHsmTst_ctor) -$define(HSMs::QHsmTst) - - - diff --git a/examples/posix/qmsmtst/Makefile b/examples/posix/qmsmtst/Makefile deleted file mode 100644 index 036272a6..00000000 --- a/examples/posix/qmsmtst/Makefile +++ /dev/null @@ -1,240 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, QMsmTst console, POSIX target, GNU compiler -# Last updated for version 6.2.0 -# Last updated on 2018-03-16 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := qmsmtst - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - main.c \ - qmsmtst.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -MKDIR := mkdir -p -RM := rm -f - -#----------------------------------------------------------------------------- -# build options for various configurations -# -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -CPPFLAGS = -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -C_SRCS += $(QS_SRCS) - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lpthread - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/* - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - diff --git a/examples/posix/qmsmtst/main.c b/examples/posix/qmsmtst/main.c deleted file mode 100644 index f0a539b0..00000000 --- a/examples/posix/qmsmtst/main.c +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************** -* Product: QMsmTst Example, Linux -* Last updated for version 5.8.0 -* Last updated on 2016-11-29 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "qmsmtst.h" - -#include -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/* local objects -----------------------------------------------------------*/ -static FILE *l_outFile = (FILE *)0; -static struct termios l_oldt; -static void dispatch(QSignal sig); - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - QMsmTst_ctor(); /* instantiate the QMsmTst object */ - - if (argc > 1) { /* file name provided? */ - l_outFile = fopen(argv[1], "w"); - } - - if (l_outFile == (FILE *)0) { /* interactive version? */ - struct termios newt; - tcgetattr(STDIN_FILENO, &l_oldt); /* save the terminal state */ - newt = l_oldt; - newt.c_lflag &= ~ICANON; - tcsetattr(STDIN_FILENO, TCSANOW, &newt); /* set non-canonical mode */ - - l_outFile = stdout; /* use the stdout as the output file */ - - printf("QMsmTst example, built on %s at %s,\n" - "QP: %s.\nPress ESC to quit...\n", - __DATE__, __TIME__, QP_VERSION_STR); - - QHSM_INIT(the_msm, (QEvt *)0); /* the top-most initial tran. */ - - for (;;) { /* event loop */ - QEvt e; - int c; - - printf("\n>"); - c = getchar(); /* get a character from stdin */ - printf(": "); - - if ('a' <= c && c <= 'i') { /* in range? */ - e.sig = (QSignal)(c - 'a' + A_SIG); - } - else if ('A' <= c && c <= 'I') { /* in range? */ - e.sig = (QSignal)(c - 'A' + A_SIG); - } - else if (c == '\33') { /* the ESC key? */ - e.sig = TERMINATE_SIG; /* terminate the interactive test */ - } - else { - e.sig = IGNORE_SIG; - } - - QHSM_DISPATCH(the_msm, &e); /* dispatch the event */ - } - } - else { /* batch version */ - printf("QMsmTst example, built on %s at %s, QP %s\n" - "output saved to %s\n", - __DATE__, __TIME__, QP_VERSION_STR, - argv[1]); - - fprintf(l_outFile, "QMsmTst example, QEP %s\n", - QP_VERSION_STR); - - QHSM_INIT(the_msm, (QEvt *)0); /* the top-most initial tran. */ - - /* testing of dynamic transitions... */ - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(I_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(G_SIG); - dispatch(H_SIG); - dispatch(H_SIG); - dispatch(C_SIG); - dispatch(G_SIG); - dispatch(C_SIG); - dispatch(C_SIG); - - fclose(l_outFile); - } - - return 0; -} -/*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} -/*..........................................................................*/ -void BSP_display(char const *msg) { - fprintf(l_outFile, msg); - fflush(l_outFile); -} -/*..........................................................................*/ -void BSP_exit(void) { - tcsetattr(STDIN_FILENO, TCSANOW, &l_oldt); - printf("Bye, Bye!\n"); - exit(0); -} -/*..........................................................................*/ -static void dispatch(QSignal sig) { - QEvt e; - Q_REQUIRE((A_SIG <= sig) && (sig <= I_SIG)); - e.sig = sig; - fprintf(l_outFile, "\n%c:", 'A' + sig - A_SIG); - QHSM_DISPATCH(the_msm, &e); /* dispatch the event */ -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY -#include "qs_port.h" - -/*..........................................................................*/ -void QF_onStartup(void) { -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QS_onCleanup(void) { -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -#endif - diff --git a/examples/posix/qmsmtst/qmsmtst.c b/examples/posix/qmsmtst/qmsmtst.c deleted file mode 100644 index b4e2eb63..00000000 --- a/examples/posix/qmsmtst/qmsmtst.c +++ /dev/null @@ -1,688 +0,0 @@ -/*$file${.::qmsmtst.c} #####################################################*/ -/* -* Model: qmsmtst.qm -* File: C:/qp_lab/qpc/examples/posix/qmsmtst/qmsmtst.c -* -* This code has been generated by QM tool (https://state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : QPC-EVAL-171231 -* Issued to : Company/individual evaluating the QP/C framework -* Framework(s): qpc -* Support ends: 2017-12-31 -* Product(s) : -* This license is available only for evaluation purposes and -* the generated code is still licensed under the terms of GPL. -* Please submit request for extension of the evaluaion period at: -* https://state-machine.com/licensing/#RequestForm -*/ -/*$endhead${.::qmsmtst.c} ##################################################*/ -#include "qpc.h" -#include "qmsmtst.h" - -/*$declare${SMs::QMsmTst} ##################################################*/ -/*${SMs::QMsmTst} ..........................................................*/ -typedef struct { -/* protected: */ - QMsm super; - -/* private: */ - uint8_t foo; -} QMsmTst; - -/* protected: */ -static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s_e(QMsmTst * const me); -static QState QMsmTst_s_x(QMsmTst * const me); -static QState QMsmTst_s_i(QMsmTst * const me); -static QMState const QMsmTst_s_s = { - (QMState const *)0, /* superstate (top) */ - Q_STATE_CAST(&QMsmTst_s), - Q_ACTION_CAST(&QMsmTst_s_e), - Q_ACTION_CAST(&QMsmTst_s_x), - Q_ACTION_CAST(&QMsmTst_s_i) -}; -static QState QMsmTst_s1 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s1_e(QMsmTst * const me); -static QState QMsmTst_s1_x(QMsmTst * const me); -static QState QMsmTst_s1_i(QMsmTst * const me); -static QMState const QMsmTst_s1_s = { - &QMsmTst_s_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s1), - Q_ACTION_CAST(&QMsmTst_s1_e), - Q_ACTION_CAST(&QMsmTst_s1_x), - Q_ACTION_CAST(&QMsmTst_s1_i) -}; -static QState QMsmTst_s11 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s11_e(QMsmTst * const me); -static QState QMsmTst_s11_x(QMsmTst * const me); -static QMState const QMsmTst_s11_s = { - &QMsmTst_s1_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s11), - Q_ACTION_CAST(&QMsmTst_s11_e), - Q_ACTION_CAST(&QMsmTst_s11_x), - Q_ACTION_CAST(0) /* no intitial tran. */ -}; -static QState QMsmTst_s2 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s2_e(QMsmTst * const me); -static QState QMsmTst_s2_x(QMsmTst * const me); -static QState QMsmTst_s2_i(QMsmTst * const me); -static QMState const QMsmTst_s2_s = { - &QMsmTst_s_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s2), - Q_ACTION_CAST(&QMsmTst_s2_e), - Q_ACTION_CAST(&QMsmTst_s2_x), - Q_ACTION_CAST(&QMsmTst_s2_i) -}; -static QState QMsmTst_s21 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s21_e(QMsmTst * const me); -static QState QMsmTst_s21_x(QMsmTst * const me); -static QState QMsmTst_s21_i(QMsmTst * const me); -static QMState const QMsmTst_s21_s = { - &QMsmTst_s2_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s21), - Q_ACTION_CAST(&QMsmTst_s21_e), - Q_ACTION_CAST(&QMsmTst_s21_x), - Q_ACTION_CAST(&QMsmTst_s21_i) -}; -static QState QMsmTst_s211 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s211_e(QMsmTst * const me); -static QState QMsmTst_s211_x(QMsmTst * const me); -static QMState const QMsmTst_s211_s = { - &QMsmTst_s21_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s211), - Q_ACTION_CAST(&QMsmTst_s211_e), - Q_ACTION_CAST(&QMsmTst_s211_x), - Q_ACTION_CAST(0) /* no intitial tran. */ -}; -/*$enddecl${SMs::QMsmTst} ##################################################*/ - -static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */ - -/*$define${SMs::QMsmTst_ctor} ##############################################*/ -/* Check for the minimum required QP version */ -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 6.0.1 or higher required -#endif -/*${SMs::QMsmTst_ctor} .....................................................*/ -void QMsmTst_ctor(void) { - QMsmTst *me = &l_msmtst; - QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); -} -/*$enddef${SMs::QMsmTst_ctor} ##############################################*/ -/*$define${SMs::QMsmTst} ###################################################*/ -/*${SMs::QMsmTst} ..........................................................*/ -/*${SMs::QMsmTst::SM} ......................................................*/ -static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s2_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::initial} */ - (void)e; /* avoid compiler warning */ - me->foo = 0U; - BSP_display("top-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s} ...................................................*/ -/*${SMs::QMsmTst::SM::s} */ -static QState QMsmTst_s_e(QMsmTst * const me) { - BSP_display("s-ENTRY;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_ENTRY(&QMsmTst_s_s); -} -/*${SMs::QMsmTst::SM::s} */ -static QState QMsmTst_s_x(QMsmTst * const me) { - BSP_display("s-EXIT;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_EXIT(&QMsmTst_s_s); -} -/*${SMs::QMsmTst::SM::s::initial} */ -static QState QMsmTst_s_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::initial} */ - BSP_display("s-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s} */ -static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::I} */ - case I_SIG: { - /*${SMs::QMsmTst::SM::s::I::[me->foo]} */ - if (me->foo) { - me->foo = 0U; - BSP_display("s-I;"); - status_ = QM_HANDLED(); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::E} */ - case E_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s-E;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::TERMINATE} */ - case TERMINATE_SIG: { - BSP_exit(); - status_ = QM_HANDLED(); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* avoid compiler warning in case 'me' is not used */ - return status_; -} -/*${SMs::QMsmTst::SM::s::s1} ...............................................*/ -/*${SMs::QMsmTst::SM::s::s1} */ -static QState QMsmTst_s1_e(QMsmTst * const me) { - BSP_display("s1-ENTRY;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_ENTRY(&QMsmTst_s1_s); -} -/*${SMs::QMsmTst::SM::s::s1} */ -static QState QMsmTst_s1_x(QMsmTst * const me) { - BSP_display("s1-EXIT;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_EXIT(&QMsmTst_s1_s); -} -/*${SMs::QMsmTst::SM::s::s1::initial} */ -static QState QMsmTst_s1_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::s1::initial} */ - BSP_display("s1-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s::s1} */ -static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s1::I} */ - case I_SIG: { - BSP_display("s1-I;"); - status_ = QM_HANDLED(); - break; - } - /*${SMs::QMsmTst::SM::s::s1::D} */ - case D_SIG: { - /*${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} */ - if (!me->foo) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - me->foo = 1U; - BSP_display("s1-D;"); - status_ = QM_TRAN(&tatbl_); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::s1::A} */ - case A_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s1-A;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::B} */ - case B_SIG: { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s1-B;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::F} */ - case F_SIG: { - static struct { - QMState const *target; - QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s1-F;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::C} */ - case C_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s2_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s1-C;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} -/*${SMs::QMsmTst::SM::s::s1::s11} ..........................................*/ -/*${SMs::QMsmTst::SM::s::s1::s11} */ -static QState QMsmTst_s11_e(QMsmTst * const me) { - BSP_display("s11-ENTRY;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_ENTRY(&QMsmTst_s11_s); -} -/*${SMs::QMsmTst::SM::s::s1::s11} */ -static QState QMsmTst_s11_x(QMsmTst * const me) { - BSP_display("s11-EXIT;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_EXIT(&QMsmTst_s11_s); -} -/*${SMs::QMsmTst::SM::s::s1::s11} */ -static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s1::s11::H} */ - case H_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s11-H;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::s11::D} */ - case D_SIG: { - /*${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} */ - if (me->foo) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - me->foo = 0U; - BSP_display("s11-D;"); - status_ = QM_TRAN(&tatbl_); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::s1::s11::G} */ - case G_SIG: { - static struct { - QMState const *target; - QActionHandler act[6]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s11-G;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} -/*${SMs::QMsmTst::SM::s::s2} ...............................................*/ -/*${SMs::QMsmTst::SM::s::s2} */ -static QState QMsmTst_s2_e(QMsmTst * const me) { - BSP_display("s2-ENTRY;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_ENTRY(&QMsmTst_s2_s); -} -/*${SMs::QMsmTst::SM::s::s2} */ -static QState QMsmTst_s2_x(QMsmTst * const me) { - BSP_display("s2-EXIT;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_EXIT(&QMsmTst_s2_s); -} -/*${SMs::QMsmTst::SM::s::s2::initial} */ -static QState QMsmTst_s2_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::s2::initial} */ - BSP_display("s2-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s::s2} */ -static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::I} */ - case I_SIG: { - /*${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} */ - if (!me->foo) { - me->foo = 1U; - BSP_display("s2-I;"); - status_ = QM_HANDLED(); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::s2::F} */ - case F_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s2-F;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::C} */ - case C_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s2-C;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} -/*${SMs::QMsmTst::SM::s::s2::s21} ..........................................*/ -/*${SMs::QMsmTst::SM::s::s2::s21} */ -static QState QMsmTst_s21_e(QMsmTst * const me) { - BSP_display("s21-ENTRY;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_ENTRY(&QMsmTst_s21_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21} */ -static QState QMsmTst_s21_x(QMsmTst * const me) { - BSP_display("s21-EXIT;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_EXIT(&QMsmTst_s21_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21::initial} */ -static QState QMsmTst_s21_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::s2::s21::initial} */ - BSP_display("s21-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s::s2::s21} */ -static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::s21::G} */ - case G_SIG: { - static struct { - QMState const *target; - QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s21-G;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::s21::A} */ - case A_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s21_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s21-A;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::s21::B} */ - case B_SIG: { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s21-B;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} -/*${SMs::QMsmTst::SM::s::s2::s21::s211} ....................................*/ -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ -static QState QMsmTst_s211_e(QMsmTst * const me) { - BSP_display("s211-ENTRY;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_ENTRY(&QMsmTst_s211_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ -static QState QMsmTst_s211_x(QMsmTst * const me) { - BSP_display("s211-EXIT;"); - (void)me; /* avoid compiler warning in case 'me' is not used */ - return QM_EXIT(&QMsmTst_s211_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ -static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::s21::s211::H} */ - case H_SIG: { - static struct { - QMState const *target; - QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s211-H;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::s21::s211::D} */ - case D_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s21_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_i), /* initial tran. */ - Q_ACTION_CAST(0) /* zero terminator */ - } - }; - BSP_display("s211-D;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} -/*$enddef${SMs::QMsmTst} ###################################################*/ diff --git a/examples/posix/qmsmtst/qmsmtst.h b/examples/posix/qmsmtst/qmsmtst.h deleted file mode 100644 index 68d91d2d..00000000 --- a/examples/posix/qmsmtst/qmsmtst.h +++ /dev/null @@ -1,50 +0,0 @@ -/*$file${.::qmsmtst.h} #####################################################*/ -/* -* Model: qmsmtst.qm -* File: C:/qp_lab/qpc/examples/posix/qmsmtst/qmsmtst.h -* -* This code has been generated by QM tool (https://state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : QPC-EVAL-171231 -* Issued to : Company/individual evaluating the QP/C framework -* Framework(s): qpc -* Support ends: 2017-12-31 -* Product(s) : -* This license is available only for evaluation purposes and -* the generated code is still licensed under the terms of GPL. -* Please submit request for extension of the evaluaion period at: -* https://state-machine.com/licensing/#RequestForm -*/ -/*$endhead${.::qmsmtst.h} ##################################################*/ -#ifndef qmsmtst_h -#define qmsmtst_h - -enum QMsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; - -extern QMsm * const the_msm; /* opaque pointer to the test MSM */ - -/*$declare${SMs::QMsmTst_ctor} #############################################*/ -/*${SMs::QMsmTst_ctor} .....................................................*/ -void QMsmTst_ctor(void); -/*$enddecl${SMs::QMsmTst_ctor} #############################################*/ - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* qmsmtst_h */ \ No newline at end of file diff --git a/examples/posix/qmsmtst/qmsmtst.qm b/examples/posix/qmsmtst/qmsmtst.qm deleted file mode 100644 index ba130b23..00000000 --- a/examples/posix/qmsmtst/qmsmtst.qm +++ /dev/null @@ -1,291 +0,0 @@ - - - QMsmTst is a QMsm state machine test based on the contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. - - - - Test active object - - - - (void)e; /* avoid compiler warning */ -me->foo = 0U; -BSP_display("top-INIT;"); - - - - - - BSP_display("s-ENTRY;"); - BSP_display("s-EXIT;"); - - BSP_display("s-INIT;"); - - - - - - - me->foo - me->foo = 0U; -BSP_display("s-I;"); - - - - - - - - - - BSP_display("s-E;"); - - - - - - BSP_exit(); - - - - - - BSP_display("s1-ENTRY;"); - BSP_display("s1-EXIT;"); - - BSP_display("s1-INIT;"); - - - - - - BSP_display("s1-I;"); - - - - - - - !me->foo - me->foo = 1U; -BSP_display("s1-D;"); - - - - - - - - - - BSP_display("s1-A;"); - - - - - - BSP_display("s1-B;"); - - - - - - BSP_display("s1-F;"); - - - - - - BSP_display("s1-C;"); - - - - - - BSP_display("s11-ENTRY;"); - BSP_display("s11-EXIT;"); - - BSP_display("s11-H;"); - - - - - - - me->foo - me->foo = 0U; -BSP_display("s11-D;"); - - - - - - - - - - BSP_display("s11-G;"); - - - - - - - - - - - - - - - - BSP_display("s2-ENTRY;"); - BSP_display("s2-EXIT;"); - - BSP_display("s2-INIT;"); - - - - - - - !me->foo - me->foo = 1U; -BSP_display("s2-I;"); - - - - - - - - - - BSP_display("s2-F;"); - - - - - - BSP_display("s2-C;"); - - - - - - BSP_display("s21-ENTRY;"); - BSP_display("s21-EXIT;"); - - BSP_display("s21-INIT;"); - - - - - - BSP_display("s21-G;"); - - - - - - BSP_display("s21-A;"); - - - - - - BSP_display("s21-B;"); - - - - - - BSP_display("s211-ENTRY;"); - BSP_display("s211-EXIT;"); - - BSP_display("s211-H;"); - - - - - - BSP_display("s211-D;"); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - QMsmTst *me = &l_msmtst; -QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); - - - - - #ifndef qmsmtst_h -#define qmsmtst_h - -enum QMsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; - -extern QMsm * const the_msm; /* opaque pointer to the test MSM */ - -$declare(SMs::QMsmTst_ctor) - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* qmsmtst_h */ - - - #include "qpc.h" -#include "qmsmtst.h" - -$declare(SMs::QMsmTst) - -static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */ - -$define(SMs::QMsmTst_ctor) -$define(SMs::QMsmTst) - - - diff --git a/examples/qutest/TDDbook_Flash/FakeMicroTime.c b/examples/qutest/TDDbook_Flash/FakeMicroTime.c deleted file mode 100644 index a146bfa1..00000000 --- a/examples/qutest/TDDbook_Flash/FakeMicroTime.c +++ /dev/null @@ -1,57 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - -#include "MicroTime.h" -//#include -//#include - -static uint32_t time = 0; -static uint32_t increment = 1; -static uint32_t totalDelay = 0; - -void FakeMicroTime_Init(uint32_t start, uint32_t incr) -{ - time = start; - increment = incr; - totalDelay = 0; -} -uint32_t MicroTime_Get(void) -{ - uint32_t t = time; - time += increment; - return t; -} - -void MicroTime_Delay(uint32_t delay) -{ - time += delay; - totalDelay += delay; -} - -uint32_t FakeMicroTime_GetDelayDuration(void) -{ - return totalDelay; -} diff --git a/examples/qutest/TDDbook_Flash/FakeMicroTime.h b/examples/qutest/TDDbook_Flash/FakeMicroTime.h deleted file mode 100644 index a7ef4e2c..00000000 --- a/examples/qutest/TDDbook_Flash/FakeMicroTime.h +++ /dev/null @@ -1,35 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - -#ifndef D_FakeMicroTime_H -#define D_FakeMicroTime_H - -#include "MicroTime.h" - -void FakeMicroTime_Init(uint32_t start, uint32_t increment); -uint32_t FakeMicroTime_GetDelayDuration(); - -#endif /* D_FakeMicroTime_H */ diff --git a/examples/qutest/TDDbook_Flash/Flash.c b/examples/qutest/TDDbook_Flash/Flash.c deleted file mode 100644 index d5106a0e..00000000 --- a/examples/qutest/TDDbook_Flash/Flash.c +++ /dev/null @@ -1,180 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - -#include "Flash.h" -#include "IO.h" -#include "m28w160ect.h" -#include "MicroTime.h" - -#define FLASH_WRITE_TIMEOUT_IN_MICROSECONDS 5000 - -void Flash_Create(void) -{ -} - -void Flash_Destroy(void) -{ -} - -static int writeError(int status) -{ - IO_Write(CommandRegister, Reset); - if (status & VppErrorBit) - return FLASH_VPP_ERROR; - else if (status & ProgramErrorBit) - return FLASH_PROGRAM_ERROR; - else if (status & BlockProtectionErrorBit) - return FLASH_PROTECTED_BLOCK_ERROR; - else - return FLASH_UNKNOWN_PROGRAM_ERROR; -} - -int Flash_Write(ioAddress offset, ioData data) -{ - ioData status = 0; - uint32_t timestamp = MicroTime_Get(); - - IO_Write(CommandRegister, ProgramCommand); - IO_Write(offset, data); - - status = IO_Read(StatusRegister); - while ((status & ReadyBit) == 0) - { - if (MicroTime_Get() - timestamp >= FLASH_WRITE_TIMEOUT_IN_MICROSECONDS) - return FLASH_TIMEOUT_ERROR; - status = IO_Read(StatusRegister); - } - - if (status != ReadyBit) - return writeError(status); - - if (data != IO_Read(offset)) - return FLASH_READ_BACK_ERROR; - - return FLASH_SUCCESS; -} - -#if 0 -int Flash_Write(ioAddress address, ioData data) -{ - return -1; -} -#endif - -#if 0 -int Flash_Write(ioAddress address, ioData data) -{ - IO_Write(0x40, 0); - return -1; -} -#endif - -#if 0 -int Flash_Write(ioAddress address, ioData data) -{ - IO_Write(0, 0x40); - IO_Write(address, data); - IO_Read(0); - IO_Read(address); - return FLASH_SUCCESS; -} -#endif - -#if 0 -int Flash_Write(ioAddress address, ioData data) -{ - IO_Write(CommandRegister, ProgramCommand); - IO_Write(address, data); - IO_Read(StatusRegister); - IO_Read(address); - return FLASH_SUCCESS; -} -#endif - -#if 0 -int Flash_Write(ioAddress address, ioData data) -{ - ioData status = 0; - - IO_Write(CommandRegister, ProgramCommand); - IO_Write(address, data); - - while ((status & ReadyBit) == 0) - status = IO_Read(StatusRegister); - - IO_Read(address); - - return FLASH_SUCCESS; -} -#endif - -#if 0 -int Flash_Write(ioAddress offset, ioData data) -{ - ioData status = 0; - IO_Write(CommandRegister, ProgramCommand); - IO_Write(offset, data); - - while ((status & ReadyBit) == 0) - status = IO_Read(StatusRegister); - - if (status != ReadyBit) - { - IO_Write(CommandRegister, Reset); - - if (status & VppErrorBit) - return FLASH_VPP_ERROR; - else if (status & ProgramErrorBit) - return FLASH_PROGRAM_ERROR; - else if (status & BlockProtectionErrorBit) - return FLASH_PROTECTED_BLOCK_ERROR; - else - return FLASH_UNKNOWN_PROGRAM_ERROR; - } - IO_Read(address); - - return FLASH_SUCCESS; -} -#endif - -#if 0 -int Flash_Write(ioAddress offset, ioData data) -{ - ioData status = 0; - IO_Write(CommandRegister, ProgramCommand); - IO_Write(offset, data); - - while ((status & ReadyBit) == 0) - status = IO_Read(StatusRegister); - if (status != ReadyBit) - return writeError(status); - if (data != IO_Read(offset)) - return FLASH_READ_BACK_ERROR; - return FLASH_SUCCESS; -} -#endif - diff --git a/examples/qutest/TDDbook_Flash/Flash.h b/examples/qutest/TDDbook_Flash/Flash.h deleted file mode 100644 index 65b5f6bf..00000000 --- a/examples/qutest/TDDbook_Flash/Flash.h +++ /dev/null @@ -1,47 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - -#ifndef D_Flash_H -#define D_Flash_H - -#include "IO.h" - -void Flash_Create(void); -void Flash_Destroy(void); -int Flash_Write(ioAddress offset, ioData data); - -typedef enum -{ - FLASH_SUCCESS = 0, - FLASH_VPP_ERROR, - FLASH_PROGRAM_ERROR, - FLASH_PROTECTED_BLOCK_ERROR, - FLASH_UNKNOWN_PROGRAM_ERROR, - FLASH_READ_BACK_ERROR, - FLASH_TIMEOUT_ERROR -} FlashStatus; -#endif /* D_Flash_H */ diff --git a/examples/qutest/TDDbook_Flash/IO.h b/examples/qutest/TDDbook_Flash/IO.h deleted file mode 100644 index 372154f3..00000000 --- a/examples/qutest/TDDbook_Flash/IO.h +++ /dev/null @@ -1,40 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - - -#ifndef D_IO_H -#define D_IO_H -#include - -typedef uint32_t ioAddress; -typedef uint16_t ioData; - -ioData IO_Read(ioAddress offset); -void IO_Write(ioAddress offset, ioData data); - -#endif - diff --git a/examples/qutest/TDDbook_Flash/Makefile b/examples/qutest/TDDbook_Flash/Makefile deleted file mode 100644 index c556ac5e..00000000 --- a/examples/qutest/TDDbook_Flash/Makefile +++ /dev/null @@ -1,247 +0,0 @@ -############################################################################## -# Product: Makefile for QUTEST self-test; QP/C on Win32 host -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make # make and run the tests in the current directory -# make TESTS=test*.tcl # make and run the selected tests in the curr. dir. -# make SCRIPT=py # make and run the Python tests -# make HOST=localhost:7705 # connect to host:port -# make norun # only make but not run the tests -# make clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_Flash - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - -# list of all source directories used by this project -VPATH = \ - . - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - Flash.c \ - FakeMicroTime.c \ - MockIO.c \ - test_Flash.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -DEFINES := - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -ifeq ($(SCRIPT),py) -run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - @echo HOST = $(HOST) - diff --git a/examples/qutest/TDDbook_Flash/MicroTime.h b/examples/qutest/TDDbook_Flash/MicroTime.h deleted file mode 100644 index a90f00c2..00000000 --- a/examples/qutest/TDDbook_Flash/MicroTime.h +++ /dev/null @@ -1,35 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - -#ifndef D_MicroTime_H -#define D_MicroTime_H - -#include - -uint32_t MicroTime_Get(void); -void MicroTime_Delay(uint32_t); - -#endif /* D_MicroTime_H */ diff --git a/examples/qutest/TDDbook_Flash/MockIO.c b/examples/qutest/TDDbook_Flash/MockIO.c deleted file mode 100644 index ede20f3c..00000000 --- a/examples/qutest/TDDbook_Flash/MockIO.c +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************** -* Purpose: example Mock for IO (Chapter 10 from TDDfEC) -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-25 -* -* 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://www.state-machine.com -* mailto:info@state-machine.com -*****************************************************************************/ -#include "qpc.h" /* for QUTEST */ -#include "IO.h" /* mocked interface */ - -enum { - IO_CALL = QS_USER1, -}; - -/*..........................................................................*/ -void MockIO_Init(void) { - /* dictionaries... */ - QS_USR_DICTIONARY(IO_CALL); - - QS_FUN_DICTIONARY(&IO_Read); - QS_FUN_DICTIONARY(&IO_Write); -} -/*..........................................................................*/ -ioData IO_Read(ioAddress offset) { - QS_TEST_PROBE_DEF(&IO_Read) - ioData ret = (ioData)0; - QS_TEST_PROBE( - ret = (ioData)qs_tp_; - ) - QS_BEGIN(IO_CALL, (void *)0) /* user-specific record */ - QS_FUN(&IO_Read); - QS_U16(0, ret); - QS_U32(0, offset); - QS_END() - return ret; -} -/*..........................................................................*/ -void IO_Write(ioAddress offset, ioData data) { - QS_BEGIN(IO_CALL, (void *)0) /* user-specific record */ - QS_FUN(&IO_Write); - QS_U32(0, offset); - QS_U16(0, data); - QS_END() -} diff --git a/examples/qutest/TDDbook_Flash/efm32-slstk3401a.mak b/examples/qutest/TDDbook_Flash/efm32-slstk3401a.mak deleted file mode 100644 index 51892b12..00000000 --- a/examples/qutest/TDDbook_Flash/efm32-slstk3401a.mak +++ /dev/null @@ -1,335 +0,0 @@ -############################################################################## -# Product: Makefile for EMF32-SLSTK3401A, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -fefm32-slstk3401a.mak # make and run the tests in the current directory -# make -fefm32-slstk3401a.mak TESTS=philo*.tcl # make and run the selected tests -# make -fefm32-slstk3401a.mak SCRIPT=py # make and run the Python tests -# make -fefm32-slstk3401a.mak HOST=localhost:7705 # connect to host:port -# make -fefm32-slstk3401a.mak norun # only make but not run the tests -# make -fefm32-slstk3401a.mak clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name, binary output directory -# -PROJECT := test_Flash -TARGET := efm32-slstk3401a - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest - -# list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b - -#----------------------------------------------------------------------------- -# files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_Flash.c \ - Flash.c \ - FakeMicroTime.c \ - MockIO.c \ - qutest_port.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c \ - em_usart.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DEFM32PG1B200F256GM48=1 - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!) -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_ARCH := 7 # NOTE: must match the ARM_CPU! -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see http://gnutoolchains.com/arm-eabi/ -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-eabi-g++ -AS := $(GNU_ARM)/bin/arm-eabi-as -LINK := $(GNU_ARM)/bin/arm-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-eabi-objcopy - -#----------------------------------------------------------------------------- -# FLASH tool (NOTE: Requires the JLINK utility) -# see ../efm32-slstk3401a/flash.bat -# - -FLASH := ..\efm32-slstk3401a\flash.bat - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := $(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) \ - -mthumb -nostdlib \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(FLASH) $(TARGET_BIN) - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(FLASH) $(TARGET_BIN) - -ifeq ($(SCRIPT),py) -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -.PHONY : clean show - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QUTEST = $(QUTEST) - @echo HOST = $(HOST) - diff --git a/examples/qutest/TDDbook_Flash/ek-tm4c123gxl.mak b/examples/qutest/TDDbook_Flash/ek-tm4c123gxl.mak deleted file mode 100644 index e8fe28c4..00000000 --- a/examples/qutest/TDDbook_Flash/ek-tm4c123gxl.mak +++ /dev/null @@ -1,335 +0,0 @@ -############################################################################## -# Product: Makefile for EK-TM4C123GXL, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak SCRIPT=py # make and run the Python tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name, binary output directory -# -PROJECT := test_Flash -TARGET := ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest - -# list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(QPC)/3rd_party/ek-tm4c123gxl \ - $(QPC)/3rd_party/ek-tm4c123gxl/gnu - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_Flash.c \ - Flash.c \ - FakeMicroTime.c \ - MockIO.c \ - qutest_port.c \ - startup_TM4C123GH6PM.c \ - system_TM4C123GH6PM.c - - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DTARGET_IS_TM4C123_RB1 - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!) -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_ARCH := 7 # NOTE: must match the ARM_CPU! -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see http://gnutoolchains.com/arm-eabi/ -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-eabi-g++ -AS := $(GNU_ARM)/bin/arm-eabi-as -LINK := $(GNU_ARM)/bin/arm-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The following symbol LMFLASH assumes that LMFlash.exe can -# be found on the PATH. You might need to adjust this symbol to the -# location of the LMFlash utility on your machine -# -ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe -endif - - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := $(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) \ - -mthumb -nostdlib \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) - -ifeq ($(SCRIPT),py) -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -.PHONY : clean show - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QUTEST = $(QUTEST) - @echo HOST = $(HOST) - diff --git a/examples/qutest/TDDbook_Flash/m28w160ect.h b/examples/qutest/TDDbook_Flash/m28w160ect.h deleted file mode 100644 index 0c5c5c4b..00000000 --- a/examples/qutest/TDDbook_Flash/m28w160ect.h +++ /dev/null @@ -1,55 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - -#ifndef D_m28w160ect_H -#define D_m28w160ect_H - -typedef enum -{ - CommandRegister = 0x0, - StatusRegister = 0x0 -} Flash_Registers; - -typedef enum -{ - ProgramCommand = 0x40, - Reset = 0xff -} Flash_Command; - -typedef enum -{ - ReadyBit = 1<<7, - EraseSuspendBit = 1<<6, - EraseErrorBit = 1<<5, - ProgramErrorBit = 1<<4, - VppErrorBit = 1<<3, - ProgramSuspendBit = 1<<2, - BlockProtectionErrorBit = 1<<1, - ReservedBit = 1 -} StatusRegisterBits; - -#endif /* _m28w160ect_H */ diff --git a/examples/qutest/TDDbook_Flash/test_Flash.c b/examples/qutest/TDDbook_Flash/test_Flash.c deleted file mode 100644 index c18240d5..00000000 --- a/examples/qutest/TDDbook_Flash/test_Flash.c +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************** -* Purpose: example 'FlashDriver' QUTEST fixture (Chapter 10 from TDDfEC) -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" /* for QUTEST */ -#include "Flash.h" /* CUT */ -#include "FakeMicroTime.h" /* test double */ - -Q_DEFINE_THIS_FILE - -/* mock initialization -----------------------------------------------------*/ -enum { - FLASH_WRITE = QS_USER0, - FAKE_MICROTIME_INIT, -}; - -void MockIO_Init(void); - -/*--------------------------------------------------------------------------*/ -int main(int argc, char *argv[]) { - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* filter setup */ - QS_FILTER_ON(QS_UA_RECORDS); /* UA==user-all */ - - /* dictionaries... */ - QS_USR_DICTIONARY(FLASH_WRITE); - QS_USR_DICTIONARY(FAKE_MICROTIME_INIT); - - QS_FUN_DICTIONARY(&Flash_Create); - QS_FUN_DICTIONARY(&Flash_Destroy); - QS_FUN_DICTIONARY(&Flash_Write); - - /* initialize the mocks... */ - MockIO_Init(); - - return QF_run(); /* run the tests */ -} - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { - Flash_Create(); -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { - Flash_Destroy(); -} -/*..........................................................................*/ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)param2; - (void)param3; - - //printf(" Command Id=%d,Par1=%ld,Par2=%ld,Par3=%ld\n", - // (int)cmdId, (long)param1, (long)param2, (long)param3); - switch (cmdId) { - case FLASH_WRITE: { - int ret = Flash_Write((ioAddress)param1, (ioData)param2); - QS_BEGIN(FLASH_WRITE, (void *)0) /* user-specific record */ - QS_U32(0, ret); - QS_END() - break; - } - case FAKE_MICROTIME_INIT: { - FakeMicroTime_Init(param1, param2); - QS_BEGIN(FAKE_MICROTIME_INIT, (void *)0) /* user-specific record */ - QS_END() - break; - } - default: - break; - } -} -/*..........................................................................*/ -/*! callback function to "massage" the injected QP events (not used here) */ -void QS_onTestEvt(QEvt *e) { - (void)e; -} diff --git a/examples/qutest/TDDbook_Flash/test_Flash.py b/examples/qutest/TDDbook_Flash/test_Flash.py deleted file mode 100644 index fc844ad3..00000000 --- a/examples/qutest/TDDbook_Flash/test_Flash.py +++ /dev/null @@ -1,200 +0,0 @@ -# QUTEST test script corresponding to the test_Flash.c test fixture. -# see https://www.state-machine.com/qtools/qutest.html -# -# This example corresponds to FlashTest.cpp test from Chapter 10 "The Mock -# Object" of the book: "Test-Driven Development for Embedded Systems" by -# James W. Grenning - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - -# Flash address and data used in this test group -address = 0x1000 -data = 0xBEEF - -# constants from "Flash.h" -FLASH_SUCCESS = 0 -FLASH_VPP_ERROR = 1 -FLASH_PROGRAM_ERROR = 2 -FLASH_PROTECTED_BLOCK_ERROR = 3 -FLASH_UNKNOWN_PROGRAM_ERROR = 4 -FLASH_READ_BACK_ERROR = 5 -FLASH_TIMEOUT_ERROR = 6 - -# constants from "m28w160ect.h" -CommandRegister = 0x0 -StatusRegister = 0x0 - -ProgramCommand = 0x40 -Reset = 0xFF - -ReadyBit = 1<<7 -EraseSuspendBit = 1<<6 -EraseErrorBit = 1<<5 -ProgramErrorBit = 1<<4 -VppErrorBit = 1<<3 -ProgramSuspendBit = 1<<2 -BlockProtectionErrorBit = 1<<1 -ReservedBit = 1<<0 - - -def on_setup(qutest): - qutest.command("FAKE_MICROTIME_INIT",0,1) - qutest.expect("%timestamp FAKE_MICROTIME_INIT") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - - -def test_Write_success_ready_immediately(qutest): - qutest.probe("IO_Read",ReadyBit) - qutest.probe("IO_Read",data) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data=128") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit} {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={data}") - qutest.expect(f"%timestamp IO_CALL IO_Read {data} {address}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_SUCCESS}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_success_not_immediately_ready(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",0) - qutest.probe("IO_Read",0) - qutest.probe("IO_Read",0) - qutest.probe("IO_Read",ReadyBit) - qutest.probe("IO_Read",data) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data=0") - qutest.expect(f"%timestamp IO_CALL IO_Read 0 {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data=0") - qutest.expect(f"%timestamp IO_CALL IO_Read 0 {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data=0") - qutest.expect(f"%timestamp IO_CALL IO_Read 0 {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data=128") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit} {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={data}") - qutest.expect(f"%timestamp IO_CALL IO_Read {data} {address}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_SUCCESS}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Vpp_Error(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",ReadyBit | VppErrorBit) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={ReadyBit|VppErrorBit}") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit|VppErrorBit} {StatusRegister}") - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {Reset}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_VPP_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Program_Error(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",ReadyBit|ProgramErrorBit) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={ReadyBit|ProgramErrorBit}") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit|ProgramErrorBit} {StatusRegister}") - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {Reset}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_PROGRAM_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Protected_Block_Error(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",ReadyBit|BlockProtectionErrorBit) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={ReadyBit|BlockProtectionErrorBit}") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit|BlockProtectionErrorBit} {StatusRegister}") - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {Reset}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_PROTECTED_BLOCK_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Unknown_Program_Error(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",ReadyBit|EraseSuspendBit|EraseErrorBit|ProgramSuspendBit|ReservedBit) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={ReadyBit|EraseSuspendBit|EraseErrorBit|ProgramSuspendBit|ReservedBit}") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit|EraseSuspendBit|EraseErrorBit|ProgramSuspendBit|ReservedBit} {StatusRegister}") - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {Reset}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_UNKNOWN_PROGRAM_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Read_Back_Error(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",ReadyBit) - qutest.probe("IO_Read",data-1) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={ReadyBit}") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit} {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={data-1}") - qutest.expect(f"%timestamp IO_CALL IO_Read {data-1} {address}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_READ_BACK_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_sucess_Ignores_Other_Bits_Until_Ready(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("IO_Read",~ReadyBit&0xFFFF) - qutest.probe("IO_Read",ReadyBit) - qutest.probe("IO_Read",data) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={~ReadyBit&0xFFFF}") - qutest.expect(f"%timestamp IO_CALL IO_Read {~ReadyBit&0xFFFF} {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={ReadyBit}") - qutest.expect(f"%timestamp IO_CALL IO_Read {ReadyBit} {StatusRegister}") - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={data}") - qutest.expect(f"%timestamp IO_CALL IO_Read {data} {address}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_SUCCESS}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Timeout(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("FAKE_MICROTIME_INIT",0,500) - qutest.expect("%timestamp FAKE_MICROTIME_INIT") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - for i in range(10): - qutest.probe("IO_Read",~ReadyBit&0xFFFF) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - for i in range(10): - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={~ReadyBit&0xFFFF}") - qutest.expect(f"%timestamp IO_CALL IO_Read {~ReadyBit&0xFFFF} {StatusRegister}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_TIMEOUT_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - -def test_Write_fails_Timeout_at_End_Of_Time(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("FAKE_MICROTIME_INIT",0xFFFFFFFF,500) - qutest.expect("%timestamp FAKE_MICROTIME_INIT") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - for i in range(10): - qutest.probe("IO_Read",~ReadyBit&0xFFFF) - qutest.command("FLASH_WRITE",address,data) - qutest.expect(f"%timestamp IO_CALL IO_Write {CommandRegister} {ProgramCommand}") - qutest.expect(f"%timestamp IO_CALL IO_Write {address} {data}") - for i in range(10): - qutest.expect(f"%timestamp TstProbe Fun=IO_Read,Data={~ReadyBit&0xFFFF}") - qutest.expect(f"%timestamp IO_CALL IO_Read {~ReadyBit&0xFFFF} {StatusRegister}") - qutest.expect(f"%timestamp FLASH_WRITE {FLASH_TIMEOUT_ERROR}") - qutest.expect(f"%timestamp Trg-Done QS_RX_COMMAND") - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/TDDbook_Flash/test_Flash.tcl b/examples/qutest/TDDbook_Flash/test_Flash.tcl deleted file mode 100644 index 94104874..00000000 --- a/examples/qutest/TDDbook_Flash/test_Flash.tcl +++ /dev/null @@ -1,200 +0,0 @@ -# QUTEST test script corresponding to the test_Flash.c test fixture. -# see https://www.state-machine.com/qtools/qutest.html -# -# This example corresponds to FlashTest.cpp test from Chapter 10 "The Mock -# Object" of the book: "Test-Driven Development for Embedded Systems" by -# James W. Grenning - -# preamble... -proc on_setup {} { - command FAKE_MICROTIME_INIT 0 1 - expect "%timestamp FAKE_MICROTIME_INIT" - expect "%timestamp Trg-Done QS_RX_COMMAND" -} - -set address [expr 0x1000] -set data [expr 0xBEEF] - -# constants from "Flash.h" -set FLASH_SUCCESS 0 -set FLASH_VPP_ERROR 1 -set FLASH_PROGRAM_ERROR 2 -set FLASH_PROTECTED_BLOCK_ERROR 3 -set FLASH_UNKNOWN_PROGRAM_ERROR 4 -set FLASH_READ_BACK_ERROR 5 -set FLASH_TIMEOUT_ERROR 6 - -# constants from "m28w160ect.h" -set CommandRegister [expr 0x0] -set StatusRegister [expr 0x0] - -set ProgramCommand [expr 0x40] -set Reset [expr 0xFF] - -set ReadyBit [expr 1<<7] -set EraseSuspendBit [expr 1<<6] -set EraseErrorBit [expr 1<<5] -set ProgramErrorBit [expr 1<<4] -set VppErrorBit [expr 1<<3] -set ProgramSuspendBit [expr 1<<2] -set BlockProtectionErrorBit [expr 1<<1] -set ReservedBit [expr 1<<0] - -# tests... - -#---------- -test "Write success ready immediately" -probe IO_Read $ReadyBit -probe IO_Read $data -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=128" -expect "%timestamp IO_CALL IO_Read $ReadyBit $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=$data" -expect "%timestamp IO_CALL IO_Read [expr $data] $address" -expect "%timestamp FLASH_WRITE $FLASH_SUCCESS" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write success not immediately ready" -noreset -probe IO_Read 0 -probe IO_Read 0 -probe IO_Read 0 -probe IO_Read $ReadyBit -probe IO_Read $data -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=0" -expect "%timestamp IO_CALL IO_Read 0 $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=0" -expect "%timestamp IO_CALL IO_Read 0 $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=0" -expect "%timestamp IO_CALL IO_Read 0 $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=128" -expect "%timestamp IO_CALL IO_Read $ReadyBit $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=$data" -expect "%timestamp IO_CALL IO_Read [expr $data] $address" -expect "%timestamp FLASH_WRITE $FLASH_SUCCESS" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Vpp Error" -noreset -probe IO_Read [expr $ReadyBit | $VppErrorBit] -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr $ReadyBit | $VppErrorBit]" -expect "%timestamp IO_CALL IO_Read [expr $ReadyBit | $VppErrorBit] $StatusRegister" -expect "%timestamp IO_CALL IO_Write $CommandRegister $Reset" -expect "%timestamp FLASH_WRITE $FLASH_VPP_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Program Error" -noreset -probe IO_Read [expr $ReadyBit | $ProgramErrorBit] -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr $ReadyBit | $ProgramErrorBit]" -expect "%timestamp IO_CALL IO_Read [expr $ReadyBit | $ProgramErrorBit] $StatusRegister" -expect "%timestamp IO_CALL IO_Write $CommandRegister $Reset" -expect "%timestamp FLASH_WRITE $FLASH_PROGRAM_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Protected-Block Error" -noreset -probe IO_Read [expr $ReadyBit | $BlockProtectionErrorBit] -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr $ReadyBit | $BlockProtectionErrorBit]" -expect "%timestamp IO_CALL IO_Read [expr $ReadyBit | $BlockProtectionErrorBit] $StatusRegister" -expect "%timestamp IO_CALL IO_Write $CommandRegister $Reset" -expect "%timestamp FLASH_WRITE $FLASH_PROTECTED_BLOCK_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Unknown Program Error" -noreset -probe IO_Read [expr $ReadyBit | $EraseSuspendBit | $EraseErrorBit | $ProgramSuspendBit | $ReservedBit] -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr $ReadyBit | $EraseSuspendBit | $EraseErrorBit | $ProgramSuspendBit | $ReservedBit]" -expect "%timestamp IO_CALL IO_Read [expr $ReadyBit | $EraseSuspendBit | $EraseErrorBit | $ProgramSuspendBit | $ReservedBit] $StatusRegister" -expect "%timestamp IO_CALL IO_Write $CommandRegister $Reset" -expect "%timestamp FLASH_WRITE $FLASH_UNKNOWN_PROGRAM_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Read-Back Error" -noreset -probe IO_Read $ReadyBit -probe IO_Read [expr $data - 1] -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr $ReadyBit]" -expect "%timestamp IO_CALL IO_Read $ReadyBit $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr $data - 1]" -expect "%timestamp IO_CALL IO_Read [expr $data - 1] $address" -expect "%timestamp FLASH_WRITE $FLASH_READ_BACK_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write sucess Ignores Other Bits Until Ready" -noreset -probe IO_Read [expr ~$ReadyBit] -probe IO_Read $ReadyBit -probe IO_Read $data -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -expect "%timestamp TstProbe Fun=IO_Read,Data=[expr ~$ReadyBit]" -expect "%timestamp IO_CALL IO_Read [expr ~$ReadyBit & 0xFFFF] $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=$ReadyBit" -expect "%timestamp IO_CALL IO_Read $ReadyBit $StatusRegister" -expect "%timestamp TstProbe Fun=IO_Read,Data=$data" -expect "%timestamp IO_CALL IO_Read $data $address" -expect "%timestamp FLASH_WRITE $FLASH_SUCCESS" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Timeout" -noreset -command FAKE_MICROTIME_INIT 0 500 -expect "%timestamp FAKE_MICROTIME_INIT" -expect "%timestamp Trg-Done QS_RX_COMMAND" -for {set i 0} {$i < 10} {incr i} { - probe IO_Read [expr ~$ReadyBit] -} -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -for {set i 0} {$i < 10} {incr i} { - expect "%timestamp TstProbe Fun=IO_Read,Data=[expr ~$ReadyBit]" - expect "%timestamp IO_CALL IO_Read [expr ~$ReadyBit & 0xFFFF] $StatusRegister" -} -expect "%timestamp FLASH_WRITE $FLASH_TIMEOUT_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Write fails Timeout at End-Of-Time" -noreset -command FAKE_MICROTIME_INIT 0xFFFFFFFF 500 -expect "%timestamp FAKE_MICROTIME_INIT" -expect "%timestamp Trg-Done QS_RX_COMMAND" -for {set i 0} {$i < 10} {incr i} { - probe IO_Read [expr ~$ReadyBit] -} -command FLASH_WRITE $address $data -expect "%timestamp IO_CALL IO_Write $CommandRegister $ProgramCommand" -expect "%timestamp IO_CALL IO_Write $address $data" -for {set i 0} {$i < 10} {incr i} { - expect "%timestamp TstProbe Fun=IO_Read,Data=[expr ~$ReadyBit]" - expect "%timestamp IO_CALL IO_Read [expr ~$ReadyBit & 0xFFFF] $StatusRegister" -} -expect "%timestamp FLASH_WRITE $FLASH_TIMEOUT_ERROR" -expect "%timestamp Trg-Done QS_RX_COMMAND" - - -# the end -end - diff --git a/examples/qutest/TDDbook_LedDriver/LedDriver.c b/examples/qutest/TDDbook_LedDriver/LedDriver.c deleted file mode 100644 index cd486866..00000000 --- a/examples/qutest/TDDbook_LedDriver/LedDriver.c +++ /dev/null @@ -1,551 +0,0 @@ -/* -* Modified by Quantum Leaps, LLC -* Replaced RUNTIME_ERROR() with QP assertions -*/ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - -#include "qassert.h" /* for QP assertions */ - -//#include "RuntimeError.h" -#include "LedDriver.h" - -Q_DEFINE_THIS_MODULE("LedDriver") - -enum {ALL_LEDS_OFF = 0, ALL_LEDS_ON = ~0}; - -static uint16_t * ledsAddress; -static uint16_t ledsImage; - -void LedDriver_Create(uint16_t * address) -{ - ledsAddress = address; - ledsImage = ALL_LEDS_OFF; - *ledsAddress = ledsImage; -} - -void LedDriver_Destroy(void) -{ -} - -enum {FIRST_LED = 1, LAST_LED = 16}; - -static BOOL IsLedOutOfBounds(int ledNumber) -{ - if ((ledNumber < FIRST_LED) || (ledNumber > LAST_LED)) - { - //RUNTIME_ERROR("LED Driver: out-of-bounds LED", ledNumber); - Q_ERROR_ID(100); /* QP assertion */ - return TRUE; - } - return FALSE; -} - -static uint16_t convertLedNumberToBit(int ledNumber) -{ - return 1 << (ledNumber - 1); -} - -static void updateHardware(void) -{ - *ledsAddress = ledsImage; -} - -static void setLedImageBit(int ledNumber) -{ - ledsImage |= convertLedNumberToBit(ledNumber); -} -void LedDriver_TurnOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - setLedImageBit(ledNumber); - updateHardware(); -} - -static void clearLedImageBit(int ledNumber) -{ - ledsImage &= ~convertLedNumberToBit(ledNumber); -} -void LedDriver_TurnOff(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - clearLedImageBit(ledNumber); - updateHardware(); -} - -void LedDriver_TurnAllOn(void) -{ - ledsImage = ALL_LEDS_ON; - updateHardware(); -} - -void LedDriver_TurnAllOff(void) -{ - ledsImage = ALL_LEDS_OFF; - updateHardware(); -} - -BOOL LedDriver_IsOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return FALSE; - - return 0 != (ledsImage & convertLedNumberToBit(ledNumber)); -} - -BOOL LedDriver_IsOff(int ledNumber) -{ - return !LedDriver_IsOn(ledNumber); -} - - -/* - * Intermediate examples below this comment - */ - -#if 0 -BOOL LedDriver_IsOff(int ledNumber) -{ - return FALSE; /* !LedDriver_IsOn(ledNumber); */ -} -#endif - - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - return 0 != (ledsImage & convertLedNumberToBit(ledNumber)); -} -#endif - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - return TRUE; - /* return 0 != (ledsImage & convertLedNumberToBit(ledNumber)); */ -} -#endif - - -#if 0 -enum {ALL_LEDS_ON = ~0, ALL_LEDS_OFF = ~ALL_LEDS_ON}; - -static uint16_t * ledsAddress; -static uint16_t ledsImage; - -void LedDriver_Create(uint16_t * address) -{ - ledsAddress = address; - ledsImage = ALL_LEDS_OFF; - *ledsAddress = ledsImage; -} - -void LedDriver_Destroy(void) -{ -} - -#if 0 -enum {FIRST_LED = 1, LAST_LED = 16}; -static BOOL IsLedOutOfBounds(int ledNumber) -{ - return (ledNumber < FIRST_LED) || (ledNumber > LAST_LED); -} -#endif - -enum {FIRST_LED = 1, LAST_LED = 16}; - -static BOOL IsLedOutOfBounds(int ledNumber) -{ - if ((ledNumber < FIRST_LED) || (ledNumber > LAST_LED)) - { - RUNTIME_ERROR("LED Driver: out-of-bounds LED", ledNumber); - return TRUE; - } - return FALSE; -} - -static uint16_t convertLedNumberToBit(int ledNumber) -{ - return 1 << (ledNumber - 1); -} - -static void updateHardware(void) -{ - *ledsAddress = ledsImage; -} - -static void setLedImageBit(int ledNumber) -{ - ledsImage |= convertLedNumberToBit(ledNumber); - updateHardware(); -} - - -void LedDriver_TurnOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - setLedImageBit(ledNumber); -} - -static void clearLedImageBit(int ledNumber) -{ - ledsImage &= ~convertLedNumberToBit(ledNumber); - updateHardware(); -} - -void LedDriver_TurnOff(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - clearLedImageBit(ledNumber); -} - - -void LedDriver_TurnAllOn(void) -{ - ledsImage = ALL_LEDS_ON; - updateHardware(); -} - -void LedDriver_TurnAllOff(void) -{ - ledsImage = ALL_LEDS_OFF; - updateHardware(); -} - -BOOL LedDriver_IsOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return FALSE; - - return 0 != (ledsImage & convertLedNumberToBit(ledNumber)); -} - -BOOL LedDriver_IsOff(int ledNumber) -{ - return !LedDriver_IsOn(ledNumber); -} -#endif - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - return ledsImage & (convertLedNumberToBit(ledNumber)); -} -#endif - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return FALSE; - - return ledsImage & (convertLedNumberToBit(ledNumber)); -} -#endif - - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - ledsImage |= convertLedNumberToBit(ledNumber); - updateHardware(); -} -void LedDriver_TurnOff(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - ledsImage &= ~(convertLedNumberToBit(ledNumber)); - updateHardware(); -} -#endif - -#if 0 -#include "LedDriver.h" - -void LedDriver_Create(uint16_t * address) -{ -} - -void LedDriver_Destroy(void) -{ -} -#endif - -#if 0 -void LedDriver_Create(uint16_t * address) -{ - *address = 0; -} -#endif - -#if 0 -void LedDriver_Create(uint16_t * address) -{ - ledsAddress = address; - *ledsAddress = 0; -} -#endif - - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - *ledsAddress = 1; -} -#endif - - -#if 0 -#include "LedDriver.h" - -static uint16_t * ledsAddress; - -void LedDriver_Create(uint16_t * address) -{ - ledsAddress = address; - *ledsAddress = 0; -} - -void LedDriver_Destroy(void) -{ -} - -void LedDriver_TurnOn(int ledNumber) -{ - *ledsAddress = 1; -} - -void LedDriver_TurnOff(int ledNumber) -{ - *ledsAddress = 0; -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - *ledsAddress |= (1 << ledNumber); -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - *ledsAddress |= 1 << (ledNumber - 1); -} -#endif - -#if 0 -static uint16_t convertLedNumberToBit(int ledNumber) -{ - return 1 << (ledNumber - 1); -} -void LedDriver_TurnOn(int ledNumber) -{ - *ledsAddress |= convertLedNumberToBit(ledNumber); -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - ledsImage |= convertLedNumberToBit(ledNumber); - *ledsAddress = ledsImage; -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - if (ledNumber <= 0 || ledNumber > 16) - return; - - ledsImage |= convertLedNumberToBit(ledNumber); - updateHardware(); -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - /* if (IsLedOutOfBounds(ledNumber)) */ - /* return; */ - - if (ledNumber <= 0 || ledNumber > 16) - return; - - ledsImage |= convertLedNumberToBit(ledNumber); - updateHardware(); -} -#endif - -#if 0 -void LedDriver_TurnOff(int ledNumber) -{ - *ledsAddress = 0; -} -#endif - -#if 0 -void LedDriver_TurnOff(int ledNumber) -{ - *ledsAddress &= ~(convertLedNumberToBit(ledNumber)); -} -#endif - -#if 0 -void LedDriver_TurnOff(int ledNumber) -{ - ledsImage &= ~(convertLedNumberToBit(ledNumber)); - *ledsAddress = ledsImage; -} -#endif -#if 0 - -void LedDriver_TurnOff(int ledNumber) -{ - if (ledNumber <= 0 || ledNumber > 16) - return; - - ledsImage &= ~(convertLedNumberToBit(ledNumber)); - updateHardware(); -} -#endif - -#if 0 -void LedDriver_TurnAllOn(void) -{ - *ledsAddress = 0xffff; -} -#endif - -#if 0 -enum {ALL_LEDS_ON = ~0, ALL_LEDS_OFF = ~ALL_LEDS_ON}; - -void LedDriver_TurnAllOn(void) -{ - *ledsAddress = ALL_LEDS_ON; -} -#endif - -#if 0 -void LedDriver_TurnAllOn(void) -{ - ledsImage = ALL_LEDS_ON; - *ledsAddress = ledsImage; -} -#endif - -#if 0 -void LedDriver_TurnAllOn(void) -{ -} -#endif - -#if 0 -void LedDriver_TurnAllOff(void) -{ - ledsImage = ALL_LEDS_OFF; - updateHardware(); -} -#endif - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - return FALSE; -} -#endif - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - return TRUE; -} -#endif - -#if 0 -BOOL LedDriver_IsOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return FALSE; - - return FALSE; -} -#endif - -#if 0 -void LedDriver_TurnOn(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - ledsImage |= convertLedNumberToBit(ledNumber); - updateHardware(); -} - -void LedDriver_TurnOff(int ledNumber) -{ - if (IsLedOutOfBounds(ledNumber)) - return; - - ledsImage &= ~convertLedNumberToBit(ledNumber); - updateHardware(); -} -#endif - -#if 0 -void LedDriver_TurnAllOn(void) -{ - ledsImage = ALL_LEDS_ON; - *ledsAddress = ledsImage; -} - -void LedDriver_TurnAllOff(void) -{ - ledsImage = ALL_LEDS_OFF; - *ledsAddress = ledsImage; -} -#endif - diff --git a/examples/qutest/TDDbook_LedDriver/LedDriver.h b/examples/qutest/TDDbook_LedDriver/LedDriver.h deleted file mode 100644 index 95d852aa..00000000 --- a/examples/qutest/TDDbook_LedDriver/LedDriver.h +++ /dev/null @@ -1,76 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - -#ifndef D_LedDriver_H -#define D_LedDriver_H -#include - -#define TRUE 1 -#define FALSE 0 -typedef int BOOL; - - -void LedDriver_Create(uint16_t * ledsAddress); -void LedDriver_Destroy(void); - -void LedDriver_TurnOn(int ledNumber); -void LedDriver_TurnOff(int ledNumber); -void LedDriver_TurnAllOn(void); -void LedDriver_TurnAllOff(void); -BOOL LedDriver_IsOn(int ledNumber); -BOOL LedDriver_IsOff(int ledNumber); -#endif /* D_LedDriver_H */ - -/* - * Intermediate examples below this comment - */ - -#if 0 -#ifndef D_LedDriver_H -#define D_LedDriver_H - -void LedDriver_Create(void); -void LedDriver_Destroy(void); - -#endif /* D_LedDriver_H */ - -#if 0 -#ifndef D_LedDriver_H -#define D_LedDriver_H - -void LedDriver_Create(void); -void LedDriver_Destroy(void); -void LedDriver_TurnOn(int ledNumber); -void LedDriver_TurnOff(int ledNumber); - -#endif - - -#endif /* D_LedDriver_H */ - - -#endif diff --git a/examples/qutest/TDDbook_LedDriver/LedDriverTest.c b/examples/qutest/TDDbook_LedDriver/LedDriverTest.c deleted file mode 100644 index edf863ff..00000000 --- a/examples/qutest/TDDbook_LedDriver/LedDriverTest.c +++ /dev/null @@ -1,297 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - -#include "unity_fixture.h" -#include "LedDriver.h" -#include "RuntimeErrorStub.h" - - -TEST_GROUP(LedDriver); -static uint16_t virtualLeds; -TEST_SETUP(LedDriver) -{ - LedDriver_Create(&virtualLeds); -} - -TEST_TEAR_DOWN(LedDriver) -{ -} - -TEST(LedDriver, LedsOffAfterCreate) -{ - uint16_t virtualLeds = 0xffff; - LedDriver_Create(&virtualLeds); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} -TEST(LedDriver, TurnOnLedOne) -{ - LedDriver_TurnOn(1); - TEST_ASSERT_EQUAL_HEX16(1, virtualLeds); -} -TEST(LedDriver, TurnOffLedOne) -{ - LedDriver_TurnOn(1); - LedDriver_TurnOff(1); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} - -TEST(LedDriver, TurnOnMultipleLeds) -{ - LedDriver_TurnOn(9); - LedDriver_TurnOn(8); - TEST_ASSERT_EQUAL_HEX16(0x180, virtualLeds); -} - -TEST(LedDriver, TurnOffMultipleLeds) -{ - LedDriver_TurnAllOn(); - LedDriver_TurnOff(9); - LedDriver_TurnOff(8); - TEST_ASSERT_EQUAL_HEX16((~0x180)&0xffff, virtualLeds); -} - -TEST(LedDriver, TurnOffAnyLed) -{ - LedDriver_TurnAllOn(); - LedDriver_TurnOff(8); - TEST_ASSERT_EQUAL_HEX16(0xff7f, virtualLeds); -} - -TEST(LedDriver, LedMemoryIsNotReadable) -{ - virtualLeds = 0xffff; - LedDriver_TurnOn(8); - TEST_ASSERT_EQUAL_HEX16(0x80, virtualLeds); -} - -TEST(LedDriver, UpperAndLowerBounds) -{ - LedDriver_TurnOn(1); - LedDriver_TurnOn(16); - TEST_ASSERT_EQUAL_HEX16(0x8001, virtualLeds); -} - -TEST(LedDriver, OutOfBoundsTurnOnDoesNoHarm) -{ - LedDriver_TurnOn(-1); - LedDriver_TurnOn(0); - LedDriver_TurnOn(17); - LedDriver_TurnOn(3141); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} - -TEST(LedDriver, OutOfBoundsTurnOffDoesNoHarm) -{ - LedDriver_TurnAllOn(); - - LedDriver_TurnOff(-1); - LedDriver_TurnOff(0); - LedDriver_TurnOff(17); - LedDriver_TurnOff(3141); - TEST_ASSERT_EQUAL_HEX16(0xffff, virtualLeds); -} - -IGNORE_TEST(LedDriver, OutOfBoundsToDo) -{ - /* TODO: what should we do during runtime? */ -} - -TEST(LedDriver, OutOfBoundsProducesRuntimeError) -{ - LedDriver_TurnOn(-1); - TEST_ASSERT_EQUAL_STRING("LED Driver: out-of-bounds LED", - RuntimeErrorStub_GetLastError()); - TEST_ASSERT_EQUAL(-1, RuntimeErrorStub_GetLastParameter()); -} - -TEST(LedDriver, IsOn) -{ - TEST_ASSERT_FALSE(LedDriver_IsOn(11)); - LedDriver_TurnOn(11); - TEST_ASSERT_TRUE(LedDriver_IsOn(11)); -} - -TEST(LedDriver, IsOff) -{ - TEST_ASSERT_TRUE(LedDriver_IsOff(12)); - LedDriver_TurnOn(12); - TEST_ASSERT_FALSE(LedDriver_IsOff(12)); -} - -TEST(LedDriver, OutOfBoundsLedsAreAlwaysOff) -{ - TEST_ASSERT_TRUE(LedDriver_IsOff(0)); - TEST_ASSERT_TRUE(LedDriver_IsOff(17)); - TEST_ASSERT_FALSE(LedDriver_IsOn(0)); - TEST_ASSERT_FALSE(LedDriver_IsOn(17)); -} - -TEST(LedDriver, AllOn) -{ - LedDriver_TurnAllOn(); - TEST_ASSERT_EQUAL_HEX16(0xffff, virtualLeds); -} - -TEST(LedDriver, AllOff) -{ - LedDriver_TurnAllOn(); - LedDriver_TurnAllOff(); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} - -/* - * Intermediate examples below this comment - */ - -#if 0 -TEST(LedDriver, TurnOnLedOne) -{ - uint16_t virtualLeds; - LedDriver_Create(&virtualLeds); - LedDriver_TurnOn(1); - TEST_ASSERT_EQUAL_HEX16(1, virtualLeds); -} - -TEST(LedDriver, TurnOffLedOne) -{ - uint16_t virtualLeds; - LedDriver_Create(&virtualLeds); - LedDriver_TurnOn(1); - LedDriver_TurnOff(1); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} -#endif - - - -#if 0 -TEST(LedDriver, AllOn) -{ - LedDriver_TurnAllOn(); - TEST_ASSERT_TRUE(LedDriver_IsOn(1)); - TEST_ASSERT_TRUE(LedDriver_IsOn(8)); - TEST_ASSERT_TRUE(LedDriver_IsOn(16)); - TEST_ASSERT_EQUAL_HEX16(0xffff, virtualLeds); -} -#endif - - -#if 0 -TEST(LedDriver, TurnOffAnyLed) -{ - LedDriver_TurnOn(9); - LedDriver_TurnOn(8); - LedDriver_TurnOff(8); - TEST_ASSERT_EQUAL_HEX16(0x100, virtualLeds); -} - -TEST(LedDriver, LedsOffAfterCreate) -{ - virtualLeds = 0xffff; - LedDriver_Create(&virtualLeds); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} -TEST(LedDriver, OutOfBoundsChangesNothing) -{ - LedDriver_TurnOn(-1); - LedDriver_TurnOn(0); - LedDriver_TurnOn(17); - LedDriver_TurnOn(3141); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} -TEST(LedDriver, OutOfBoundsChangesNothing) -{ - LedDriver_TurnOn(-1); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); - LedDriver_TurnOn(0); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); - LedDriver_TurnOn(17); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); - LedDriver_TurnOn(33); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); - LedDriver_TurnOn(3141); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} -TEST(LedDriver, OutOfBoundsTurnOffDoesNoHarm) -{ - LedDriver_TurnOff(-1); - LedDriver_TurnOff(0); - LedDriver_TurnOff(17); - LedDriver_TurnOff(3141); - TEST_ASSERT_EQUAL_HEX16(0, virtualLeds); -} -TEST(LedDriver, OutOfBoundsTurnOffDoesNoHarm) -{ - LedDriver_TurnAllOn(); - LedDriver_TurnOff(-1); - LedDriver_TurnOff(0); - LedDriver_TurnOff(17); - LedDriver_TurnOff(3141); - TEST_ASSERT_EQUAL_HEX16(0xffff, virtualLeds); -} - -TEST(LedDriver, OutOfBoundsLedsAreAlwaysOff) -{ - TEST_ASSERT_FALSE(LedDriver_IsOn(0)); - TEST_ASSERT_FALSE(LedDriver_IsOn(17)); -} -#endif - -#if 0 -#include "unity_fixture.h" -TEST_GROUP(LedDriver); - -TEST_SETUP(LedDriver) -{ -} - -TEST_TEAR_DOWN(LedDriver) -{ -} - -TEST(LedDriver, LedsOffAfterCreate) -{ - TEST_FAIL_MESSAGE("Start here"); -} - -TEST_GROUP(LedDriver) - -TEST_SETUP(LedDriver) -{ -} - -TEST_TEAR_DOWN(LedDriver) -{ -} - - -TEST(LedDriver, LedsOffAfterCreate) -{ -} - -#endif - diff --git a/examples/qutest/TDDbook_LedDriver/Makefile b/examples/qutest/TDDbook_LedDriver/Makefile deleted file mode 100644 index ba353c9c..00000000 --- a/examples/qutest/TDDbook_LedDriver/Makefile +++ /dev/null @@ -1,245 +0,0 @@ -############################################################################## -# Product: Makefile for QUTEST self-test; QP/C on Win32 host -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make # make and run the tests in the current directory -# make TESTS=test*.tcl # make and run the selected tests in the curr. dir. -# make SCRIPT=py # make and run the Python tests -# make HOST=localhost:7705 # connect to host:port -# make norun # only make but not run the tests -# make clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_LedDriver - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - -# list of all source directories used by this project -VPATH = \ - . - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - LedDriver.c \ - test_LedDriver.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -DEFINES := - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -ifeq ($(SCRIPT),py) -run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - @echo HOST = $(HOST) - diff --git a/examples/qutest/TDDbook_LedDriver/test_LedDriver.c b/examples/qutest/TDDbook_LedDriver/test_LedDriver.c deleted file mode 100644 index a35905f8..00000000 --- a/examples/qutest/TDDbook_LedDriver/test_LedDriver.c +++ /dev/null @@ -1,163 +0,0 @@ -/***************************************************************************** -* Purpose: example 'LedDriver' QUTEST fixture (Chapters 3&4 from TDDfEC) -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-05-20 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" /* for QUTEST */ -#include "LedDriver.h" /* CUT */ - -Q_DEFINE_THIS_FILE - -/*--------------------------------------------------------------------------*/ -static uint16_t virtualLeds; - -enum { - LEDDRIVER_CREATE = QS_USER, - LEDDRIVER_DESTROY, - LEDDRIVER_TURNON, - LEDDRIVER_TURNOFF, - LEDDRIVER_TURNALLON, - LEDDRIVER_TURNALLOFF, - LEDDRIVER_ISON, - LEDDRIVER_ISOFF, -}; - -/*--------------------------------------------------------------------------*/ -int main(int argc, char *argv[]) { - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* filter setup */ - QS_FILTER_ON(QS_UA_RECORDS); /* UA==user-all */ - - /* dictionaries... */ - QS_OBJ_DICTIONARY(&virtualLeds); - QS_USR_DICTIONARY(LEDDRIVER_CREATE); - QS_USR_DICTIONARY(LEDDRIVER_DESTROY); - QS_USR_DICTIONARY(LEDDRIVER_TURNON); - QS_USR_DICTIONARY(LEDDRIVER_TURNOFF); - QS_USR_DICTIONARY(LEDDRIVER_TURNALLON); - QS_USR_DICTIONARY(LEDDRIVER_TURNALLOFF); - QS_USR_DICTIONARY(LEDDRIVER_ISON); - QS_USR_DICTIONARY(LEDDRIVER_ISOFF); - - return QF_run(); /* run the tests */ -} - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { - LedDriver_Create(&virtualLeds); -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { - LedDriver_Destroy(); -} -/*..........................................................................*/ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)param2; - (void)param3; - BOOL ret; - - //printf(" Command Id=%d,Par1=%ld,Par2=%ld,Par3=%ld\n", - // (int)cmdId, (long)param1, (long)param2, (long)param3); - switch (cmdId) { - case LEDDRIVER_CREATE: { - LedDriver_Create(&virtualLeds); - QS_BEGIN(LEDDRIVER_CREATE, (void *)0) /* user-specific record */ - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_DESTROY: { - LedDriver_Destroy(); - QS_BEGIN(LEDDRIVER_DESTROY, (void *)0) /* user-specific record */ - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_TURNON: { - LedDriver_TurnOn((int)param1); - QS_BEGIN(LEDDRIVER_TURNON, (void *)0) /* user-specific record */ - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_TURNOFF: { - LedDriver_TurnOff((int)param1); - QS_BEGIN(LEDDRIVER_TURNOFF, (void *)0) - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_TURNALLON: { - LedDriver_TurnAllOn(); - QS_BEGIN(LEDDRIVER_TURNALLON, (void *)0) - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_TURNALLOFF: { - LedDriver_TurnAllOff(); - QS_BEGIN(LEDDRIVER_TURNALLOFF, (void *)0) - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_ISON: { - ret = LedDriver_IsOn((int)param1); - QS_BEGIN(LEDDRIVER_ISON, (void *)0) - QS_U8(1, ret); - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - case LEDDRIVER_ISOFF: { - ret = LedDriver_IsOff((int)param1); - QS_BEGIN(LEDDRIVER_ISOFF, (void *)0) - QS_U8(1, ret); - QS_U32_HEX(4, (uint32_t)virtualLeds); - QS_END() - break; - } - default: - break; - } -} -/*..........................................................................*/ -/*! callback function to "massage" the injected QP events (not used here) */ -void QS_onTestEvt(QEvt *e) { - (void)e; -} diff --git a/examples/qutest/TDDbook_LedDriver/test_LedDriver.py b/examples/qutest/TDDbook_LedDriver/test_LedDriver.py deleted file mode 100644 index 3b354c8b..00000000 --- a/examples/qutest/TDDbook_LedDriver/test_LedDriver.py +++ /dev/null @@ -1,80 +0,0 @@ -# QUTEST test script corresponding to the test_LedDriver.c test fixture. -# see https://www.state-machine.com/qtools/qutest.html -# -# This example corresponds to LedDriver.c from Chapters 3 & 4 "Starting -# a C Module" & "Testing Your Way to Done" of the book: "Test-Driven -# Development for Embedded Systems" by James W. Grenning - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def test_LEDs_off_after_Create(qutest): - qutest.command("LEDDRIVER_CREATE") - qutest.expect("%timestamp LEDDRIVER_CREATE 0x0000") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_Turn_on_LED_1(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("LEDDRIVER_TURNON",1) - qutest.expect("%timestamp LEDDRIVER_TURNON 0x0001") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_Turn_off_LED_1(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("LEDDRIVER_TURNOFF",1) - qutest.expect("%timestamp LEDDRIVER_TURNOFF 0x0000") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_Turn_on_multiple_LEDs(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("LEDDRIVER_TURNON",9) - qutest.expect("%timestamp LEDDRIVER_TURNON 0x0100") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("LEDDRIVER_TURNON",8) - qutest.expect("%timestamp LEDDRIVER_TURNON 0x0180") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_Turn_off_multiple_LEDs(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("LEDDRIVER_TURNALLON") - qutest.expect("%timestamp LEDDRIVER_TURNALLON 0xFFFF") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("LEDDRIVER_TURNOFF",9) - qutest.expect("%timestamp LEDDRIVER_TURNOFF 0xFEFF") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("LEDDRIVER_TURNOFF",8) - qutest.expect("%timestamp LEDDRIVER_TURNOFF 0xFE7F") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_Out_of_bounds_produces_Runtime_Error(qutest_noreset): - qutest = qutest_noreset # name change - qutest.command("LEDDRIVER_TURNON", (-1 & 0xFFFFFFFF)) - qutest.expect("%timestamp =ASSERT= Mod=LedDriver,Loc=100") - -def test_Turn_off_any_LED(qutest): - qutest.command("LEDDRIVER_TURNALLON") - qutest.expect("%timestamp LEDDRIVER_TURNALLON 0xFFFF") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("LEDDRIVER_TURNOFF",8) - qutest.expect("%timestamp LEDDRIVER_TURNOFF 0xFF7F") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_LED_memory_is_not_readable(qutest_noreset): - qutest = qutest_noreset # name change - qutest.current_obj(QS_OBJ_KIND.AP,"virtualLeds") - qutest.poke(0,2,struct.pack('") - qutest.command("LEDDRIVER_TURNON",8) - qutest.expect("%timestamp LEDDRIVER_TURNON 0x0080") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/TDDbook_LedDriver/test_LedDriver.tcl b/examples/qutest/TDDbook_LedDriver/test_LedDriver.tcl deleted file mode 100644 index db2eedb6..00000000 --- a/examples/qutest/TDDbook_LedDriver/test_LedDriver.tcl +++ /dev/null @@ -1,75 +0,0 @@ -# QUTEST test script corresponding to the test_LedDriver.c test fixture. -# see https://www.state-machine.com/qtools/qutest.html -# -# This example corresponds to LedDriver.c from Chapters 3 & 4 "Starting -# a C Module" & "Testing Your Way to Done" of the book: "Test-Driven -# Development for Embedded Systems" by James W. Grenning - -# tests... - -#---------- -test "LEDs off after Create" -command LEDDRIVER_CREATE -expect "%timestamp LEDDRIVER_CREATE 0x0000" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Turn on LED(1)" -noreset -command LEDDRIVER_TURNON 1 -expect "%timestamp LEDDRIVER_TURNON 0x0001" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Turn off LED(1)" -noreset -command LEDDRIVER_TURNOFF 1 -expect "%timestamp LEDDRIVER_TURNOFF 0x0000" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Turn on multiple LEDs" -noreset -command LEDDRIVER_TURNON 9 -expect "%timestamp LEDDRIVER_TURNON 0x0100" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command LEDDRIVER_TURNON 8 -expect "%timestamp LEDDRIVER_TURNON 0x0180" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Turn off multiple LEDs" -noreset -command LEDDRIVER_TURNALLON -expect "%timestamp LEDDRIVER_TURNALLON 0xFFFF" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command LEDDRIVER_TURNOFF 9 -expect "%timestamp LEDDRIVER_TURNOFF 0xFEFF" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command LEDDRIVER_TURNOFF 8 -expect "%timestamp LEDDRIVER_TURNOFF 0xFE7F" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Out of bounds produces Runtime Error" -noreset -command LEDDRIVER_TURNON -1 -expect "%timestamp =ASSERT= Mod=LedDriver,Loc=100" - -#---------- -test "Turn off any LED" -command LEDDRIVER_TURNALLON -expect "%timestamp LEDDRIVER_TURNALLON 0xFFFF" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command LEDDRIVER_TURNOFF 8 -expect "%timestamp LEDDRIVER_TURNOFF 0xFF7F" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "LED memory is not readable" -noreset -current_obj AP virtualLeds -poke 0 2 [binary format s 0xFFFF] -peek 0 2 1 -expect "%timestamp Trg-Peek Offs=0,Size=2,Num=1,Data=" -command LEDDRIVER_TURNON 8 -expect "%timestamp LEDDRIVER_TURNON 0x0080" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -# the end -end - diff --git a/examples/qutest/TDDbook_Sprintf/SprintfTest.c b/examples/qutest/TDDbook_Sprintf/SprintfTest.c deleted file mode 100644 index dca990e1..00000000 --- a/examples/qutest/TDDbook_Sprintf/SprintfTest.c +++ /dev/null @@ -1,146 +0,0 @@ -/*** - * Excerpted from "Test-Driven Development for Embedded C", - * published by The Pragmatic Bookshelf. - * Copyrights apply to this code. It may not be used to create training material, - * courses, books, articles, and the like. Contact us if you are in doubt. - * We make no guarantees that this code is fit for any purpose. - * Visit http://www.pragmaticprogrammer.com/titles/jgade for more book information. -***/ -/*- ------------------------------------------------------------------ -*/ -/*- Copyright (c) James W. Grenning -- All Rights Reserved -*/ -/*- For use by owners of Test-Driven Development for Embedded C, -*/ -/*- and attendees of Renaissance Software Consulting, Co. training -*/ -/*- classes. -*/ -/*- -*/ -/*- Available at http://pragprog.com/titles/jgade/ -*/ -/*- ISBN 1-934356-62-X, ISBN13 978-1-934356-62-3 -*/ -/*- -*/ -/*- Authorized users may use this source code in your own -*/ -/*- projects, however the source code may not be used to -*/ -/*- create training material, courses, books, articles, and -*/ -/*- the like. We make no guarantees that this source code is -*/ -/*- fit for any purpose. -*/ -/*- -*/ -/*- www.renaissancesoftware.net james@renaissancesoftware.net -*/ -/*- ------------------------------------------------------------------ -*/ - - -#include "unity_fixture.h" -#include -#include - -TEST_GROUP(sprintf); - -static char output[100]; -static const char * expected; - -TEST_SETUP(sprintf) -{ - memset(output, 0xaa, sizeof output); - expected = ""; -} - -TEST_TEAR_DOWN(sprintf) -{ -} - -static void expect(const char * s) -{ - expected = s; -} - -static void given(int charsWritten) -{ - TEST_ASSERT_EQUAL(strlen(expected), charsWritten); - TEST_ASSERT_EQUAL_STRING(expected, output); - TEST_ASSERT_BYTES_EQUAL(0xaa, output[strlen(expected) + 1]); -} - - -#if 1 -TEST(sprintf, NoFormatOperations) -{ - expect("hey"); - given(sprintf(output, "hey")); -} - -TEST(sprintf, InsertString) -{ - expect("Hello World\n"); - given(sprintf(output, "Hello %s\n", "World")); -} -#endif - -/* to run this also change in SprintfTestRunner.c */ -#if 0 -TEST(sprintf, NoFormatOperations) -{ - char output[5]; - - TEST_ASSERT_EQUAL(4, sprintf(output, "hey")); - TEST_ASSERT_EQUAL_STRING("hey", output); -} -#endif - -#if 0 -TEST(sprintf, NoFormatOperations) -{ - char output[5]; - memset(output, 0xaa, sizeof output); - - TEST_ASSERT_EQUAL(3, sprintf(output, "hey")); - TEST_ASSERT_EQUAL_STRING("hey", output); - TEST_ASSERT_BYTES_EQUAL(0xaa, output[4]); -} - -TEST(sprintf, InsertString) -{ - char output[20]; - memset(output, 0xaa, sizeof output); - - TEST_ASSERT_EQUAL(12, sprintf(output, "Hello %s\n", "World")); - TEST_ASSERT_EQUAL_STRING("Hello World\n", output); - TEST_ASSERT_BYTES_EQUAL(0xaa, output[13]); -} -#endif - -#if 0 -TEST(sprintf, NoFormatOperations) -{ - char output[5]; - - TEST_ASSERT_EQUAL(3, sprintf(output, "hey")); - TEST_ASSERT_EQUAL_STRING("hey", output); -} -#endif - -#if 0 -TEST(sprintf, NoFormatOperations) -{ - char output[5] = ""; - TEST_ASSERT_EQUAL(3, sprintf(output, "hey")); - TEST_ASSERT_EQUAL_STRING("hey", output); -} -#endif - -#if 0 -TEST(sprintf, NoFormatOperations) -{ - char output[5]; - memset(output, 0xaa, sizeof output); - - TEST_ASSERT_EQUAL(3, sprintf(output, "hey")); - TEST_ASSERT_EQUAL_STRING("hey", output); -} -#endif - - -#if 0 -TEST(sprintf, InsertString) -{ - char output[20] = ""; - - TEST_ASSERT_EQUAL(12, sprintf(output, "Hello %s\n", "World")); - TEST_ASSERT_EQUAL_STRING("Hello World\n", output); -} -#endif diff --git a/examples/qutest/TDDbook_Sprintf/test_Sprintf.c b/examples/qutest/TDDbook_Sprintf/test_Sprintf.c deleted file mode 100644 index c99607dc..00000000 --- a/examples/qutest/TDDbook_Sprintf/test_Sprintf.c +++ /dev/null @@ -1,95 +0,0 @@ -/***************************************************************************** -* Purpose: example 'sprintf' QUTEST fixture -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" /* QUTest interface */ - -#include /* CUT interface */ - -Q_DEFINE_THIS_FILE - -/*--------------------------------------------------------------------------*/ -static char format[20]; -static char output[100]; -static char string[20]; - -enum { - SPRINTF_CALL = QS_USER, -}; - -/*--------------------------------------------------------------------------*/ -int main(int argc, char *argv[]) { - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* dictionaries... */ - QS_OBJ_DICTIONARY(format); - QS_OBJ_DICTIONARY(output); - QS_OBJ_DICTIONARY(string); - QS_USR_DICTIONARY(SPRINTF_CALL); - - return QF_run(); /* run the tests */ -} - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { -} - -/*..........................................................................*/ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - switch (cmdId) { - case 0: { /* call the CUT and report results */ - int ret = sprintf(&output[8], - format, param1, string, param2, param3); - QS_BEGIN(SPRINTF_CALL, (void *)0) /* user-specific record */ - QS_U8(0, (uint8_t)ret); /* return value */ - QS_STR(&output[8]); /* produced string */ - QS_END() - break; - } - default: - break; - } -} -/*..........................................................................*/ -/*! callback function to "massage" the injected QP events (not used here) */ -void QS_onTestEvt(QEvt *e) { - (void)e; -} diff --git a/examples/qutest/TDDbook_Sprintf/test_Sprintf.py b/examples/qutest/TDDbook_Sprintf/test_Sprintf.py deleted file mode 100644 index cec48978..00000000 --- a/examples/qutest/TDDbook_Sprintf/test_Sprintf.py +++ /dev/null @@ -1,53 +0,0 @@ -# QUTEST test script corresponding to the test_Sprintf.c test fixture. -# see https://www.state-machine.com/qtools/qutest.html -# -# This example corresponds to SprintfTest.c from Chapter 2 "Test-Driving -# Tools and Conventions" of the book: "Test-Driven Development for Embedded -# Systems" by James W. Grenning - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - -def test_No_format_operations(qutest): - qutest.glb_filter(FILTER.UA) - qutest.current_obj(QS_OBJ_KIND.AP,"format") - qutest.poke(0,1,bytes("Hello World!\0",'ascii')) - qutest.command(0) - qutest.expect("0000000001 SPRINTF_CALL 12 Hello World!") - qutest.expect("0000000002 Trg-Done QS_RX_COMMAND") - -def test_Insert_decimal(qutest_noreset): - qutest = qutest_noreset # name change - qutest.current_obj(QS_OBJ_KIND.AP,"format") - qutest.poke(0,1,bytes("dec=%d\0",'ascii')) - qutest.command(0,1234) - qutest.expect("0000000001 SPRINTF_CALL 8 dec=1234") - qutest.expect("0000000002 Trg-Done QS_RX_COMMAND") - -def test_Insert_decimal_and_string(qutest_noreset): - qutest = qutest_noreset # name change - qutest.current_obj(QS_OBJ_KIND.AP,"format") - qutest.poke(0,1,bytes("dec=%d, str=%s\0",'ascii')) - qutest.current_obj(QS_OBJ_KIND.AP,"string") - qutest.poke(0,1,bytes("Hello\0",'ascii')) - qutest.current_obj(QS_OBJ_KIND.AP,"output") - qutest.fill(0,1,100,0xAA) - qutest.command(0,4321) - qutest.expect("0000000001 SPRINTF_CALL 19 dec=4321, str=Hello") - qutest.expect("0000000002 Trg-Done QS_RX_COMMAND") - -def test_Overflow_underflow(qutest_noreset): - qutest = qutest_noreset # name change - qutest.current_obj(QS_OBJ_KIND.AP,"output") - qutest.peek(26,1,4) - qutest.expect("%timestamp Trg-Peek Offs=26,Size=1,Num=4,Data=<6F,00,AA,AA>") - qutest.peek(0,1,10) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=1,Num=10,Data=" -peek 0 1 10 -expect "%timestamp Trg-Peek Offs=0,Size=1,Num=10,Data=" - -# the end -end - diff --git a/examples/qutest/blinky/blinky.c b/examples/qutest/blinky/src/blinky.c similarity index 97% rename from examples/qutest/blinky/blinky.c rename to examples/qutest/blinky/src/blinky.c index 1c4e1def..c1b31035 100644 --- a/examples/qutest/blinky/blinky.c +++ b/examples/qutest/blinky/src/blinky.c @@ -3,7 +3,7 @@ * Model: blinky.qm * File: ${.::blinky.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -20,7 +20,7 @@ #include "blinky.h" #include "bsp.h" -Q_DEFINE_THIS_MODULE("blinky") +//Q_DEFINE_THIS_MODULE("blinky") /*************** ask QM to declare the Blinky class ******************/ /*$declare${AOs::Blinky} ###################################################*/ diff --git a/examples/qutest/blinky/blinky.h b/examples/qutest/blinky/src/blinky.h similarity index 95% rename from examples/qutest/blinky/blinky.h rename to examples/qutest/blinky/src/blinky.h index 34e27024..74b72124 100644 --- a/examples/qutest/blinky/blinky.h +++ b/examples/qutest/blinky/src/blinky.h @@ -3,7 +3,7 @@ * Model: blinky.qm * File: ${.::blinky.h} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/qutest/blinky/blinky.qm b/examples/qutest/blinky/src/blinky.qm similarity index 97% rename from examples/qutest/blinky/blinky.qm rename to examples/qutest/blinky/src/blinky.qm index 48d55eb1..d979822e 100644 --- a/examples/qutest/blinky/blinky.qm +++ b/examples/qutest/blinky/src/blinky.qm @@ -1,5 +1,5 @@ - + Blinky model @@ -76,7 +76,7 @@ $declare${AOs::AO_Blinky} #include "blinky.h" #include "bsp.h" -Q_DEFINE_THIS_MODULE("blinky") +//Q_DEFINE_THIS_MODULE("blinky") /*************** ask QM to declare the Blinky class ******************/ $declare${AOs::Blinky} diff --git a/examples/qutest/blinky/bsp.c b/examples/qutest/blinky/src/bsp.c similarity index 98% rename from examples/qutest/blinky/bsp.c rename to examples/qutest/blinky/src/bsp.c index 3e9b59b8..1ba9c80d 100644 --- a/examples/qutest/blinky/bsp.c +++ b/examples/qutest/blinky/src/bsp.c @@ -35,7 +35,7 @@ #include "blinky.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE enum { LED = QS_USER diff --git a/examples/qutest/blinky/bsp.h b/examples/qutest/blinky/src/bsp.h similarity index 100% rename from examples/qutest/blinky/bsp.h rename to examples/qutest/blinky/src/bsp.h diff --git a/examples/qutest/blinky/test_blinky.c b/examples/qutest/blinky/test_blinky.c deleted file mode 100644 index dda6deea..00000000 --- a/examples/qutest/blinky/test_blinky.c +++ /dev/null @@ -1,105 +0,0 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 6.3.2 -* Date of the Last Update: 2018-06-13 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" -#include "blinky.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* storage for small pool*/ - static QEvt const *blinkyQSto[10]; /* event queue storage for Blinky */ - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - BSP_init(); /* initialize the BSP */ - - /* dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(blinkyQSto); - - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); - - /* pause execution of the test and wait for the test script to continue */ - QS_TEST_PAUSE(); - - /* publish-subscribe not used, no call to QF_psInit() */ - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Blinky_ctor(); - QACTIVE_START(AO_Blinky, - 1U, - blinkyQSto, Q_DIM(blinkyQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); -} - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { -} -/*..........................................................................*/ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)param1; - (void)param2; - (void)param3; - - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } -} - -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ -void QS_onTestEvt(QEvt *e) { - (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ -#endif -} diff --git a/examples/qutest/blinky/test_blinky.py b/examples/qutest/blinky/test_blinky.py deleted file mode 100644 index 581b952e..00000000 --- a/examples/qutest/blinky/test_blinky.py +++ /dev/null @@ -1,64 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.expect_pause() - qutest.glb_filter(FILTER.ON) - qutest.Continue() - qutest.expect("%timestamp TE0-Arm Obj=l_blinky.timeEvt,AO=l_blinky,*") - qutest.expect("===RTC===> St-Init Obj=l_blinky,State=QHsm_top->Blinky_off") - qutest.expect("%timestamp LED 0") - qutest.expect("===RTC===> St-Entry Obj=l_blinky,State=Blinky_off") - qutest.expect("%timestamp Init===> Obj=l_blinky,State=Blinky_off") - qutest.current_obj(QS_OBJ_KIND.SM_AO,"l_blinky") - - -def test_TIMEOUT_SIG_l_blinky(qutest): - qutest.post("TIMEOUT_SIG") - qutest.expect("%timestamp QF-New Sig=TIMEOUT_SIG,*") - qutest.expect("%timestamp MP-Get Obj=smlPoolSto,*") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=l_blinky,Evt Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off") - qutest.expect("%timestamp LED 1") - qutest.expect("===RTC===> St-Entry Obj=l_blinky,State=Blinky_on") - qutest.expect("%timestamp ===>Tran Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off->Blinky_on") - qutest.expect("%timestamp QF-gc Evt Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off") - qutest.expect("%timestamp LED 1") - qutest.expect("===RTC===> St-Entry Obj=l_blinky,State=Blinky_on") - qutest.expect("%timestamp ===>Tran Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off->Blinky_on") - qutest.expect("%timestamp Trg-Done QS_RX_TICK") - -def test_timeEvt_Blinky_on_tick(qutest_noreset): - qutest = qutest_noreset # name change - qutest.tick() - qutest.expect("%timestamp TE0-Post Obj=l_blinky.timeEvt,Sig=TIMEOUT_SIG,AO=l_blinky") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=l_blinky,Evt Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_on") - qutest.expect("%timestamp LED 0") - qutest.expect("===RTC===> St-Entry Obj=l_blinky,State=Blinky_off") - qutest.expect("%timestamp ===>Tran Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_on->Blinky_off") - qutest.expect("%timestamp Trg-Done QS_RX_TICK") - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/blinky/test_blinky.tcl b/examples/qutest/blinky/test_blinky.tcl deleted file mode 100644 index 4a79544e..00000000 --- a/examples/qutest/blinky/test_blinky.tcl +++ /dev/null @@ -1,57 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - expect_pause - glb_filter ON - continue - expect "%timestamp TE0-Arm Obj=l_blinky.timeEvt,AO=l_blinky,*" - expect "===RTC===> St-Init Obj=l_blinky,State=QHsm_top->Blinky_off" - expect "%timestamp LED 0" - expect "===RTC===> St-Entry Obj=l_blinky,State=Blinky_off" - expect "%timestamp Init===> Obj=l_blinky,State=Blinky_off" - current_obj SM_AO l_blinky -} - -# tests... -test "TIMEOUT_SIG->l_blinky" -post TIMEOUT_SIG -expect "%timestamp QF-New Sig=TIMEOUT_SIG,*" -expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_blinky,Evt Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off" -expect "%timestamp LED 1" -expect "===RTC===> St-Entry Obj=l_blinky,State=Blinky_on" -expect "%timestamp ===>Tran Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off->Blinky_on" -expect "%timestamp QF-gc EvtBlinky_off (tick)" -current_obj TE l_blinky.timeEvt -tick -expect "%timestamp TE0-Post Obj=l_blinky.timeEvt,Sig=TIMEOUT_SIG,AO=l_blinky" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_blinky,Evt Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off" -expect "%timestamp LED 1" -expect "===RTC===> St-Entry Obj=l_blinky,State=Blinky_on" -expect "%timestamp ===>Tran Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_off->Blinky_on" -expect "%timestamp Trg-Done QS_RX_TICK" - -test "timeEvt->Blinky_on (tick)" -noreset -tick -expect "%timestamp TE0-Post Obj=l_blinky.timeEvt,Sig=TIMEOUT_SIG,AO=l_blinky" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_blinky,Evt Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_on" -expect "%timestamp LED 0" -expect "===RTC===> St-Entry Obj=l_blinky,State=Blinky_off" -expect "%timestamp ===>Tran Obj=l_blinky,Sig=TIMEOUT_SIG,State=Blinky_on->Blinky_off" -expect "%timestamp Trg-Done QS_RX_TICK" - - -# the end -end diff --git a/examples/qutest/defer/conftest.py b/examples/qutest/defer/conftest.py deleted file mode 100644 index 48253da6..00000000 --- a/examples/qutest/defer/conftest.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# pytest configuration file for QUTest/Py unit testing harness, see: -# https://www.state-machine.com/qtools/qutest.html -# - -# Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset diff --git a/examples/qutest/defer/defer.c b/examples/qutest/defer/defer.c deleted file mode 100644 index 4ad459c1..00000000 --- a/examples/qutest/defer/defer.c +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************** -* Product: Deferred Event state pattern example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-14 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" -#include "defer.h" -//#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -typedef struct { /* Transaction Server active object */ - QActive super; /* inherit QActive */ - - QEQueue requestQueue; /* native QF queue for deferred request events */ - QEvt const *requestQSto[3]; /* storage for deferred queue buffer */ - RequestEvt const *activeRequest; /* request event being processed */ - - QTimeEvt receivedEvt; /* private time event generator */ - QTimeEvt authorizedEvt; /* private time event generator */ -} TServer; - -/* hierarchical state machine ... */ -static QState TServer_initial (TServer * const me, QEvt const * const e); -static QState TServer_idle (TServer * const me, QEvt const * const e); -static QState TServer_busy (TServer * const me, QEvt const * const e); -static QState TServer_receiving (TServer * const me, QEvt const * const e); -static QState TServer_authorizing(TServer * const me, QEvt const * const e); -static QState TServer_final (TServer * const me, QEvt const * const e); - -/*..........................................................................*/ -static TServer l_tserver; -QActive * const AO_TServer = &l_tserver.super; - -/*..........................................................................*/ -void TServer_ctor() { - TServer * const me = &l_tserver; - QActive_ctor(&me->super, Q_STATE_CAST(&TServer_initial)); - QEQueue_init(&me->requestQueue, - me->requestQSto, Q_DIM(me->requestQSto)); - QTimeEvt_ctorX(&me->receivedEvt, &me->super, RECEIVED_SIG, 0U); - QTimeEvt_ctorX(&me->authorizedEvt, &me->super, AUTHORIZED_SIG, 0U); -} -/* HSM definition ----------------------------------------------------------*/ -QState TServer_initial(TServer * const me, QEvt const * const e) { - (void)e; /* unused parameter */ - me->activeRequest = (RequestEvt const *)0; /* no active request yet */ - - QS_FUN_DICTIONARY(&QHsm_top); - QS_FUN_DICTIONARY(&TServer_idle); - QS_FUN_DICTIONARY(&TServer_busy); - QS_FUN_DICTIONARY(&TServer_receiving); - QS_FUN_DICTIONARY(&TServer_authorizing); - QS_FUN_DICTIONARY(&TServer_final); - - QS_OBJ_DICTIONARY(&l_tserver); - QS_OBJ_DICTIONARY(&l_tserver.requestQueue); - QS_OBJ_DICTIONARY(&l_tserver.receivedEvt); - QS_OBJ_DICTIONARY(&l_tserver.authorizedEvt); - - QS_SIG_DICTIONARY(NEW_REQUEST_SIG, (void *)0); - QS_SIG_DICTIONARY(RECEIVED_SIG, (void *)0); - QS_SIG_DICTIONARY(AUTHORIZED_SIG, (void *)0); - QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - - return Q_TRAN(&TServer_idle); -} -/*..........................................................................*/ -QState TServer_idle(TServer * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - //printf("idle-ENTRY;\n"); - - /* recall the oldest deferred request... */ - if (QActive_recall(&me->super, &me->requestQueue)) { - //printf("Request recalled\n"); - } - else { - //printf("No deferred requests\n"); - } - status = Q_HANDLED(); - break; - } - case NEW_REQUEST_SIG: { - /* create and save a new reference to the request event so that - * this event will be available beyond this RTC step and won't be - * recycled. - */ - Q_NEW_REF(me->activeRequest, RequestEvt); - - //printf("Processing request #%d\n", - // (int)me->activeRequest->ref_num); - - status = Q_TRAN(&TServer_receiving); - break; - } - case TERMINATE_SIG: { - status = Q_TRAN(&TServer_final); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState TServer_busy(TServer * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_EXIT_SIG: { - //printf("busy-EXIT; done processing request #%d\n", - // (int)me->activeRequest->ref_num); - - /* delete the reference to the active request, because - * it is now processed. - */ - Q_DELETE_REF(me->activeRequest); - - status = Q_HANDLED(); - break; - } - case NEW_REQUEST_SIG: { - /* defer the new request event... */ - if (QActive_defer(&me->super, &me->requestQueue, e)) { - //printf("Request #%d deferred;\n", - // (int)Q_EVT_CAST(RequestEvt)->ref_num); - } - else { - /* notify the request sender that his request was denied... */ - //printf("Request #%d IGNORED;\n", - // (int)Q_EVT_CAST(RequestEvt)->ref_num); - } - status = Q_HANDLED(); - break; - } - case TERMINATE_SIG: { - status = Q_TRAN(&TServer_final); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState TServer_receiving(TServer * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - /* inform about the first stage of processing of the request... */ - //printf("receiving-ENTRY; active request: #%d\n", - // (int)me->activeRequest->ref_num); - - /* one-shot timeout in 1 second */ - QTimeEvt_armX(&me->receivedEvt, BSP_TICKS_PER_SEC, 0U); - status = Q_HANDLED(); - break; - } - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->receivedEvt); - status = Q_HANDLED(); - break; - } - case RECEIVED_SIG: { - status = Q_TRAN(&TServer_authorizing); - break; - } - default: { - status = Q_SUPER(&TServer_busy); - break; - } - } - return status; -} -/*..........................................................................*/ -QState TServer_authorizing(TServer * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - /* inform about the second stage of processing of the request.. */ - //printf("authorizing-ENTRY; active request: #%d\n", - // (int)me->activeRequest->ref_num); - - /* one-shot timeout in 2 seconds */ - QTimeEvt_armX(&me->authorizedEvt, 2U*BSP_TICKS_PER_SEC, 0U); - status = Q_HANDLED(); - break; - } - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->authorizedEvt); - status = Q_HANDLED(); - break; - } - case AUTHORIZED_SIG: { - status = Q_TRAN(&TServer_idle); - break; - } - default: { - status = Q_SUPER(&TServer_busy); - break; - } - } - return status; -} -/*..........................................................................*/ -QState TServer_final(TServer * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - //printf("final-ENTRY;\n"); - QF_stop(); /* terminate the application */ - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} diff --git a/examples/qutest/defer/defer.h b/examples/qutest/defer/defer.h deleted file mode 100644 index 4821f4e9..00000000 --- a/examples/qutest/defer/defer.h +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************** -* Product: Deferred Event state pattern example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-12 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 -*****************************************************************************/ -#ifndef defer_h -#define defer_h - -enum { BSP_TICKS_PER_SEC = 100 }; - -/*..........................................................................*/ -enum TServerSignals { - NEW_REQUEST_SIG = Q_USER_SIG, /* the new request signal */ - RECEIVED_SIG, /* the request has been received */ - AUTHORIZED_SIG, /* the request has been authorized */ - TERMINATE_SIG /* terminate the application */ -}; - -/*..........................................................................*/ -typedef struct { - QEvt super; /* inherit QEvt */ - uint8_t ref_num; /* reference number of the request */ -} RequestEvt; - -/*..........................................................................*/ -void TServer_ctor(void); -extern QActive * const AO_TServer; - -#endif /* defer_h */ diff --git a/examples/qutest/defer/ek-tm4c123gxl.mak b/examples/qutest/defer/ek-tm4c123gxl.mak deleted file mode 100644 index 2a24c4e8..00000000 --- a/examples/qutest/defer/ek-tm4c123gxl.mak +++ /dev/null @@ -1,332 +0,0 @@ -############################################################################## -# Product: Makefile for EK-TM4C123GXL, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak SCRIPT=py # make and run the Python tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name, binary output directory -# -PROJECT := test_defer -TARGET := ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest - -# list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(QPC)/3rd_party/ek-tm4c123gxl \ - $(QPC)/3rd_party/ek-tm4c123gxl/gnu - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - test_defer.c \ - defer.c \ - system_TM4C123GH6PM.c \ - startup_TM4C123GH6PM.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DTARGET_IS_TM4C123_RB1 - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!) -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_ARCH := 7 # NOTE: must match the ARM_CPU! -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see http://gnutoolchains.com/arm-eabi/ -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-eabi-g++ -AS := $(GNU_ARM)/bin/arm-eabi-as -LINK := $(GNU_ARM)/bin/arm-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The following symbol LMFLASH assumes that LMFlash.exe can -# be found on the PATH. You might need to adjust this symbol to the -# location of the LMFlash utility on your machine -# -ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe -endif - - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := $(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) \ - -mthumb -nostdlib \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) - -ifeq ($(SCRIPT),py) -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -.PHONY : clean show - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QUTEST = $(QUTEST) - @echo HOST = $(HOST) - diff --git a/examples/qutest/defer/test_defer.c b/examples/qutest/defer/test_defer.c deleted file mode 100644 index 511f60a7..00000000 --- a/examples/qutest/defer/test_defer.c +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" -#include "defer.h" -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QF_MPOOL_EL(RequestEvt) smlPoolSto[10]; /* storage for small pool*/ - static QEvt const *tserverQSto[10]; /* event queue storage for TServer */ - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tserverQSto); - - /* pause execution of the test and wait for the test script to continue */ - QS_TEST_PAUSE(); - - /* publish-subscribe not used, no call to QF_psInit() */ - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - TServer_ctor(); - QACTIVE_START(AO_TServer, - 1U, - tserverQSto, Q_DIM(tserverQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); -} - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { -} -/*..........................................................................*/ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)param1; - (void)param2; - (void)param3; - - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } -} - -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ -void QS_onTestEvt(QEvt *e) { - (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ -#endif -} - diff --git a/examples/qutest/defer/test_defer_disp.py b/examples/qutest/defer/test_defer_disp.py deleted file mode 100644 index 81de046e..00000000 --- a/examples/qutest/defer/test_defer_disp.py +++ /dev/null @@ -1,78 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.expect_pause() - qutest.glb_filter(FILTER.SM,FILTER.AO,FILTER.QF,FILTER.EQ) - qutest.Continue() - qutest.expect("===RTC===> St-Init Obj=l_tserver,State=QHsm_top->TServer_idle") - qutest.expect("%timestamp AO-RCllA Obj=l_tserver,Que=l_tserver.requestQueue") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_idle") - qutest.expect("%timestamp Init===> Obj=l_tserver,State=TServer_idle") - qutest.current_obj(QS_OBJ_KIND.SM_AO,"l_tserver") - - -def test_NEW_REQUEST_SIG_l_tserver(qutest): - qutest.dispatch("NEW_REQUEST_SIG") - qutest.expect("%timestamp QF-New Sig=NEW_REQUEST_SIG,*") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle") - qutest.expect("%timestamp QF-NewRf Evt") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving") - qutest.expect("%timestamp QF-gcA Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_NEW_REQUEST_SIG_l_tserver_defer(qutest_noreset): - qutest = qutest_noreset # name change - qutest.dispatch("NEW_REQUEST_SIG") - qutest.expect("%timestamp QF-New Sig=NEW_REQUEST_SIG,*") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_receiving") - qutest.expect("%timestamp EQ-Post Obj=l_tserver.requestQueue,Evt,*") - qutest.expect("%timestamp AO-Defer Obj=l_tserver,Que=l_tserver.requestQueue,Evt") - qutest.expect("%timestamp =>Intern Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_busy") - qutest.expect("%timestamp QF-gcA Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_RECEIVED_SIG_AUTHORIZED_SIG_l_tserver_recall(qutest_noreset): - qutest = qutest_noreset # name change - qutest.dispatch("RECEIVED_SIG") - qutest.expect("%timestamp QF-New Sig=RECEIVED_SIG,*") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving") - qutest.expect("===RTC===> St-Exit Obj=l_tserver,State=TServer_receiving") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_authorizing") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving->TServer_authorizing") - qutest.expect("%timestamp QF-gc Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - qutest.dispatch("AUTHORIZED_SIG") - qutest.expect("%timestamp QF-New Sig=AUTHORIZED_SIG,*") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing") - qutest.expect("===RTC===> St-Exit Obj=l_tserver,State=TServer_authorizing") - qutest.expect("%timestamp QF-DelRf Evt") - qutest.expect("%timestamp QF-gc Evt") - qutest.expect("===RTC===> St-Exit Obj=l_tserver,State=TServer_busy") - qutest.expect("%timestamp EQ-GetL Obj=l_tserver.requestQueue,Evt") - qutest.expect("%timestamp AO-LIFO Obj=l_tserver,Evt,*") - qutest.expect("%timestamp AO-RCall Obj=l_tserver,Que=l_tserver.requestQueue,Evt") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_idle") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing->TServer_idle") - qutest.expect("%timestamp QF-gc Evt") - qutest.expect("%timestamp AO-GetL Obj=l_tserver,Evt") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle") - qutest.expect("%timestamp QF-NewRf Evt") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving") - qutest.expect("%timestamp QF-gcA Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/defer/test_defer_disp.tcl b/examples/qutest/defer/test_defer_disp.tcl deleted file mode 100644 index 35ff46af..00000000 --- a/examples/qutest/defer/test_defer_disp.tcl +++ /dev/null @@ -1,81 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - expect_pause - glb_filter SM AO QF EQ - continue - expect "===RTC===> St-Init Obj=l_tserver,State=QHsm_top->TServer_idle" - expect "%timestamp AO-RCllA Obj=l_tserver,Que=l_tserver.requestQueue" - expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_idle" - expect "%timestamp Init===> Obj=l_tserver,State=TServer_idle" - current_obj SM_AO l_tserver -} - -# tests... -test "NEW_REQUEST_SIG->l_tserver" -dispatch NEW_REQUEST_SIG -expect "%timestamp QF-New Sig=NEW_REQUEST_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle" -expect "%timestamp QF-NewRf Evt" -#expect "%timestamp TE0-Arm Obj=l_tserver.receivedEvt,AO=l_tserver,Tim=100,Int=0" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving" -expect "%timestamp QF-gcA Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - -test "NEW_REQUEST_SIG->l_tserver (defer)" -noreset -dispatch NEW_REQUEST_SIG -expect "%timestamp QF-New Sig=NEW_REQUEST_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_receiving" -expect "%timestamp EQ-Post Obj=l_tserver.requestQueue,Evt,*" -expect "%timestamp AO-Defer Obj=l_tserver,Que=l_tserver.requestQueue,Evt" -expect "%timestamp =>Intern Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_busy" -expect "%timestamp QF-gcA Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - -test "RECEIVED_SIG/AUTHORIZED_SIG->l_tserver (recall)" -noreset -dispatch RECEIVED_SIG -expect "%timestamp QF-New Sig=RECEIVED_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp Disp===> Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving" -#expect "%timestamp TE0-Dis Obj=l_tserver.receivedEvt,AO=l_tserver,Tim=100,Int=0" -expect "===RTC===> St-Exit Obj=l_tserver,State=TServer_receiving" -#expect "%timestamp TE0-Arm Obj=l_tserver.authorizedEvt,AO=l_tserver,Tim=200,Int=0" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_authorizing" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving->TServer_authorizing" -expect "%timestamp QF-gc Evt" -#expect "%timestamp MP-Put Obj=smlPoolSto,*" -expect "%timestamp Trg-Done QS_RX_EVENT" -dispatch AUTHORIZED_SIG -expect "%timestamp QF-New Sig=AUTHORIZED_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp Disp===> Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing" -#expect "%timestamp TE0-Dis Obj=l_tserver.authorizedEvt,AO=l_tserver,Tim=200,Int=0" -expect "===RTC===> St-Exit Obj=l_tserver,State=TServer_authorizing" -expect "%timestamp QF-DelRf Evt" -expect "%timestamp QF-gc Evt" -#expect "%timestamp MP-Put Obj=smlPoolSto,*" -expect "===RTC===> St-Exit Obj=l_tserver,State=TServer_busy" -expect "%timestamp EQ-GetL Obj=l_tserver.requestQueue,Evt" -expect "%timestamp AO-LIFO Obj=l_tserver,Evt,*" -expect "%timestamp AO-RCall Obj=l_tserver,Que=l_tserver.requestQueue,Evt" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_idle" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing->TServer_idle" -expect "%timestamp QF-gc Evt" -#expect "%timestamp MP-Put Obj=smlPoolSto,*" -expect "%timestamp AO-GetL Obj=l_tserver,Evt" -expect "%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle" -expect "%timestamp QF-NewRf Evt" -#expect "%timestamp TE0-Arm Obj=l_tserver.receivedEvt,AO=l_tserver,Tim=100,Int=0" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving" -expect "%timestamp QF-gcA Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - - -# the end -end diff --git a/examples/qutest/defer/test_defer_post.py b/examples/qutest/defer/test_defer_post.py deleted file mode 100644 index 09e4d211..00000000 --- a/examples/qutest/defer/test_defer_post.py +++ /dev/null @@ -1,86 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.expect_pause() - qutest.glb_filter(FILTER.SM,FILTER.AO,FILTER.QF,FILTER.EQ) - qutest.Continue() - qutest.expect("===RTC===> St-Init Obj=l_tserver,State=QHsm_top->TServer_idle") - qutest.expect("%timestamp AO-RCllA Obj=l_tserver,Que=l_tserver.requestQueue") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_idle") - qutest.expect("%timestamp Init===> Obj=l_tserver,State=TServer_idle") - qutest.current_obj(QS_OBJ_KIND.SM_AO,"l_tserver") - - -def test_NEW_REQUEST_SIG_l_tserver(qutest): - qutest.post("NEW_REQUEST_SIG") - qutest.expect("%timestamp QF-New Sig=NEW_REQUEST_SIG,*") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*") - qutest.expect("%timestamp AO-GetL Obj=l_tserver,Evt") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle") - qutest.expect("%timestamp QF-NewRf Evt") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving") - qutest.expect("%timestamp QF-gcA Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_NEW_REQUEST_SIG_l_tserver_defer(qutest_noreset): - qutest = qutest_noreset # name change - qutest.post("NEW_REQUEST_SIG") - qutest.expect("%timestamp QF-New Sig=NEW_REQUEST_SIG,*") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*") - qutest.expect("%timestamp AO-GetL Obj=l_tserver,Evt") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_receiving") - qutest.expect("%timestamp EQ-Post Obj=l_tserver.requestQueue,Evt,*") - qutest.expect("%timestamp AO-Defer Obj=l_tserver,Que=l_tserver.requestQueue,Evt") - qutest.expect("%timestamp =>Intern Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_busy") - qutest.expect("%timestamp QF-gcA Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_RECEIVED_SIG_AUTHORIZED_SIG_l_tserver_recall(qutest_noreset): - qutest = qutest_noreset # name change - qutest.post("RECEIVED_SIG") - qutest.expect("%timestamp QF-New Sig=RECEIVED_SIG,*") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*") - qutest.expect("%timestamp AO-GetL Obj=l_tserver,Evt") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving") - qutest.expect("===RTC===> St-Exit Obj=l_tserver,State=TServer_receiving") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_authorizing") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving->TServer_authorizing") - qutest.expect("%timestamp QF-gc Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - qutest.post("AUTHORIZED_SIG") - qutest.expect("%timestamp QF-New Sig=AUTHORIZED_SIG,*") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*") - qutest.expect("%timestamp AO-GetL Obj=l_tserver,Evt") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing") - qutest.expect("===RTC===> St-Exit Obj=l_tserver,State=TServer_authorizing") - qutest.expect("%timestamp QF-DelRf Evt") - qutest.expect("%timestamp QF-gc Evt") - qutest.expect("===RTC===> St-Exit Obj=l_tserver,State=TServer_busy") - qutest.expect("%timestamp EQ-GetL Obj=l_tserver.requestQueue,Evt") - qutest.expect("%timestamp AO-LIFO Obj=l_tserver,Evt,*") - qutest.expect("%timestamp AO-RCall Obj=l_tserver,Que=l_tserver.requestQueue,Evt") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_idle") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing->TServer_idle") - qutest.expect("%timestamp QF-gc Evt") - qutest.expect("%timestamp AO-GetL Obj=l_tserver,Evt") - qutest.expect("%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle") - qutest.expect("%timestamp QF-NewRf Evt") - qutest.expect("===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving") - qutest.expect("%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving") - qutest.expect("%timestamp QF-gcA Evt") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/defer/test_defer_post.tcl b/examples/qutest/defer/test_defer_post.tcl deleted file mode 100644 index 0d61f664..00000000 --- a/examples/qutest/defer/test_defer_post.tcl +++ /dev/null @@ -1,89 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - expect_pause - glb_filter SM AO QF EQ - continue - expect "===RTC===> St-Init Obj=l_tserver,State=QHsm_top->TServer_idle" - expect "%timestamp AO-RCllA Obj=l_tserver,Que=l_tserver.requestQueue" - expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_idle" - expect "%timestamp Init===> Obj=l_tserver,State=TServer_idle" - current_obj SM_AO l_tserver -} - -# tests... -test "NEW_REQUEST_SIG->l_tserver" -post NEW_REQUEST_SIG -expect "%timestamp QF-New Sig=NEW_REQUEST_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*" -expect "%timestamp AO-GetL Obj=l_tserver,Evt" -expect "%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle" -expect "%timestamp QF-NewRf Evt" -#expect "%timestamp TE0-Arm Obj=l_tserver.receivedEvt,AO=l_tserver,Tim=100,Int=0" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving" -expect "%timestamp QF-gcA Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - -test "NEW_REQUEST_SIG->l_tserver (defer)" -noreset -post NEW_REQUEST_SIG -expect "%timestamp QF-New Sig=NEW_REQUEST_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*" -expect "%timestamp AO-GetL Obj=l_tserver,Evt" -expect "%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_receiving" -expect "%timestamp EQ-Post Obj=l_tserver.requestQueue,Evt,*" -expect "%timestamp AO-Defer Obj=l_tserver,Que=l_tserver.requestQueue,Evt" -expect "%timestamp =>Intern Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_busy" -expect "%timestamp QF-gcA Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - -test "RECEIVED_SIG/AUTHORIZED_SIG->l_tserver (recall)" -noreset -post RECEIVED_SIG -expect "%timestamp QF-New Sig=RECEIVED_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*" -expect "%timestamp AO-GetL Obj=l_tserver,Evt" -expect "%timestamp Disp===> Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving" -#expect "%timestamp TE0-Dis Obj=l_tserver.receivedEvt,AO=l_tserver,Tim=100,Int=0" -expect "===RTC===> St-Exit Obj=l_tserver,State=TServer_receiving" -#expect "%timestamp TE0-Arm Obj=l_tserver.authorizedEvt,AO=l_tserver,Tim=200,Int=0" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_authorizing" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=RECEIVED_SIG,State=TServer_receiving->TServer_authorizing" -expect "%timestamp QF-gc Evt" -#expect "%timestamp MP-Put Obj=smlPoolSto,*" -expect "%timestamp Trg-Done QS_RX_EVENT" -post AUTHORIZED_SIG -expect "%timestamp QF-New Sig=AUTHORIZED_SIG,*" -#expect "%timestamp MP-Get Obj=smlPoolSto,*" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=l_tserver,Evt,*" -expect "%timestamp AO-GetL Obj=l_tserver,Evt" -expect "%timestamp Disp===> Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing" -#expect "%timestamp TE0-Dis Obj=l_tserver.authorizedEvt,AO=l_tserver,Tim=200,Int=0" -expect "===RTC===> St-Exit Obj=l_tserver,State=TServer_authorizing" -expect "%timestamp QF-DelRf Evt" -expect "%timestamp QF-gc Evt" -#expect "%timestamp MP-Put Obj=smlPoolSto,*" -expect "===RTC===> St-Exit Obj=l_tserver,State=TServer_busy" -expect "%timestamp EQ-GetL Obj=l_tserver.requestQueue,Evt" -expect "%timestamp AO-LIFO Obj=l_tserver,Evt,*" -expect "%timestamp AO-RCall Obj=l_tserver,Que=l_tserver.requestQueue,Evt" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_idle" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=AUTHORIZED_SIG,State=TServer_authorizing->TServer_idle" -expect "%timestamp QF-gc Evt" -#expect "%timestamp MP-Put Obj=smlPoolSto,*" -expect "%timestamp AO-GetL Obj=l_tserver,Evt" -expect "%timestamp Disp===> Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle" -expect "%timestamp QF-NewRf Evt" -#expect "%timestamp TE0-Arm Obj=l_tserver.receivedEvt,AO=l_tserver,Tim=100,Int=0" -expect "===RTC===> St-Entry Obj=l_tserver,State=TServer_receiving" -expect "%timestamp ===>Tran Obj=l_tserver,Sig=NEW_REQUEST_SIG,State=TServer_idle->TServer_receiving" -expect "%timestamp QF-gcA Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - - -# the end -end diff --git a/examples/qutest/dpp/conftest.py b/examples/qutest/dpp/conftest.py deleted file mode 100644 index 48253da6..00000000 --- a/examples/qutest/dpp/conftest.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# pytest configuration file for QUTest/Py unit testing harness, see: -# https://www.state-machine.com/qtools/qutest.html -# - -# Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset diff --git a/examples/qutest/dpp/efm32-slstk3401a.ewd b/examples/qutest/dpp/efm32-slstk3401a.ewd deleted file mode 100644 index 7495a24b..00000000 --- a/examples/qutest/dpp/efm32-slstk3401a.ewd +++ /dev/null @@ -1,1407 +0,0 @@ - - - 3 - - QUTest - - 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/qutest/dpp/efm32-slstk3401a.ewp b/examples/qutest/dpp/efm32-slstk3401a.ewp deleted file mode 100644 index a32d9dc3..00000000 --- a/examples/qutest/dpp/efm32-slstk3401a.ewp +++ /dev/null @@ -1,1135 +0,0 @@ - - - 3 - - QUTest - - ARM - - 1 - - General - 3 - - 28 - 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.c - - - $PROJ_DIR$\bsp.h - - - $PROJ_DIR$\dpp.h - - - $PROJ_DIR$\main.c - - - $PROJ_DIR$\philo.c - - - $PROJ_DIR$\..\..\..\include\qstamp.c - - - $PROJ_DIR$\table.c - - - $PROJ_DIR$\test_dpp.c - - - - efm32pg1b - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\em_assert.c - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\em_system.c - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\em_usart.c - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\iar\startup_efm32pg1b.s - - - $PROJ_DIR$\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - - - - QP - - $PROJ_DIR$\..\..\..\src\qep_hsm.c - - - $PROJ_DIR$\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\src\qs\qs_64bit.c - - - $PROJ_DIR$\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\src\qs\qs_rx.c - - - $PROJ_DIR$\..\..\..\src\qs\qutest.c - - - - QP_port - - $PROJ_DIR$\..\efm32-slstk3401a\qutest_port.c - - - diff --git a/examples/qutest/dpp/efm32-slstk3401a.eww b/examples/qutest/dpp/efm32-slstk3401a.eww deleted file mode 100644 index f5a41624..00000000 --- a/examples/qutest/dpp/efm32-slstk3401a.eww +++ /dev/null @@ -1,10 +0,0 @@ - - - - - $WS_DIR$\efm32-slstk3401a.ewp - - - - - diff --git a/examples/qutest/dpp/posix_host.mak b/examples/qutest/dpp/posix_host.mak deleted file mode 100644 index 4d76d607..00000000 --- a/examples/qutest/dpp/posix_host.mak +++ /dev/null @@ -1,260 +0,0 @@ -############################################################################## -# Product: Makefile for QUTEST; QP/C on POSIX *Host* -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -f posix_host.mak # make and run the tests in the current directory -# make -f posix_host.mak TESTS=philo*.tcl # make and run the selected tests -# make -f posix_host.mak SCRIPT=py # make and run the Python tests -# make -f posix_host.mak HOST=localhost:7705 # connect to host:port -# make -f posix_host.mak norun # only make but not run the tests -# make -f posix_host.mak clean # cleanup the build -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_dpp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix-qutest - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c \ - test_dpp.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -LIB_DIRS := -LIBS := - -# defines... -DEFINES := - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities - -MKDIR := mkdir -p -RM := rm -f - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -BIN_DIR := posix_host - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -ifeq ($(SCRIPT),py) -run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - @echo HOST = $(HOST) - diff --git a/examples/qutest/dpp/bsp.c b/examples/qutest/dpp/src/bsp.c similarity index 100% rename from examples/qutest/dpp/bsp.c rename to examples/qutest/dpp/src/bsp.c diff --git a/examples/qutest/dpp/bsp.h b/examples/qutest/dpp/src/bsp.h similarity index 100% rename from examples/qutest/dpp/bsp.h rename to examples/qutest/dpp/src/bsp.h diff --git a/examples/qutest/dpp/dpp.h b/examples/qutest/dpp/src/dpp.h similarity index 97% rename from examples/qutest/dpp/dpp.h rename to examples/qutest/dpp/src/dpp.h index 74687650..b6d31031 100644 --- a/examples/qutest/dpp/dpp.h +++ b/examples/qutest/dpp/src/dpp.h @@ -3,7 +3,7 @@ * Model: dpp.qm * File: ${.::dpp.h} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/qutest/dpp/dpp.qm b/examples/qutest/dpp/src/dpp.qm similarity index 96% rename from examples/qutest/dpp/dpp.qm rename to examples/qutest/dpp/src/dpp.qm index 3b8b756f..4839fd25 100644 --- a/examples/qutest/dpp/dpp.qm +++ b/examples/qutest/dpp/src/dpp.qm @@ -1,5 +1,5 @@ - + Dining Philosopher Problem example NOTE: Requries QP5. @@ -29,8 +29,6 @@ if (registered == (uint8_t)0) { QS_FUN_DICTIONARY(&Philo_hungry); QS_FUN_DICTIONARY(&Philo_eating); } -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); @@ -118,14 +116,6 @@ Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); uint8_t n; (void)e; /* suppress the compiler warning about unused parameter */ -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); diff --git a/examples/qutest/dpp/philo.c b/examples/qutest/dpp/src/philo.c similarity index 97% rename from examples/qutest/dpp/philo.c rename to examples/qutest/dpp/src/philo.c index e7979f57..76c754ca 100644 --- a/examples/qutest/dpp/philo.c +++ b/examples/qutest/dpp/src/philo.c @@ -3,7 +3,7 @@ * Model: dpp.qm * File: ${.::philo.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -104,8 +104,6 @@ static QState Philo_initial(Philo * const me, QEvt const * const e) { QS_FUN_DICTIONARY(&Philo_hungry); QS_FUN_DICTIONARY(&Philo_eating); } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); diff --git a/examples/qutest/dpp/table.c b/examples/qutest/dpp/src/table.c similarity index 96% rename from examples/qutest/dpp/table.c rename to examples/qutest/dpp/src/table.c index 10b0896b..4dafdd3d 100644 --- a/examples/qutest/dpp/table.c +++ b/examples/qutest/dpp/src/table.c @@ -3,7 +3,7 @@ * Model: dpp.qm * File: ${.::table.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -85,14 +85,6 @@ static QState Table_initial(Table * const me, QEvt const * const e) { uint8_t n; (void)e; /* suppress the compiler warning about unused parameter */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); diff --git a/examples/qutest/dpp/Makefile b/examples/qutest/dpp/test_dpp/Makefile similarity index 66% rename from examples/qutest/dpp/Makefile rename to examples/qutest/dpp/test_dpp/Makefile index edcdd321..b660f687 100644 --- a/examples/qutest/dpp/Makefile +++ b/examples/qutest/dpp/test_dpp/Makefile @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for QUTEST DPP-test; QP/C on Win32 host -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 +# Product: Makefile for QUTEST-QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -47,39 +47,34 @@ # #----------------------------------------------------------------------------- -# project name +# project name: # PROJECT := test_dpp #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - # list of all source directories used by this project -VPATH = \ - . +VPATH = . \ + ../src # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include +INCLUDES = -I. \ + -I../src + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif #----------------------------------------------------------------------------- -# files +# project files: # # C source files... @@ -91,72 +86,107 @@ C_SRCS := \ test_dpp.c # C++ source files... -CPP_SRCS := +CPP_SRCS := -LIB_DIRS := -LIBS := +LIB_DIRS := +LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API DEFINES := -DQP_API_VERSION=9999 #----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + QP_PORT_DIR := $(QPC)/ports/win32-qutest + LIB_DIRS += -L$(QP_PORT_DIR)/mingw + LIBS += -lqp -lwsock32 +else + QP_PORT_DIR := $(QPC)/ports/posix-qutest + C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + + LIBS += -lpthread +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QPC)/src/qs $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: # # NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH # CC := gcc CPP := g++ LINK := gcc # for C programs #LINK := g++ # for C++ programs -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif -#============================================================================ -# Typically you should not need to change anything below this line - #----------------------------------------------------------------------------- -# build options +# basic utilities (depends on the OS this Makefile runs on): # - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif #----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 +# build options... +BIN_DIR := build + +CFLAGS = -c -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +CPPFLAGS = -c -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +LINKFLAGS := + +#----------------------------------------------------------------------------- C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) @@ -171,7 +201,7 @@ endif # rules # -.PHONY : run norun +.PHONY : norun clean show ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_EXE) @@ -189,16 +219,11 @@ endif endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) -ifeq ($(SCRIPT),py) run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ @@ -207,12 +232,10 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun + $(CC) $(CFLAGS) $< -o $@ # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) @@ -224,13 +247,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @@ -245,5 +266,4 @@ show : @echo QTOOLS = $(QTOOLS) @echo QUTEST = $(QUTEST) @echo TESTS = $(TESTS) - @echo HOST = $(HOST) diff --git a/examples/qutest/blinky/conftest.py b/examples/qutest/dpp/test_dpp/conftest.py similarity index 69% rename from examples/qutest/blinky/conftest.py rename to examples/qutest/dpp/test_dpp/conftest.py index 48253da6..5a61638a 100644 --- a/examples/qutest/blinky/conftest.py +++ b/examples/qutest/dpp/test_dpp/conftest.py @@ -4,4 +4,4 @@ # # Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset +from qspypy.fixtures import * diff --git a/examples/qutest/dpp/main.c b/examples/qutest/dpp/test_dpp/main.c similarity index 86% rename from examples/qutest/dpp/main.c rename to examples/qutest/dpp/test_dpp/main.c index f61a09a7..f68f71e9 100644 --- a/examples/qutest/dpp/main.c +++ b/examples/qutest/dpp/test_dpp/main.c @@ -1,11 +1,11 @@ /***************************************************************************** * Product: DPP example -* Last Updated for Version: 6.3.3 -* Date of the Last Update: 2018-06-22 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-04 * -* 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. * @@ -43,7 +43,6 @@ int main(int argc, char *argv[]) { static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ uint8_t n; - QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(argc, argv); /* initialize the Board Support Package */ @@ -54,7 +53,15 @@ int main(int argc, char *argv[]) { QS_OBJ_DICTIONARY(AO_Philo[2]); QS_OBJ_DICTIONARY(AO_Philo[3]); QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(smlPoolSto); + + /* signal dictionaries */ + 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); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); /* pause execution of the test and wait for the test script to continue */ QS_TEST_PAUSE(); diff --git a/examples/qutest/dpp/efm32-slstk3401a.mak b/examples/qutest/dpp/test_dpp/make_efm32 similarity index 82% rename from examples/qutest/dpp/efm32-slstk3401a.mak rename to examples/qutest/dpp/test_dpp/make_efm32 index 6c825ce7..68bb9777 100644 --- a/examples/qutest/dpp/efm32-slstk3401a.mak +++ b/examples/qutest/dpp/test_dpp/make_efm32 @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for EMF32-SLSTK3401A, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 +# Product: Makefile for EMF32, QUTEST, GNU-ARM +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -fefm32-slstk3401a.mak # make and run the tests in the current directory -# make -fefm32-slstk3401a.mak TESTS=philo*.tcl # make and run the selected tests -# make -fefm32-slstk3401a.mak SCRIPT=py # make and run the Python tests -# make -fefm32-slstk3401a.mak HOST=localhost:7705 # connect to host:port -# make -fefm32-slstk3401a.mak norun # only make but not run the tests -# make -fefm32-slstk3401a.mak clean # cleanup the build +# make -f make_efm32 # make and run the tests in the current directory +# make -f make_efm32 TESTS=philo*.tcl # make and run the selected tests +# make -f make_efm32 SCRIPT=py # make and run the Python tests +# make -f make_efm32 HOST=localhost:7705 # connect to host:port +# make -f make_efm32 norun # only make but not run the tests +# make -f make_efm32 clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -47,32 +47,34 @@ # #----------------------------------------------------------------------------- -# project name, binary output directory +# project name, target name, target directory: # PROJECT := test_dpp -TARGET := efm32-slstk3401a +TARGET := efm32 +TARGET_DIR := ..\..\target_efm32 #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) +# location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../.. +QPC := ../../../.. endif -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - # QP port used in this project QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + # list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ +VPATH := . \ + ../src \ + $(TARGET_DIR) \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ @@ -80,9 +82,9 @@ VPATH = \ $(QPC)/3rd_party/efm32pg1b/gnu # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ -I$(QPC)/include \ -I$(QPC)/src \ -I$(QP_PORT_DIR) \ @@ -90,7 +92,7 @@ INCLUDES = \ -I$(QPC)/3rd_party/efm32pg1b #----------------------------------------------------------------------------- -# files +# project files: # # assembler source files @@ -114,7 +116,7 @@ C_SRCS := \ CPP_SRCS := OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld +LD_SCRIPT := $(TARGET_DIR)/test.ld QP_SRCS := \ qep_hsm.c \ @@ -128,6 +130,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -175,10 +178,10 @@ BIN := $(GNU_ARM)/bin/arm-eabi-objcopy #----------------------------------------------------------------------------- # FLASH tool (NOTE: Requires the JLINK utility) -# see ../efm32-slstk3401a/flash.bat +# see $(TARGET_DIR)\flash.bat # -FLASH := ..\efm32-slstk3401a\flash.bat +FLASH := $(TARGET_DIR)\flash.bat ############################################################################## # Typically you should not need to change anything below this line @@ -190,11 +193,9 @@ MKDIR := mkdir RM := rm ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := python -m qspypy.qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif #----------------------------------------------------------------------------- @@ -205,15 +206,15 @@ endif C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) -BIN_DIR := $(TARGET) +BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST @@ -271,15 +272,9 @@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) flash : $(FLASH) $(TARGET_BIN) -ifeq ($(SCRIPT),py) run : $(TARGET_BIN) $(FLASH) $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/qutest/dpp/posix.mak b/examples/qutest/dpp/test_dpp/make_posix similarity index 74% rename from examples/qutest/dpp/posix.mak rename to examples/qutest/dpp/test_dpp/make_posix index 1cc7e472..50beaf75 100644 --- a/examples/qutest/dpp/posix.mak +++ b/examples/qutest/dpp/test_dpp/make_posix @@ -1,11 +1,11 @@ ############################################################################## # Product: Makefile for QUTEST; QP/C on POSIX *Target* -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,10 +33,10 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f posix.mak # make and run the tests in the current directory -# make -f posix.mak HOST=192.168.1.65:6601 # make and run the executable -# make -f posix.mak norun # only make but not run the tests -# make -f posix.mak clean # cleanup the build +# make -f make_posix # make and run the tests in the current directory +# make -f make_posix HOST=192.168.1.65:6601 # make and run the executable +# make -f make_posix norun # only make but not run the tests +# make -f make_posix clean # cleanup the build # #----------------------------------------------------------------------------- @@ -45,33 +45,34 @@ PROJECT := test_dpp #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix-qutest - # list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) +VPATH = . \ + ../src # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) +INCLUDES = -I. \ + -I../src + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif + + +ifeq ($(MAKECMDGOALS),test) + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + +endif #----------------------------------------------------------------------------- -# files +# project files: # # C source files... @@ -85,7 +86,20 @@ C_SRCS := \ # C++ source files... CPP_SRCS := -QP_SRCS := \ +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/posix-qutest + +C_SRCS += \ qep_hsm.c \ qep_msm.c \ qf_act.c \ @@ -97,6 +111,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -104,51 +119,42 @@ QP_SRCS := \ qutest.c \ qutest_port.c -LIB_DIRS := -LIBS := +LIBS += -lpthread -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QPC)/src/qs $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) #----------------------------------------------------------------------------- -# GNU toolset +# GNU toolset: # CC := gcc CPP := g++ LINK := gcc # for C programs #LINK := g++ # for C++ programs -# basic utilities +#----------------------------------------------------------------------------- +# basic utilities: MKDIR := mkdir -p RM := rm -f -#============================================================================ -# Typically you should not need to change anything below this line - #----------------------------------------------------------------------------- -# build options -# +# build options... -# combine all the soruces... -C_SRCS += $(QP_SRCS) +BIN_DIR := build_$(TARGET -BIN_DIR := posix - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ +CFLAGS = -c -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ -DQ_SPY -DQ_UTEST -DQ_HOST -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ +CPPFLAGS = -c -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ -DQ_SPY -DQ_UTEST -DQ_HOST -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections +LINKFLAGS := #----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) - C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) @@ -167,27 +173,17 @@ endif # rules # -.PHONY : clean show test run norun +.PHONY : norun test clean show ifeq ($(MAKECMDGOALS),norun) - all : $(TARGET_EXE) norun : all - -else ifeq ($(MAKECMDGOALS),test) - -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - else - all : $(TARGET_EXE) run - endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) # run the test fixture on a POSIX target in a loop, so that it is re-started @@ -206,15 +202,15 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) $< -o $@ # include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),test) - ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),test) -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) endif endif @@ -223,13 +219,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @@ -242,3 +236,4 @@ show : @echo LIBS = $(LIBS) @echo DEFINES = $(DEFINES) @echo HOST = $(HOST) + diff --git a/examples/qutest/dpp/ek-tm4c123gxl.mak b/examples/qutest/dpp/test_dpp/make_tm4c123 similarity index 81% rename from examples/qutest/dpp/ek-tm4c123gxl.mak rename to examples/qutest/dpp/test_dpp/make_tm4c123 index 4458271f..5f1e1608 100644 --- a/examples/qutest/dpp/ek-tm4c123gxl.mak +++ b/examples/qutest/dpp/test_dpp/make_tm4c123 @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for EK-TM4C123GXL, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 +# Product: Makefile for TM4C123, QUTEST, GNU-ARM +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak SCRIPT=py # make and run the Python tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build +# make -f make_tm4c123 # make and run the tests in the current directory +# make -f make_tm4c123 TESTS=philo*.tcl # make and run the selected tests +# make -f make_tm4c123 SCRIPT=py # make and run the Python tests +# make -f make_tm4c123 HOST=localhost:7705 # connect to host:port +# make -f make_tm4c123 norun # only make but not run the tests +# make -f make_tm4c123 clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -47,32 +47,34 @@ # #----------------------------------------------------------------------------- -# project name, binary output directory +# project name, target name, target directory: # PROJECT := test_dpp -TARGET := ek-tm4c123gxl +TARGET := tm4c123 +TARGET_DIR := ..\..\target_tm4c123 #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) +# location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../.. +QPC := ../../../.. endif -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - # QP port used in this project QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + # list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ +VPATH := . \ + ../src \ + $(TARGET_DIR) \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ @@ -80,9 +82,9 @@ VPATH = \ $(QPC)/3rd_party/ek-tm4c123gxl/gnu # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ -I$(QPC)/include \ -I$(QPC)/src \ -I$(QP_PORT_DIR) \ @@ -90,7 +92,7 @@ INCLUDES = \ -I$(QPC)/3rd_party/ek-tm4c123gxl #----------------------------------------------------------------------------- -# files +# project files: # # assembler source files @@ -110,7 +112,7 @@ C_SRCS := \ CPP_SRCS := OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld +LD_SCRIPT := $(TARGET_DIR)/test.ld QP_SRCS := \ qep_hsm.c \ @@ -124,6 +126,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -175,7 +178,7 @@ BIN := $(GNU_ARM)/bin/arm-eabi-objcopy # location of the LMFlash utility on your machine # ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe +FLASH := LMFlash.exe -q ek-tm4c123gxl endif @@ -189,11 +192,9 @@ MKDIR := mkdir RM := rm ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := python -m qspypy.qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif #----------------------------------------------------------------------------- @@ -204,15 +205,15 @@ endif C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) -BIN_DIR := $(TARGET) +BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST @@ -261,24 +262,18 @@ endif $(TARGET_BIN) : $(TARGET_ELF) $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ + $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) + $(FLASH) $(TARGET_BIN) -ifeq ($(SCRIPT),py) run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif + $(FLASH) -c $< + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/qutest/dpp/test_dpp.c b/examples/qutest/dpp/test_dpp/test_dpp.c similarity index 70% rename from examples/qutest/dpp/test_dpp.c rename to examples/qutest/dpp/test_dpp/test_dpp.c index 39b42b40..e195cea5 100644 --- a/examples/qutest/dpp/test_dpp.c +++ b/examples/qutest/dpp/test_dpp/test_dpp.c @@ -1,11 +1,11 @@ /***************************************************************************** * Product: QUTEST fixture for the DPP components -* Last Updated for Version: 5.9.0 -* Date of the Last Update: 2017-05-15 +* Last Updated for Version: 6.3.5 +* Date of the Last Update: 2018-09-16 * -* 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. * @@ -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 "qpc.h" @@ -37,6 +37,8 @@ //#include +//Q_DEFINE_THIS_FILE + /*..........................................................................*/ void QS_onTestSetup(void) { //printf("QS_onTestSetup\n"); @@ -72,18 +74,30 @@ void QS_onCommand(uint8_t cmdId, } /****************************************************************************/ +/*! Host callback function to "massage" the event, if necessary */ +void QS_onTestEvt(QEvt *e) { + (void)e; #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ - - /*! Host callback function to "massage" the event, if necessary */ - void QS_onTestEvt(QEvt *e) { - (void)e; - } - #else /* embedded Target */ - - /*! Target callback function to "massage" the event, if necessary */ - void QS_onTestEvt(QEvt *e) { - (void)e; - } - #endif /* embedded Target */ +} +/*..........................................................................*/ +/*! callback function to output the posted QP events (not used here) */ +void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status) +{ + (void)sender; + (void)status; + switch (e->sig) { + case EAT_SIG: + case DONE_SIG: + case HUNGRY_SIG: + QS_BEGIN(QUTEST_ON_POST, (void *)0) /* application-specific record */ + QS_SIG(e->sig, recipient); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_END() + break; + default: + break; + } +} diff --git a/examples/qutest/dpp/test_dpp/test_init.py b/examples/qutest/dpp/test_dpp/test_init.py new file mode 100644 index 00000000..e1d16a44 --- /dev/null +++ b/examples/qutest/dpp/test_dpp/test_init.py @@ -0,0 +1,71 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +import sys +import pytest +import struct +from qspypy.qspy import * + +# preamble... +def on_reset(qutest): + qutest.expect_pause() + qutest.glb_filter(FILTER.ON) + qutest.Continue() # note continue in lower case. is a reserved word in python + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<0>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<0>,Sig=TEST_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<0>,State=QHsm_top->Philo_thinking") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<0>.timeEvt,AO=AO_Philo<0>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<0>,State=Philo_thinking") + qutest.expect("%timestamp Init===> Obj=AO_Philo<0>,State=Philo_thinking") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<1>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<1>,Sig=TEST_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<1>,State=QHsm_top->Philo_thinking") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<1>.timeEvt,AO=AO_Philo<1>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<1>,State=Philo_thinking") + qutest.expect("%timestamp Init===> Obj=AO_Philo<1>,State=Philo_thinking") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=TEST_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking") + qutest.expect("%timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<3>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<3>,Sig=TEST_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<3>,State=QHsm_top->Philo_thinking") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<3>.timeEvt,AO=AO_Philo<3>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<3>,State=Philo_thinking") + qutest.expect("%timestamp Init===> Obj=AO_Philo<3>,State=Philo_thinking") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<4>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<4>,Sig=TEST_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<4>,State=QHsm_top->Philo_thinking") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<4>.timeEvt,AO=AO_Philo<4>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<4>,State=Philo_thinking") + qutest.expect("%timestamp Init===> Obj=AO_Philo<4>,State=Philo_thinking") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=DONE_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=PAUSE_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=SERVE_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=TEST_SIG") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 0 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 1 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 2 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 3 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 4 thinking") + qutest.expect("===RTC===> St-Init Obj=AO_Table,State=QHsm_top->Table_serving") + qutest.expect("===RTC===> St-Entry Obj=AO_Table,State=Table_serving") + qutest.expect("%timestamp Init===> Obj=AO_Table,State=Table_serving") + +def test_DPP_init(qutest): + pass # empty function + + +if __name__ == "__main__": + # stop on first failure, verbose output but small stack trace + options = ['-x', '-v', '--tb=short'] + options.extend(sys.argv) + pytest.main(options) + diff --git a/examples/qutest/dpp/test_dpp/test_init.tcl b/examples/qutest/dpp/test_dpp/test_init.tcl new file mode 100644 index 00000000..7b417f55 --- /dev/null +++ b/examples/qutest/dpp/test_dpp/test_init.tcl @@ -0,0 +1,62 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +# preamble... +proc on_reset {} { + expect_pause + glb_filter ON + continue + expect "%timestamp AO-Subsc Obj=AO_Philo<0>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Philo<0>,Sig=TEST_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<0>,State=QHsm_top->Philo_thinking" + expect "%timestamp BSP_CALL BSP_random *" + expect "%timestamp TE0-Arm Obj=l_philo<0>.timeEvt,AO=AO_Philo<0>,Tim=*,Int=0" + expect "===RTC===> St-Entry Obj=AO_Philo<0>,State=Philo_thinking" + expect "%timestamp Init===> Obj=AO_Philo<0>,State=Philo_thinking" + expect "%timestamp AO-Subsc Obj=AO_Philo<1>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Philo<1>,Sig=TEST_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<1>,State=QHsm_top->Philo_thinking" + expect "%timestamp BSP_CALL BSP_random *" + expect "%timestamp TE0-Arm Obj=l_philo<1>.timeEvt,AO=AO_Philo<1>,Tim=*,Int=0" + expect "===RTC===> St-Entry Obj=AO_Philo<1>,State=Philo_thinking" + expect "%timestamp Init===> Obj=AO_Philo<1>,State=Philo_thinking" + expect "%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=TEST_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking" + expect "%timestamp BSP_CALL BSP_random *" + expect "%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0" + expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking" + expect "%timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking" + expect "%timestamp AO-Subsc Obj=AO_Philo<3>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Philo<3>,Sig=TEST_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<3>,State=QHsm_top->Philo_thinking" + expect "%timestamp BSP_CALL BSP_random *" + expect "%timestamp TE0-Arm Obj=l_philo<3>.timeEvt,AO=AO_Philo<3>,Tim=*,Int=0" + expect "===RTC===> St-Entry Obj=AO_Philo<3>,State=Philo_thinking" + expect "%timestamp Init===> Obj=AO_Philo<3>,State=Philo_thinking" + expect "%timestamp AO-Subsc Obj=AO_Philo<4>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Philo<4>,Sig=TEST_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<4>,State=QHsm_top->Philo_thinking" + expect "%timestamp BSP_CALL BSP_random *" + expect "%timestamp TE0-Arm Obj=l_philo<4>.timeEvt,AO=AO_Philo<4>,Tim=*,Int=0" + expect "===RTC===> St-Entry Obj=AO_Philo<4>,State=Philo_thinking" + expect "%timestamp Init===> Obj=AO_Philo<4>,State=Philo_thinking" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=DONE_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=PAUSE_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=SERVE_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=TEST_SIG" + expect "%timestamp BSP_CALL BSP_displayPhilStat 0 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 1 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 2 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 3 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 4 thinking" + expect "===RTC===> St-Init Obj=AO_Table,State=QHsm_top->Table_serving" + expect "===RTC===> St-Entry Obj=AO_Table,State=Table_serving" + expect "%timestamp Init===> Obj=AO_Table,State=Table_serving" +} + +# tests... +test "DPP init" + +# the end +end diff --git a/examples/qutest/dpp/test_dpp/test_tick.py b/examples/qutest/dpp/test_dpp/test_tick.py new file mode 100644 index 00000000..90e883fd --- /dev/null +++ b/examples/qutest/dpp/test_dpp/test_tick.py @@ -0,0 +1,84 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +import sys +import pytest +import struct +from qspypy.qspy import * + +# preamble... +def on_reset(qutest): + qutest.expect_pause() + qutest.Continue() # note continue in lower case. is a reserved word in python + +# tests... +def test_tick(qutest): + qutest.glb_filter(FILTER.ON) + qutest.current_obj(QS_OBJ_KIND.TE,'l_philo<2>.timeEvt') + qutest.tick() + qutest.expect(" Tick<0> Ctr=*") + qutest.expect(" TE0-ADis Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>") + qutest.expect("%timestamp TE0-Post Obj=l_philo<2>.timeEvt,Sig=TIMEOUT_SIG,AO=AO_Philo<2>") + qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt,*") + qutest.expect("%timestamp AO-GetL Obj=AO_Philo<2>,Evt") + qutest.expect("%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking") + qutest.expect("%timestamp TE0-DisA Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>") + qutest.expect("===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking") + qutest.expect("%timestamp QF-New Sig=HUNGRY_SIG,*") + qutest.expect("%timestamp MP-Get Obj=EvtPool1,*") + qutest.expect("%timestamp AO-Post Sdr=AO_Philo<2>,Obj=AO_Table,Evt,*") + qutest.expect("%timestamp QUTEST_ON_POST HUNGRY_SIG,Obj=AO_Table 2") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_hungry") + qutest.expect("%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking->Philo_hungry") + qutest.expect("%timestamp AO-GetL Obj=AO_Table,Evt") + qutest.expect("%timestamp Disp===> Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 2 hungry ") + qutest.expect("%timestamp QF-New Sig=EAT_SIG,*") + qutest.expect("%timestamp MP-Get Obj=EvtPool1,*") + qutest.expect("%timestamp QF-Pub Sdr=AO_Table,Evt") + qutest.expect("%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<4>,Evt,*") + qutest.expect("%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<4> 2") + qutest.expect("%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<3>,Evt,*") + qutest.expect("%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<3> 2") + qutest.expect("%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<2>,Evt,*") + qutest.expect("%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<2> 2") + qutest.expect("%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<1>,Evt,*") + qutest.expect("%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<1> 2") + qutest.expect("%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<0>,Evt,*") + qutest.expect("%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<0> 2") + qutest.expect("%timestamp QF-gcA EvtIntern Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving") + qutest.expect("%timestamp QF-gc Evt") + qutest.expect("%timestamp MP-Put Obj=EvtPool1,*") + qutest.expect("%timestamp AO-GetL Obj=AO_Philo<4>,Evt Obj=AO_Philo<4>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp =>Intern Obj=AO_Philo<4>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp QF-gcA Evt,Evt Obj=AO_Philo<3>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp =>Intern Obj=AO_Philo<3>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp QF-gcA Evt,Evt Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_eating") + qutest.expect("%timestamp ===>Tran Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry->Philo_eating") + qutest.expect("%timestamp QF-gcA Evt,Evt Obj=AO_Philo<1>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp =>Intern Obj=AO_Philo<1>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp QF-gcA Evt,Evt Obj=AO_Philo<0>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp =>Intern Obj=AO_Philo<0>,Sig=EAT_SIG,State=Philo_thinking") + qutest.expect("%timestamp QF-gc Evt.timeEvt +tick +expect " Tick<0> Ctr=*" +expect " TE0-ADis Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" +expect "%timestamp TE0-Post Obj=l_philo<2>.timeEvt,Sig=TIMEOUT_SIG,AO=AO_Philo<2>" +expect "%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt,*" +expect "%timestamp AO-GetL Obj=AO_Philo<2>,Evt" +expect "%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking" +expect "%timestamp TE0-DisA Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" +expect "===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking" +expect "%timestamp QF-New Sig=HUNGRY_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp AO-Post Sdr=AO_Philo<2>,Obj=AO_Table,Evt,*" +expect "%timestamp QUTEST_ON_POST HUNGRY_SIG,Obj=AO_Table 2" +expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_hungry" +expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking->Philo_hungry" +expect "%timestamp AO-GetL Obj=AO_Table,Evt" +expect "%timestamp Disp===> Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving" +expect "%timestamp BSP_CALL BSP_displayPhilStat 2 hungry " +expect "%timestamp QF-New Sig=EAT_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-Pub Sdr=AO_Table,Evt" +expect "%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<4>,Evt,*" +expect "%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<4> 2" +expect "%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<3>,Evt,*" +expect "%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<3> 2" +expect "%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<2>,Evt,*" +expect "%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<2> 2" +expect "%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<1>,Evt,*" +expect "%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<1> 2" +expect "%timestamp AO-Post Sdr=AO_Table,Obj=AO_Philo<0>,Evt,*" +expect "%timestamp QUTEST_ON_POST EAT_SIG,Obj=AO_Philo<0> 2" +expect "%timestamp QF-gcA EvtIntern Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving" +expect "%timestamp QF-gc Evt" +expect "%timestamp MP-Put Obj=EvtPool1,*" +expect "%timestamp AO-GetL Obj=AO_Philo<4>,Evt Obj=AO_Philo<4>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp =>Intern Obj=AO_Philo<4>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp QF-gcA Evt,Evt Obj=AO_Philo<3>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp =>Intern Obj=AO_Philo<3>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp QF-gcA Evt,Evt Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry" +expect "%timestamp BSP_CALL BSP_random *" +expect "%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0" +expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_eating" +expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry->Philo_eating" +expect "%timestamp QF-gcA Evt,Evt Obj=AO_Philo<1>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp =>Intern Obj=AO_Philo<1>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp QF-gcA Evt,Evt Obj=AO_Philo<0>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp =>Intern Obj=AO_Philo<0>,Sig=EAT_SIG,State=Philo_thinking" +expect "%timestamp QF-gc Evt $@ @@ -205,12 +231,10 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun + $(CC) $(CFLAGS) $< -o $@ # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) @@ -222,13 +246,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @@ -243,5 +265,4 @@ show : @echo QTOOLS = $(QTOOLS) @echo QUTEST = $(QUTEST) @echo TESTS = $(TESTS) - @echo HOST = $(HOST) diff --git a/examples/qutest/TDDbook_Flash/conftest.py b/examples/qutest/dpp/test_philo/conftest.py similarity index 69% rename from examples/qutest/TDDbook_Flash/conftest.py rename to examples/qutest/dpp/test_philo/conftest.py index 48253da6..5a61638a 100644 --- a/examples/qutest/TDDbook_Flash/conftest.py +++ b/examples/qutest/dpp/test_philo/conftest.py @@ -4,4 +4,4 @@ # # Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset +from qspypy.fixtures import * diff --git a/examples/qutest/dpp/test_philo/test_init.py b/examples/qutest/dpp/test_philo/test_init.py new file mode 100644 index 00000000..0f37a8f5 --- /dev/null +++ b/examples/qutest/dpp/test_philo/test_init.py @@ -0,0 +1,32 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +import sys +import pytest +import struct +from qspypy.qspy import * + +# preamble... +def on_reset(qutest): + qutest.expect_pause() + qutest.glb_filter(FILTER.ON) + qutest.Continue() # note continue in lower case. is a reserved word in python + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=TEST_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking") + qutest.expect("%timestamp BSP_CALL BSP_random *") + qutest.expect("%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0") + qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking") + qutest.expect("%timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking") + +# tests... +def test_init(qutest): + pass # empty (runs only on_reset) + +# end... +if __name__ == "__main__": + # stop on first failure, verbose output but small stack trace + options = ['-x', '-v', '--tb=short'] + options.extend(sys.argv) + pytest.main(options) + diff --git a/examples/qutest/dpp/test_philo/test_init.tcl b/examples/qutest/dpp/test_philo/test_init.tcl new file mode 100644 index 00000000..62e9c23e --- /dev/null +++ b/examples/qutest/dpp/test_philo/test_init.tcl @@ -0,0 +1,22 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +# preamble... +proc on_reset {} { + expect_pause + glb_filter ON + continue + expect "%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=TEST_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking" + expect "%timestamp BSP_CALL BSP_random *" + expect "%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0" + expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking" + expect "%timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking" +} + +# tests... +test "init" + +# the end +end diff --git a/examples/qutest/dpp/test_philo/test_philo.c b/examples/qutest/dpp/test_philo/test_philo.c new file mode 100644 index 00000000..4e97f660 --- /dev/null +++ b/examples/qutest/dpp/test_philo/test_philo.c @@ -0,0 +1,160 @@ +/***************************************************************************** +* Product: QUTEST fixture for the DPP components +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-04 +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* 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://www.state-machine.com +* mailto:info@state-machine.com +*****************************************************************************/ +#include "qpc.h" +#include "bsp.h" +#include "dpp.h" + +//#include + +//Q_DEFINE_THIS_FILE + +/* instantiate dummy collaborator AOs... */ +static QActiveDummy l_dummyTable; +QActive * const AO_Table = &l_dummyTable.super; + +/*..........................................................................*/ +int main(int argc, char *argv[]) { + static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; + static QSubscrList subscrSto[MAX_PUB_SIG]; + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ + uint8_t n; + + QF_init(); /* initialize the framework and the underlying RT kernel */ + BSP_init(argc, argv); /* initialize the Board Support Package */ + + /* object dictionaries... */ + QS_OBJ_DICTIONARY(AO_Table); + QS_OBJ_DICTIONARY(AO_Philo[0]); + QS_OBJ_DICTIONARY(AO_Philo[1]); + QS_OBJ_DICTIONARY(AO_Philo[2]); + QS_OBJ_DICTIONARY(AO_Philo[3]); + QS_OBJ_DICTIONARY(AO_Philo[4]); + + /* signal dictionaries */ + 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); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + + /* pause execution of the test and wait for the test script to continue */ + QS_TEST_PAUSE(); + + /* initialize publish-subscribe... */ + QF_psInit(subscrSto, Q_DIM(subscrSto)); + + /* initialize event pools... */ + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + /* start the active objects... */ + Philo_ctor(); /* instantiate all Philosopher active objects */ + n = 2U; + QACTIVE_START(AO_Philo[n], /* AO to start */ + (uint_fast8_t)(n + 1), /* QP priority of the AO */ + philoQueueSto[n], /* event queue storage */ + Q_DIM(philoQueueSto[n]), /* queue length [events] */ + (void *)0, /* stack storage (not used) */ + 0U, /* size of the stack [bytes] */ + (QEvt *)0); /* initialization event */ + + /* instantiate all dummy AOs... */ + QActiveDummy_ctor(&l_dummyTable); + + return QF_run(); /* run the QF application */ +} + +/*..........................................................................*/ +void QS_onTestSetup(void) { + //printf("QS_onTestSetup\n"); +} +void QS_onTestTeardown(void) { + //printf("QS_onTestTeardown\n"); +} + +/*..........................................................................*/ +/*! callback function to execute user commands */ +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + (void)cmdId; + (void)param1; + (void)param2; + (void)param3; + + switch (cmdId) { + case 0U: { + QEvt const e = { PAUSE_SIG, 0U, 0U }; + QHSM_DISPATCH(&AO_Table->super, &e); + break; + } + case 1U: { + QEvt const e = { SERVE_SIG, 0U, 0U }; + QHSM_DISPATCH(&AO_Table->super, &e); + break; + } + default: + break; + } +} + +/****************************************************************************/ +/*! Host callback function to "massage" the event, if necessary */ +void QS_onTestEvt(QEvt *e) { + (void)e; +#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ +#else /* embedded Target */ +#endif /* embedded Target */ +} +/*..........................................................................*/ +/*! callback function to output the posted QP events (not used here) */ +void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status) +{ + (void)sender; + (void)status; + switch (e->sig) { + case EAT_SIG: + case DONE_SIG: + case HUNGRY_SIG: + QS_BEGIN(QUTEST_ON_POST, (void *)0) /* app-specific record */ + QS_SIG(e->sig, recipient); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_END() + break; + default: + break; + } +} diff --git a/examples/qutest/dpp/test_philo.py b/examples/qutest/dpp/test_philo/test_philo.py similarity index 75% rename from examples/qutest/dpp/test_philo.py rename to examples/qutest/dpp/test_philo/test_philo.py index 60a5ddd0..06ed4fba 100644 --- a/examples/qutest/dpp/test_philo.py +++ b/examples/qutest/dpp/test_philo/test_philo.py @@ -4,24 +4,24 @@ import sys import pytest import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - +from qspypy.qspy import * +# preamble... def on_reset(qutest): qutest.expect_pause() qutest.glb_filter(FILTER.SM) - qutest.loc_filter(QS_OBJ_KIND.SM_AO,"AO_Philo<2>") - qutest.Continue() + qutest.loc_filter(QS_OBJ_KIND.SM_AO, 'AO_Philo<2>') + qutest.Continue() # note continue in lower case. is a reserved word in python qutest.expect("===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking") qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking") qutest.expect("%timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking") - qutest.glb_filter(FILTER.SM,FILTER.AO,FILTER.UA) - qutest.current_obj(QS_OBJ_KIND.SM_AO,"AO_Philo<2>") - + qutest.glb_filter(FILTER.SM, FILTER.AO, FILTER.UA) + qutest.current_obj(QS_OBJ_KIND.SM_AO, 'AO_Philo<2>') +# tests... def test_TIMEOUT_Philo_post(qutest): - qutest.post("TIMEOUT_SIG") - qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt,Evt,Evt Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking") qutest.expect("===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking") @@ -30,21 +30,22 @@ def test_TIMEOUT_Philo_post(qutest): qutest.expect("%timestamp Trg-Done QS_RX_EVENT") def test_publish_EAT_2(qutest_noreset): - qutest = qutest_noreset # name change - qutest.loc_filter(QS_OBJ_KIND.SM_AO,"AO_Philo<2>") - qutest.publish("EAT_SIG", struct.pack('< B', 2)) + qutest = qutest_noreset # Rename for consistancy + qutest.loc_filter(QS_OBJ_KIND.SM_AO, 'AO_Philo<2>') + qutest.publish('EAT_SIG', struct.pack('< B', 2)) # Send byte of value 2 qutest.expect("%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt 2") qutest.expect("%timestamp Trg-Done QS_RX_EVENT") qutest.expect("%timestamp AO-GetL Obj=AO_Philo<2>,Evt Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry") - qutest.expect("%timestamp BSP_CALL BSP_random 123") + qutest.expect("%timestamp BSP_CALL BSP_random *") qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_eating") qutest.expect("%timestamp ===>Tran Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry->Philo_eating") qutest.expect("%timestamp Trg-Done QS_RX_EVENT") def test_TIMEOUT_Philo_thinking_ASSERT(qutest): - qutest.probe("QActive_post_",1) - qutest.dispatch("TIMEOUT_SIG") + qutest.probe('QActive_post_', 1) + qutest.dispatch('TIMEOUT_SIG') qutest.expect("%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking") qutest.expect("===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking") qutest.expect("%timestamp TstProbe Fun=QActive_post_,Data=1") @@ -52,26 +53,26 @@ def test_TIMEOUT_Philo_thinking_ASSERT(qutest): def test_TIMEOUT_Philo_eating_PUBLISH_from_AO(qutest): qutest.glb_filter(FILTER.OFF) - qutest.dispatch("TIMEOUT_SIG") + qutest.dispatch('TIMEOUT_SIG') qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - qutest.dispatch("EAT_SIG", struct.pack('< B', 2)) + qutest.dispatch('EAT_SIG', struct.pack('< B', 2)) qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - qutest.glb_filter(FILTER.SM,FILTER.AO,FILTER.QF) - qutest.dispatch("TIMEOUT_SIG") + qutest.glb_filter(FILTER.SM, FILTER.AO, FILTER.QF) + qutest.dispatch('TIMEOUT_SIG') qutest.expect("%timestamp QF-New Sig=TIMEOUT_SIG,*") qutest.expect("%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_eating") qutest.expect("%timestamp QF-New Sig=DONE_SIG,*") qutest.expect("%timestamp QF-Pub Sdr=AO_Philo<2>,Evt") - qutest.expect("%timestamp QF-gcA Evt") + qutest.expect("%timestamp QF-gc? Evt St-Exit Obj=AO_Philo<2>,State=Philo_eating") qutest.expect("===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking") qutest.expect("%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking") - qutest.expect("%timestamp QF-gc Evt") + qutest.expect("%timestamp QF-gc? Evt.timeEvt") + qutest.glb_filter(FILTER.SM, FILTER.AO, FILTER.TE) + qutest.current_obj(QS_OBJ_KIND.TE, 'l_philo<2>.timeEvt') qutest.tick() qutest.expect(" TE0-ADis Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>") qutest.expect("%timestamp TE0-Post Obj=l_philo<2>.timeEvt,Sig=TIMEOUT_SIG,AO=AO_Philo<2>") @@ -84,8 +85,10 @@ def test_timeEvt_Philo_tick(qutest): qutest.expect("%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking->Philo_hungry") qutest.expect("%timestamp Trg-Done QS_RX_TICK") - +# end... if __name__ == "__main__": + # stop on first failure, verbose output but small stack trace options = ['-x', '-v', '--tb=short'] options.extend(sys.argv) pytest.main(options) + diff --git a/examples/qutest/dpp/test_philo.tcl b/examples/qutest/dpp/test_philo/test_philo.tcl similarity index 51% rename from examples/qutest/dpp/test_philo.tcl rename to examples/qutest/dpp/test_philo/test_philo.tcl index 1574fc4e..60d8615d 100644 --- a/examples/qutest/dpp/test_philo.tcl +++ b/examples/qutest/dpp/test_philo/test_philo.tcl @@ -4,77 +4,86 @@ # preamble... proc on_reset {} { expect_pause - glb_filter SM - loc_filter SM_AO AO_Philo<2> continue - expect "===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->Philo_thinking" - expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking" - expect "%timestamp Init===> Obj=AO_Philo<2>,State=Philo_thinking" - glb_filter SM AO UA + glb_filter ON + loc_filter SM_AO AO_Philo<2> current_obj SM_AO AO_Philo<2> + current_obj TE l_philo<2>.timeEvt } # tests... -test "TIMEOUT->Philo (post)" -post TIMEOUT_SIG +test "Philo-thinking tick" +tick +expect " Tick<0> Ctr=*" +expect " TE0-ADis Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" +expect "%timestamp TE0-Post Obj=l_philo<2>.timeEvt,Sig=TIMEOUT_SIG,AO=AO_Philo<2>" expect "%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt,Evt Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking" +expect "%timestamp TE0-DisA Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" expect "===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking" +expect "%timestamp QF-New Sig=HUNGRY_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-gc Evt St-Entry Obj=AO_Philo<2>,State=Philo_hungry" expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking->Philo_hungry" -expect "%timestamp Trg-Done QS_RX_EVENT" +expect "%timestamp Trg-Done QS_RX_TICK" -test "publish EAT(2)" -noreset -loc_filter SM_AO AO_Philo<2> +test "Philo-hungry publish EAT" -noreset publish EAT_SIG [binary format c 2] +expect "%timestamp QF-New Sig=EAT_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-Pub Sdr=QS_RX,Evt,Evt 2" +expect "%timestamp QF-gc? Evt,Evt Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry" -expect "%timestamp BSP_CALL BSP_random 123" +expect "%timestamp BSP_CALL BSP_random *" +expect "%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0" expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_eating" expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=EAT_SIG,State=Philo_hungry->Philo_eating" +expect "%timestamp QF-gc EvtPhilo_thinking (ASSERT)" -probe QActive_post_ 1 -dispatch TIMEOUT_SIG -expect "%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking" -expect "===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking" -expect "%timestamp TstProbe Fun=QActive_post_,Data=1" -expect "%timestamp =ASSERT= Mod=qf_actq,Loc=110" - -test "TIMEOUT->Philo_eating (PUBLISH from AO)" -glb_filter OFF -dispatch TIMEOUT_SIG -expect "%timestamp Trg-Done QS_RX_EVENT" -dispatch EAT_SIG [binary format c 2] -expect "%timestamp Trg-Done QS_RX_EVENT" -glb_filter SM AO QF -dispatch TIMEOUT_SIG -expect "%timestamp QF-New Sig=TIMEOUT_SIG,*" -expect "%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_eating" -expect "%timestamp QF-New Sig=DONE_SIG,*" -expect "%timestamp QF-Pub Sdr=AO_Philo<2>,Evt" -expect "%timestamp QF-gcA Evt" -expect "===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_eating" -expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking" -expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking" -expect "%timestamp QF-gc Evt" -expect "%timestamp Trg-Done QS_RX_EVENT" - -test "timeEvt->Philo (tick)" -glb_filter SM AO TE -current_obj TE l_philo<2>.timeEvt +test "Philo-eating tick" -noreset tick +expect " Tick<0> Ctr=*" expect " TE0-ADis Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" expect "%timestamp TE0-Post Obj=l_philo<2>.timeEvt,Sig=TIMEOUT_SIG,AO=AO_Philo<2>" -expect "%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt,Evt,Evt,*" +expect "%timestamp AO-GetL Obj=AO_Philo<2>,Evt" +expect "%timestamp Disp===> Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_eating" +expect "%timestamp QF-New Sig=DONE_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-Pub Sdr=AO_Philo<2>,Evt" +expect "%timestamp QF-gc Evt" +expect "%timestamp MP-Put Obj=EvtPool1,*" +expect "%timestamp TE0-DisA Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" +expect "===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_eating" +expect "%timestamp BSP_CALL BSP_random *" +expect "%timestamp TE0-Arm Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>,Tim=*,Int=0" +expect "===RTC===> St-Entry Obj=AO_Philo<2>,State=Philo_thinking" +expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking" +expect "%timestamp Trg-Done QS_RX_TICK" + +test "Philo-thinking tick(2)" -noreset +tick +expect " Tick<0> Ctr=*" +expect " TE0-ADis Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" +expect "%timestamp TE0-Post Obj=l_philo<2>.timeEvt,Sig=TIMEOUT_SIG,AO=AO_Philo<2>" +expect "%timestamp AO-Post Sdr=QS_RX,Obj=AO_Philo<2>,Evt,Evt Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking" expect "%timestamp TE0-DisA Obj=l_philo<2>.timeEvt,AO=AO_Philo<2>" expect "===RTC===> St-Exit Obj=AO_Philo<2>,State=Philo_thinking" +expect "%timestamp QF-New Sig=HUNGRY_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-gc Evt St-Entry Obj=AO_Philo<2>,State=Philo_hungry" expect "%timestamp ===>Tran Obj=AO_Philo<2>,Sig=TIMEOUT_SIG,State=Philo_thinking->Philo_hungry" expect "%timestamp Trg-Done QS_RX_TICK" diff --git a/examples/qutest/dpp/test_table.tcl b/examples/qutest/dpp/test_table.tcl deleted file mode 100644 index eb919882..00000000 --- a/examples/qutest/dpp/test_table.tcl +++ /dev/null @@ -1,45 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - expect_pause - continue - glb_filter SM AO UA - loc_filter AO AO_Table - current_obj SM_AO AO_Table -} - -proc on_setup {} { - #puts "on_setup" -} - -proc on_teardown {} { - #puts "on_teardown" -} - - -# tests... -test "PAUSE->Table" -dispatch PAUSE_SIG -expect "%timestamp Disp===> Obj=AO_Table,Sig=PAUSE_SIG,State=Table_serving" -expect "%timestamp BSP_CALL BSP_displayPaused 1" -expect "===RTC===> St-Entry Obj=AO_Table,State=Table_paused" -expect "%timestamp ===>Tran Obj=AO_Table,Sig=PAUSE_SIG,State=Table_serving->Table_paused" -expect "%timestamp Trg-Done QS_RX_EVENT" - -test "SERVE->Table (1)" -command 1 -expect "%timestamp Disp===> Obj=AO_Table,Sig=SERVE_SIG,State=Table_serving" -expect "%timestamp =>Ignore Obj=AO_Table,Sig=SERVE_SIG,State=Table_serving" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -test "SERVE->Table (2)" -noreset -probe BSP_displayPaused 1 -dispatch PAUSE_SIG -expect "%timestamp Disp===> Obj=AO_Table,Sig=PAUSE_SIG,State=Table_serving" -expect "%timestamp TstProbe Fun=BSP_displayPaused,Data=1" -expect "%timestamp =ASSERT= Mod=bsp,Loc=100" - -# the end -end diff --git a/examples/qutest/defer/Makefile b/examples/qutest/dpp/test_table/Makefile similarity index 65% rename from examples/qutest/defer/Makefile rename to examples/qutest/dpp/test_table/Makefile index ec9cd41b..6f71714c 100644 --- a/examples/qutest/defer/Makefile +++ b/examples/qutest/dpp/test_table/Makefile @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for QUTEST; QP/C on Win32 host -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 +# Product: Makefile for QUTEST-QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -47,113 +47,145 @@ # #----------------------------------------------------------------------------- -# project name +# project name: # -PROJECT := test_defer +PROJECT := test_table #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - # list of all source directories used by this project -VPATH = \ - . +VPATH = . \ + ../src # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include +INCLUDES = -I. \ + -I../src + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif #----------------------------------------------------------------------------- -# files +# project files: # # C source files... C_SRCS := \ - defer.c \ - test_defer.c + bsp.c \ + table.c \ + test_table.c # C++ source files... -CPP_SRCS := +CPP_SRCS := -LIB_DIRS := -LIBS := +LIB_DIRS := +LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API DEFINES := -DQP_API_VERSION=9999 #----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + QP_PORT_DIR := $(QPC)/ports/win32-qutest + LIB_DIRS += -L$(QP_PORT_DIR)/mingw + LIBS += -lqp -lwsock32 +QS_SRCS := +else + QP_PORT_DIR := $(QPC)/ports/posix-qutest + C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + + LIBS += -lpthread +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QPC)/src/qs $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: # # NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH # CC := gcc CPP := g++ LINK := gcc # for C programs #LINK := g++ # for C++ programs -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif -#============================================================================ -# Typically you should not need to change anything below this line - #----------------------------------------------------------------------------- -# build options +# basic utilities (depends on the OS this Makefile runs on): # - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif #----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 +# build options... +BIN_DIR := build + +CFLAGS = -c -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +CPPFLAGS = -c -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +LINKFLAGS := + +#----------------------------------------------------------------------------- C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) @@ -168,7 +200,7 @@ endif # rules # -.PHONY : run norun +.PHONY : norun clean show ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_EXE) @@ -186,16 +218,11 @@ endif endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) -ifeq ($(SCRIPT),py) run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ @@ -204,12 +231,10 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun + $(CC) $(CFLAGS) $< -o $@ # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) @@ -221,13 +246,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @@ -242,5 +265,4 @@ show : @echo QTOOLS = $(QTOOLS) @echo QUTEST = $(QUTEST) @echo TESTS = $(TESTS) - @echo HOST = $(HOST) diff --git a/examples/qutest/TDDbook_LedDriver/conftest.py b/examples/qutest/dpp/test_table/conftest.py similarity index 69% rename from examples/qutest/TDDbook_LedDriver/conftest.py rename to examples/qutest/dpp/test_table/conftest.py index 48253da6..5a61638a 100644 --- a/examples/qutest/TDDbook_LedDriver/conftest.py +++ b/examples/qutest/dpp/test_table/conftest.py @@ -4,4 +4,4 @@ # # Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset +from qspypy.fixtures import * diff --git a/examples/qutest/dpp/test_table/test_init.py b/examples/qutest/dpp/test_table/test_init.py new file mode 100644 index 00000000..f3f5dce2 --- /dev/null +++ b/examples/qutest/dpp/test_table/test_init.py @@ -0,0 +1,47 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +import sys +import pytest +import struct +from qspypy.qspy import * + +# preamble... +def on_reset(qutest): + qutest.expect_pause() + qutest.glb_filter(FILTER.ON) + qutest.Continue() # note continue in lower case. is a reserved word in python + qutest.expect("===RTC===> St-Init Obj=AO_Philo<0>,State=QHsm_top->NULL") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<0>,Sig=EAT_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<1>,State=QHsm_top->NULL") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<1>,Sig=EAT_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->NULL") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=EAT_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<3>,State=QHsm_top->NULL") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<3>,Sig=EAT_SIG") + qutest.expect("===RTC===> St-Init Obj=AO_Philo<4>,State=QHsm_top->NULL") + qutest.expect("%timestamp AO-Subsc Obj=AO_Philo<4>,Sig=EAT_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=DONE_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=PAUSE_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=SERVE_SIG") + qutest.expect("%timestamp AO-Subsc Obj=AO_Table,Sig=TEST_SIG") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 0 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 1 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 2 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 3 thinking") + qutest.expect("%timestamp BSP_CALL BSP_displayPhilStat 4 thinking") + qutest.expect("===RTC===> St-Init Obj=AO_Table,State=QHsm_top->Table_serving") + qutest.expect("===RTC===> St-Entry Obj=AO_Table,State=Table_serving") + qutest.expect("%timestamp Init===> Obj=AO_Table,State=Table_serving") + +# tests... +def test_init(qutest): + pass # empty (runs only on_reset) + +# end... +if __name__ == "__main__": + # stop on first failure, verbose output but small stack trace + options = ['-x', '-v', '--tb=short'] + options.extend(sys.argv) + pytest.main(options) + diff --git a/examples/qutest/dpp/test_table/test_init.tcl b/examples/qutest/dpp/test_table/test_init.tcl new file mode 100644 index 00000000..2536e129 --- /dev/null +++ b/examples/qutest/dpp/test_table/test_init.tcl @@ -0,0 +1,37 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +# preamble... +proc on_reset {} { + expect_pause + glb_filter ON + continue + expect "===RTC===> St-Init Obj=AO_Philo<0>,State=QHsm_top->NULL" + expect "%timestamp AO-Subsc Obj=AO_Philo<0>,Sig=EAT_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<1>,State=QHsm_top->NULL" + expect "%timestamp AO-Subsc Obj=AO_Philo<1>,Sig=EAT_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<2>,State=QHsm_top->NULL" + expect "%timestamp AO-Subsc Obj=AO_Philo<2>,Sig=EAT_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<3>,State=QHsm_top->NULL" + expect "%timestamp AO-Subsc Obj=AO_Philo<3>,Sig=EAT_SIG" + expect "===RTC===> St-Init Obj=AO_Philo<4>,State=QHsm_top->NULL" + expect "%timestamp AO-Subsc Obj=AO_Philo<4>,Sig=EAT_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=DONE_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=PAUSE_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=SERVE_SIG" + expect "%timestamp AO-Subsc Obj=AO_Table,Sig=TEST_SIG" + expect "%timestamp BSP_CALL BSP_displayPhilStat 0 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 1 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 2 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 3 thinking" + expect "%timestamp BSP_CALL BSP_displayPhilStat 4 thinking" + expect "===RTC===> St-Init Obj=AO_Table,State=QHsm_top->Table_serving" + expect "===RTC===> St-Entry Obj=AO_Table,State=Table_serving" + expect "%timestamp Init===> Obj=AO_Table,State=Table_serving" +} + +# tests... +test "init" + +# the end +end diff --git a/examples/qutest/dpp/test_table/test_table.c b/examples/qutest/dpp/test_table/test_table.c new file mode 100644 index 00000000..bab4d313 --- /dev/null +++ b/examples/qutest/dpp/test_table/test_table.c @@ -0,0 +1,176 @@ +/***************************************************************************** +* Product: QUTEST fixture for the DPP components +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-04 +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* 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://www.state-machine.com +* mailto:info@state-machine.com +*****************************************************************************/ +#include "qpc.h" +#include "bsp.h" +#include "dpp.h" + +//#include + +//Q_DEFINE_THIS_FILE + +/* instantiate dummy collaborator AOs... */ +static QActiveDummy l_dummyPhilo[N_PHILO]; +QActive * const AO_Philo[N_PHILO] = { + &l_dummyPhilo[0].super, + &l_dummyPhilo[1].super, + &l_dummyPhilo[2].super, + &l_dummyPhilo[3].super, + &l_dummyPhilo[4].super +}; + +/*..........................................................................*/ +int main(int argc, char *argv[]) { + static QEvt const *tableQueueSto[N_PHILO]; + static QSubscrList subscrSto[MAX_PUB_SIG]; + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ + uint8_t n; + + QF_init(); /* initialize the framework and the underlying RT kernel */ + BSP_init(argc, argv); /* initialize the Board Support Package */ + + /* object dictionaries... */ + QS_OBJ_DICTIONARY(AO_Table); + QS_OBJ_DICTIONARY(AO_Philo[0]); + QS_OBJ_DICTIONARY(AO_Philo[1]); + QS_OBJ_DICTIONARY(AO_Philo[2]); + QS_OBJ_DICTIONARY(AO_Philo[3]); + QS_OBJ_DICTIONARY(AO_Philo[4]); + + /* signal dictionaries */ + 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); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + + /* pause execution of the test and wait for the test script to continue */ + QS_TEST_PAUSE(); + + /* initialize publish-subscribe... */ + QF_psInit(subscrSto, Q_DIM(subscrSto)); + + /* initialize event pools... */ + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + /* start and setup dummy AOs... + * NOTE: You need to start dummy AOs, if you wish to subscribe + * them to events. + */ + for (n = 0; n < N_PHILO; ++n) { + QActiveDummy_ctor(&l_dummyPhilo[n]); + QACTIVE_START(AO_Philo[n], + (uint_fast8_t)(n + 1U), /* priority */ + (QEvt const **)0, 0U, (void *)0, 0U, + (QEvt const *)0); + QActive_subscribe(AO_Philo[n], EAT_SIG); + } + + + /* start the active objects... */ + Table_ctor(); /* instantiate the Table active object */ + QACTIVE_START(AO_Table, /* AO to start */ + (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ + tableQueueSto, /* event queue storage */ + Q_DIM(tableQueueSto), /* queue length [events] */ + (void *)0, /* stack storage (not used) */ + 0U, /* size of the stack [bytes] */ + (QEvt *)0); /* initialization event */ + + return QF_run(); /* run the QF application */ +} + +/*..........................................................................*/ +void QS_onTestSetup(void) { + //printf("QS_onTestSetup\n"); +} +void QS_onTestTeardown(void) { + //printf("QS_onTestTeardown\n"); +} + +/*..........................................................................*/ +/*! callback function to execute user commands */ +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + (void)cmdId; + (void)param1; + (void)param2; + (void)param3; + + switch (cmdId) { + case 0U: { + QEvt const e = { PAUSE_SIG, 0U, 0U }; + QHSM_DISPATCH(&AO_Table->super, &e); + break; + } + case 1U: { + QEvt const e = { SERVE_SIG, 0U, 0U }; + QHSM_DISPATCH(&AO_Table->super, &e); + break; + } + default: + break; + } +} + +/****************************************************************************/ +/*! Host callback function to "massage" the event, if necessary */ +void QS_onTestEvt(QEvt *e) { + (void)e; +#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ +#else /* embedded Target */ +#endif /* embedded Target */ +} +/*..........................................................................*/ +/*! callback function to output the posted QP events (not used here) */ +void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status) +{ + (void)sender; + (void)status; + switch (e->sig) { + case EAT_SIG: + case DONE_SIG: + case HUNGRY_SIG: + QS_BEGIN(QUTEST_ON_POST, (void *)0) /* app-specific record */ + QS_SIG(e->sig, recipient); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_END() + break; + default: + break; + } +} diff --git a/examples/qutest/dpp/test_table.py b/examples/qutest/dpp/test_table/test_table.py similarity index 67% rename from examples/qutest/dpp/test_table.py rename to examples/qutest/dpp/test_table/test_table.py index 4af15452..3dfac6f9 100644 --- a/examples/qutest/dpp/test_table.py +++ b/examples/qutest/dpp/test_table/test_table.py @@ -4,28 +4,26 @@ import sys import pytest import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - +from qspypy.qspy import * +# preamble... def on_reset(qutest): qutest.expect_pause() - qutest.Continue() - qutest.glb_filter(FILTER.SM,FILTER.AO,FILTER.UA) - qutest.loc_filter(QS_OBJ_KIND.AO,"AO_Table") - qutest.current_obj(QS_OBJ_KIND.SM_AO,"AO_Table") - + qutest.Continue() # note continue in lower case. is a reserved word in python + qutest.glb_filter(FILTER.SM, FILTER.AO, FILTER.UA) + qutest.loc_filter(QS_OBJ_KIND.SM_AO, 'AO_Table') + qutest.current_obj(QS_OBJ_KIND.SM_AO, 'AO_Table') def on_setup(qutest): - print("on_setup") - + print("\non_setup") def on_teardown(qutest): - print("on_teardown") - + print("\non_teardown") +# tests... def test_PAUSE_Table(qutest): - qutest.dispatch("PAUSE_SIG") + qutest.dispatch('PAUSE_SIG') qutest.expect("%timestamp Disp===> Obj=AO_Table,Sig=PAUSE_SIG,State=Table_serving") qutest.expect("%timestamp BSP_CALL BSP_displayPaused 1") qutest.expect("===RTC===> St-Entry Obj=AO_Table,State=Table_paused") @@ -39,14 +37,16 @@ def test_SERVE_Table_1(qutest): qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") def test_SERVE_Table_2(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("BSP_displayPaused",1) - qutest.dispatch("PAUSE_SIG") - qutest.expect("%timestamp Disp===> Obj=AO_Table,Sig=PAUSE_SIG,State=Table_serving") + qutest = qutest_noreset # name change + qutest.probe('BSP_displayPaused', 1) + qutest.dispatch('PAUSE_SIG') + qutest.expect( + "%timestamp Disp===> Obj=AO_Table,Sig=PAUSE_SIG,State=Table_serving") qutest.expect("%timestamp TstProbe Fun=BSP_displayPaused,Data=1") qutest.expect("%timestamp =ASSERT= Mod=bsp,Loc=100") +# end... if __name__ == "__main__": options = ['-x', '-v', '--tb=short'] options.extend(sys.argv) diff --git a/examples/qutest/dpp/test_table/test_table.tcl b/examples/qutest/dpp/test_table/test_table.tcl new file mode 100644 index 00000000..8afae526 --- /dev/null +++ b/examples/qutest/dpp/test_table/test_table.tcl @@ -0,0 +1,83 @@ +# test-script for QUTest unit testing harness +# see https://www.state-machine.com/qtools/qutest.html + +# preamble... +proc on_reset {} { + expect_pause + continue + glb_filter ON + loc_filter SM_AO AO_Table + current_obj SM_AO AO_Table +} + +# tests... +test "post HUNGRY" +post HUNGRY_SIG [binary format c 2] +expect "%timestamp QF-New Sig=HUNGRY_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp AO-Post Sdr=QS_RX,Obj=AO_Table,Evt Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving" +expect "%timestamp BSP_CALL BSP_displayPhilStat 2 hungry " +expect "%timestamp QF-New Sig=EAT_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-Pub Sdr=AO_Table,Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gc Evt" +expect "%timestamp MP-Put Obj=EvtPool1,*" +expect "%timestamp BSP_CALL BSP_displayPhilStat 2 eating " +expect "%timestamp =>Intern Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving" +expect "%timestamp QF-gc Evt Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving" +expect "%timestamp BSP_CALL BSP_displayPhilStat 1 hungry " +expect "%timestamp =>Intern Obj=AO_Table,Sig=HUNGRY_SIG,State=Table_serving" +expect "%timestamp QF-gc Evt" +expect "%timestamp Trg-Done QS_RX_EVENT" +expect "%timestamp AO-GetL Obj=AO_Table,Evt Obj=AO_Table,Sig=DONE_SIG,State=Table_serving" +expect "%timestamp BSP_CALL BSP_displayPhilStat 2 thinking" +expect "%timestamp QF-New Sig=EAT_SIG,*" +expect "%timestamp MP-Get Obj=EvtPool1,*" +expect "%timestamp QF-Pub Sdr=AO_Table,Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gcA Evt" +expect "%timestamp QF-gc Evt" +expect "%timestamp MP-Put Obj=EvtPool1,*" +expect "%timestamp BSP_CALL BSP_displayPhilStat 1 eating " +expect "%timestamp =>Intern Obj=AO_Table,Sig=DONE_SIG,State=Table_serving" +expect "%timestamp QF-gc Evt. -# -# Contact information: -# https://www.state-machine.com -# mailto:info@state-machine.com -############################################################################## -# -# examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak SCRIPT=py # make and run the Python tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name, binary output directory -# -PROJECT := evt_par -TARGET := ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest - -# list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(QPC)/3rd_party/ek-tm4c123gxl \ - $(QPC)/3rd_party/ek-tm4c123gxl/gnu - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - my_ao.c \ - test_evt_par.c \ - system_TM4C123GH6PM.c \ - startup_TM4C123GH6PM.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DTARGET_IS_TM4C123_RB1 - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!) -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_ARCH := 7 # NOTE: must match the ARM_CPU! -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see http://gnutoolchains.com/arm-eabi/ -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-eabi-g++ -AS := $(GNU_ARM)/bin/arm-eabi-as -LINK := $(GNU_ARM)/bin/arm-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The following symbol LMFLASH assumes that LMFlash.exe can -# be found on the PATH. You might need to adjust this symbol to the -# location of the LMFlash utility on your machine -# -ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe -endif - - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := $(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) \ - -mthumb -nostdlib \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) - -ifeq ($(SCRIPT),py) -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -.PHONY : clean show - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QUTEST = $(QUTEST) - @echo HOST = $(HOST) - diff --git a/examples/qutest/evt_par/my_ao.c b/examples/qutest/evt_par/src/my_ao.c similarity index 98% rename from examples/qutest/evt_par/my_ao.c rename to examples/qutest/evt_par/src/my_ao.c index 7416b23d..fadb82bb 100644 --- a/examples/qutest/evt_par/my_ao.c +++ b/examples/qutest/evt_par/src/my_ao.c @@ -1,7 +1,7 @@ #include "qpc.h" #include "my_app.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* MyAO declaration --------------------------------------------------------*/ typedef struct { diff --git a/examples/qutest/evt_par/my_app.h b/examples/qutest/evt_par/src/my_app.h similarity index 100% rename from examples/qutest/evt_par/my_app.h rename to examples/qutest/evt_par/src/my_app.h diff --git a/examples/qutest/evt_par/test_evt_par.c b/examples/qutest/evt_par/test_evt_par.c deleted file mode 100644 index 0a266cd9..00000000 --- a/examples/qutest/evt_par/test_evt_par.c +++ /dev/null @@ -1,142 +0,0 @@ -/***************************************************************************** -* Purpose: example event QUTEST fixture -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" /* QUTest interface */ -#include "my_app.h" /* My Application */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(MyEvt3) smlPoolSto[10]; - static QEvt const *myAoQueueSto[10]; - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(AO_MyAO); - QS_TEST_PAUSE(); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start active objects... */ - MyAO_ctor(); /* instantiate the MyAO active object */ - QACTIVE_START(AO_MyAO, /* AO to start */ - (uint_fast8_t)1, /* QP priority of the AO */ - myAoQueueSto, /* event queue storage */ - Q_DIM(myAoQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - -/*--------------------------------------------------------------------------*/ -enum AppSpecRecords { - MY_EVT0 = QS_USER, - MY_EVT1, - MY_EVT2, - MY_EVT3 -}; - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { - QS_USR_DICTIONARY(MY_EVT0); - QS_USR_DICTIONARY(MY_EVT1); - QS_USR_DICTIONARY(MY_EVT2); - QS_USR_DICTIONARY(MY_EVT3); -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { -} - -/*..........................................................................*/ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)param1; /* unused parameter */ - (void)param2; /* unused parameter */ - (void)param3; /* unused parameter */ - - switch (cmdId) { - case 0: { - break; - } - default: - break; - } -} -/*..........................................................................*/ -/*! callback function to "massage" the injected QP events (not used here) */ -void QS_onTestEvt(QEvt *e) { - - switch (e->sig) { - case MY_EVT0_SIG: - QS_BEGIN(MY_EVT0, (void *)0) /* user-specific record */ - QS_END() - break; - case MY_EVT1_SIG: - QS_BEGIN(MY_EVT1, (void *)0) /* user-specific record */ - QS_U32(0, Q_EVT_CAST(MyEvt1)->u32); - QS_END() - break; - case MY_EVT2_SIG: - QS_BEGIN(MY_EVT2, (void *)0) /* user-specific record */ - QS_U32(0, Q_EVT_CAST(MyEvt2)->u32); - QS_U32(0, Q_EVT_CAST(MyEvt2)->u16); - QS_END() - break; - case MY_EVT3_SIG: - QS_BEGIN(MY_EVT3, (void *)0) /* user-specific record */ - QS_U32(0, Q_EVT_CAST(MyEvt3)->u32); - QS_U32(0, Q_EVT_CAST(MyEvt3)->u16); - QS_U32(0, Q_EVT_CAST(MyEvt3)->u8); - QS_END() - break; - } - -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ - -} diff --git a/examples/qutest/evt_par/test_evt_par.py b/examples/qutest/evt_par/test_evt_par.py deleted file mode 100644 index 15d5a4dd..00000000 --- a/examples/qutest/evt_par/test_evt_par.py +++ /dev/null @@ -1,42 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.expect_pause() - qutest.glb_filter(FILTER.UA) - qutest.current_obj(QS_OBJ_KIND.SM_AO,"AO_MyAO") - qutest.Continue() - - -def test_EVT0(qutest): - qutest.dispatch("MY_EVT0_SIG") - qutest.expect("%timestamp MY_EVT0") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_EVT1(qutest): - qutest.dispatch("MY_EVT1_SIG",struct.pack('. -# -# Contact information: -# https://www.state-machine.com -# mailto:info@state-machine.com -############################################################################## -# -# examples of invoking this Makefile: -# make # make and run the tests in the current directory -# make TESTS=test*.tcl # make and run the selected tests in the curr. dir. -# make SCRIPT=py # make and run the Python tests -# make HOST=localhost:7705 # connect to host:port -# make norun # only make but not run the tests -# make clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_qhsm - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - -# list of all source directories used by this project -VPATH = \ - . - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - qhsmtst.c \ - test_qhsm.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -ifeq ($(SCRIPT),py) -run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - @echo HOST = $(HOST) - diff --git a/examples/qutest/qhsmtst/conftest.py b/examples/qutest/qhsmtst/conftest.py deleted file mode 100644 index 48253da6..00000000 --- a/examples/qutest/qhsmtst/conftest.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# pytest configuration file for QUTest/Py unit testing harness, see: -# https://www.state-machine.com/qtools/qutest.html -# - -# Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset diff --git a/examples/qutest/qhsmtst/efm32-slstk3401a.mak b/examples/qutest/qhsmtst/efm32-slstk3401a.mak deleted file mode 100644 index 8900fcf7..00000000 --- a/examples/qutest/qhsmtst/efm32-slstk3401a.mak +++ /dev/null @@ -1,333 +0,0 @@ -############################################################################## -# Product: Makefile for EMF32-SLSTK3401A, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -fefm32-slstk3401a.mak # make and run the tests in the current directory -# make -fefm32-slstk3401a.mak TESTS=philo*.tcl # make and run the selected tests -# make -fefm32-slstk3401a.mak SCRIPT=py # make and run the Python tests -# make -fefm32-slstk3401a.mak HOST=localhost:7705 # connect to host:port -# make -fefm32-slstk3401a.mak norun # only make but not run the tests -# make -fefm32-slstk3401a.mak clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name, binary output directory -# -PROJECT := test_qhsm -TARGET := efm32-slstk3401a - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest - -# list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b - -#----------------------------------------------------------------------------- -# files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - qhsmtst.c \ - test_qhsm.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c \ - em_usart.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DEFM32PG1B200F256GM48=1 - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!) -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_ARCH := 7 # NOTE: must match the ARM_CPU! -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see http://gnutoolchains.com/arm-eabi/ -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-eabi-g++ -AS := $(GNU_ARM)/bin/arm-eabi-as -LINK := $(GNU_ARM)/bin/arm-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-eabi-objcopy - -#----------------------------------------------------------------------------- -# FLASH tool (NOTE: Requires the JLINK utility) -# see ../efm32-slstk3401a/flash.bat -# - -FLASH := ..\efm32-slstk3401a\flash.bat - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := $(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) \ - -mthumb -nostdlib \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(FLASH) $(TARGET_BIN) - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(FLASH) $(TARGET_BIN) - -ifeq ($(SCRIPT),py) -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -.PHONY : clean show - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QUTEST = $(QUTEST) - @echo HOST = $(HOST) - diff --git a/examples/qutest/qhsmtst/ek-tm4c123gxl.mak b/examples/qutest/qhsmtst/ek-tm4c123gxl.mak deleted file mode 100644 index 9699e1af..00000000 --- a/examples/qutest/qhsmtst/ek-tm4c123gxl.mak +++ /dev/null @@ -1,332 +0,0 @@ -############################################################################## -# Product: Makefile for EK-TM4C123GXL, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak SCRIPT=py # make and run the Python tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name, binary output directory -# -PROJECT := test_qhsm -TARGET := ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest - -# list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) \ - $(QPC)/3rd_party/ek-tm4c123gxl \ - $(QPC)/3rd_party/ek-tm4c123gxl/gnu - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) \ - -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/ek-tm4c123gxl - -#----------------------------------------------------------------------------- -# files -# - -# assembler source files -ASM_SRCS := - -# C source files -C_SRCS := \ - qhsmtst.c \ - test_qhsm.c \ - system_TM4C123GH6PM.c \ - startup_TM4C123GH6PM.c - -# C++ source files -CPP_SRCS := - -OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -QP_ASMS := - -LIB_DIRS := -LIBS := - -# defines -DEFINES := -DTARGET_IS_TM4C123_RB1 - -# ARM CPU, ARCH, FPU, and Float-ABI types... -# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] -# ARM_ARCH: [6 | 7] (NOTE: must match ARM_CPU!) -# ARM_FPU: [ | vfp] -# FLOAT_ABI: [ | soft | softfp | hard] -# -ARM_CPU := -mcpu=cortex-m4 -ARM_ARCH := 7 # NOTE: must match the ARM_CPU! -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp - -#----------------------------------------------------------------------------- -# GNU-ARM toolset (NOTE: You need to adjust to your machine) -# see http://gnutoolchains.com/arm-eabi/ -# -ifeq ($(GNU_ARM),) -GNU_ARM := $(QTOOLS)/gnu_arm-eabi -endif - -# make sure that the GNU-ARM toolset exists... -ifeq ("$(wildcard $(GNU_ARM))","") -$(error GNU_ARM toolset not found. Please adjust the Makefile) -endif - -CC := $(GNU_ARM)/bin/arm-eabi-gcc -CPP := $(GNU_ARM)/bin/arm-eabi-g++ -AS := $(GNU_ARM)/bin/arm-eabi-as -LINK := $(GNU_ARM)/bin/arm-eabi-gcc -BIN := $(GNU_ARM)/bin/arm-eabi-objcopy - -#----------------------------------------------------------------------------- -# NOTE: The following symbol LMFLASH assumes that LMFlash.exe can -# be found on the PATH. You might need to adjust this symbol to the -# location of the LMFlash utility on your machine -# -ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe -endif - - -############################################################################## -# Typically you should not need to change anything below this line - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) -ASM_SRCS += $(QP_ASMS) - -BIN_DIR := $(TARGET) - -ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) - -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST - - -LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) \ - -mthumb -nostdlib \ - -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - -ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) -C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) -CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) - -TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin -TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf -ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun flash - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_BIN) -norun : all -else -all : $(TARGET_BIN) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_BIN) : $(TARGET_ELF) - $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ - -$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) - -ifeq ($(SCRIPT),py) -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.s - $(AS) $(ASFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -.PHONY : clean show - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.bin \ - $(BIN_DIR)/*.elf \ - $(BIN_DIR)/*.map - -show : - @echo PROJECT = $(PROJECT) - @echo TESTS = $(TESTS) - @echo TARGET_ELF = $(TARGET_ELF) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo ASM_SRCS = $(ASM_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - - @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QUTEST = $(QUTEST) - @echo HOST = $(HOST) - diff --git a/examples/qutest/qhsmtst/qhsmtst.c b/examples/qutest/qhsmtst/src/qhsmtst.c similarity index 100% rename from examples/qutest/qhsmtst/qhsmtst.c rename to examples/qutest/qhsmtst/src/qhsmtst.c diff --git a/examples/qutest/qhsmtst/qhsmtst.h b/examples/qutest/qhsmtst/src/qhsmtst.h similarity index 100% rename from examples/qutest/qhsmtst/qhsmtst.h rename to examples/qutest/qhsmtst/src/qhsmtst.h diff --git a/examples/qutest/qhsmtst/qhsmtst.qm b/examples/qutest/qhsmtst/src/qhsmtst.qm similarity index 100% rename from examples/qutest/qhsmtst/qhsmtst.qm rename to examples/qutest/qhsmtst/src/qhsmtst.qm diff --git a/examples/qutest/qhsmtst/test_qhsm-funct.py b/examples/qutest/qhsmtst/test_qhsm-funct.py deleted file mode 100644 index 359fc97b..00000000 --- a/examples/qutest/qhsmtst/test_qhsm-funct.py +++ /dev/null @@ -1,201 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.glb_filter(FILTER.UA) - qutest.current_obj(QS_OBJ_KIND.SM,"the_hsm") - - -def test_QHsmTst_init(qutest): - qutest.init() - qutest.expect("%timestamp BSP_DISPLAY top-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_QHsmTst_dispatch(qutest_noreset): - qutest = qutest_noreset # name change - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp BSP_DISPLAY s21-A;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s21-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp BSP_DISPLAY s21-B;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp BSP_DISPLAY s211-D;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp BSP_DISPLAY s-E;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-I;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-F;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp BSP_DISPLAY s2-I;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp BSP_DISPLAY s-I;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp BSP_DISPLAY s2-F;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-A;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-B;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-D;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp BSP_DISPLAY s11-D;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp BSP_DISPLAY s-E;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp BSP_DISPLAY s11-G;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp BSP_DISPLAY s211-H;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp BSP_DISPLAY s11-H;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-C;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp BSP_DISPLAY s21-G;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-C;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp BSP_DISPLAY s2-C;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/qhsmtst/test_qhsm-funct.tcl b/examples/qutest/qhsmtst/test_qhsm-funct.tcl deleted file mode 100644 index 575659d1..00000000 --- a/examples/qutest/qhsmtst/test_qhsm-funct.tcl +++ /dev/null @@ -1,194 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - glb_filter UA - current_obj SM the_hsm -} - -# tests... -test "QHsmTst init" -init -expect "%timestamp BSP_DISPLAY top-INIT;" -expect "%timestamp BSP_DISPLAY s-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-INIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -#------------------ -test "QHsmTst dispatch" -noreset - -dispatch A_SIG -expect "%timestamp BSP_DISPLAY s21-A;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s21-INIT;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp BSP_DISPLAY s21-B;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp BSP_DISPLAY s211-D;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-INIT;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp BSP_DISPLAY s-E;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp BSP_DISPLAY s1-I;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp BSP_DISPLAY s1-F;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp BSP_DISPLAY s2-I;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp BSP_DISPLAY s-I;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp BSP_DISPLAY s2-F;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch A_SIG -expect "%timestamp BSP_DISPLAY s1-A;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp BSP_DISPLAY s1-B;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp BSP_DISPLAY s1-D;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s-INIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp BSP_DISPLAY s11-D;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp BSP_DISPLAY s-E;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp BSP_DISPLAY s11-G;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp BSP_DISPLAY s211-H;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s-INIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp BSP_DISPLAY s11-H;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s-INIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp BSP_DISPLAY s1-C;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-INIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp BSP_DISPLAY s21-G;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp BSP_DISPLAY s1-C;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-INIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp BSP_DISPLAY s2-C;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -# the end -end - diff --git a/examples/qutest/qhsmtst/test_qhsm-struct.py b/examples/qutest/qhsmtst/test_qhsm-struct.py deleted file mode 100644 index 6edb3424..00000000 --- a/examples/qutest/qhsmtst/test_qhsm-struct.py +++ /dev/null @@ -1,225 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.glb_filter(FILTER.SM) - qutest.current_obj(QS_OBJ_KIND.SM,"the_hsm") - - -def test_QHsmTst_init(qutest): - qutest.init() - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsm_top->QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp Init===> Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_QHsmTst_dispatch(qutest_noreset): - qutest = qutest_noreset # name change - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s21->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s21->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s211->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s11") - qutest.expect("%timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s1") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s1->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s211") - qutest.expect("%timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s2") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Unhnd Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s2") - qutest.expect("%timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s2->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Unhnd Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s11->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s211->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s11->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s21->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s2->QHsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/qhsmtst/test_qhsm-struct.tcl b/examples/qutest/qhsmtst/test_qhsm-struct.tcl deleted file mode 100644 index ee829142..00000000 --- a/examples/qutest/qhsmtst/test_qhsm-struct.tcl +++ /dev/null @@ -1,218 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - glb_filter SM - current_obj SM the_hsm -} - -# tests... -test "QHsmTst init" -init -expect "===RTC===> St-Init Obj=the_hsm,State=QHsm_top->QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp Init===> Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -#------------------ -test "QHsmTst dispatch" -noreset - -dispatch A_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s21->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s21->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s211->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s11" -expect "%timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s1" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s1->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s211" -expect "%timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s2" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Unhnd Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s2" -expect "%timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s2->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch A_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s1->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s1->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Unhnd Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s1->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s11->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s211->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s11->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s21->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21" -expect "===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1" -expect "===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11" -expect "===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11" -expect "%timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s2->QHsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -# the end -end - diff --git a/examples/qutest/qmsmtst/Makefile b/examples/qutest/qmsmtst/Makefile deleted file mode 100644 index 0e95fe97..00000000 --- a/examples/qutest/qmsmtst/Makefile +++ /dev/null @@ -1,246 +0,0 @@ -############################################################################## -# Product: Makefile for QUTEST; QP/C on Win32 host -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make # make and run the tests in the current directory -# make TESTS=test*.tcl # make and run the selected tests in the curr. dir. -# make SCRIPT=py # make and run the Python tests -# make HOST=localhost:7705 # connect to host:port -# make norun # only make but not run the tests -# make clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_qmsm - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - -# list of all source directories used by this project -VPATH = \ - . - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - qmsmtst.c \ - test_qmsm.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -ifeq ($(SCRIPT),py) -run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - @echo HOST = $(HOST) - diff --git a/examples/qutest/qmsmtst/conftest.py b/examples/qutest/qmsmtst/conftest.py deleted file mode 100644 index 48253da6..00000000 --- a/examples/qutest/qmsmtst/conftest.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# pytest configuration file for QUTest/Py unit testing harness, see: -# https://www.state-machine.com/qtools/qutest.html -# - -# Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset diff --git a/examples/qutest/qmsmtst/qmsmtst.c b/examples/qutest/qmsmtst/src/qmsmtst.c similarity index 100% rename from examples/qutest/qmsmtst/qmsmtst.c rename to examples/qutest/qmsmtst/src/qmsmtst.c diff --git a/examples/qutest/qmsmtst/qmsmtst.h b/examples/qutest/qmsmtst/src/qmsmtst.h similarity index 100% rename from examples/qutest/qmsmtst/qmsmtst.h rename to examples/qutest/qmsmtst/src/qmsmtst.h diff --git a/examples/qutest/qmsmtst/qmsmtst.qm b/examples/qutest/qmsmtst/src/qmsmtst.qm similarity index 100% rename from examples/qutest/qmsmtst/qmsmtst.qm rename to examples/qutest/qmsmtst/src/qmsmtst.qm diff --git a/examples/qutest/qmsmtst/test_qmsm-funct.py b/examples/qutest/qmsmtst/test_qmsm-funct.py deleted file mode 100644 index d8b3f80f..00000000 --- a/examples/qutest/qmsmtst/test_qmsm-funct.py +++ /dev/null @@ -1,201 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.glb_filter(FILTER.UA) - qutest.current_obj(QS_OBJ_KIND.SM,"the_msm") - - -def test_QMsmTst_init(qutest): - qutest.init() - qutest.expect("%timestamp BSP_DISPLAY top-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_QMsmTst_dispatch(qutest_noreset): - qutest = qutest_noreset # name change - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp BSP_DISPLAY s21-A;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s21-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp BSP_DISPLAY s21-B;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp BSP_DISPLAY s211-D;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp BSP_DISPLAY s-E;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-I;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-F;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp BSP_DISPLAY s2-I;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp BSP_DISPLAY s-I;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp BSP_DISPLAY s2-F;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-A;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-B;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-D;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp BSP_DISPLAY s11-D;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp BSP_DISPLAY s-E;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp BSP_DISPLAY s11-G;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp BSP_DISPLAY s211-H;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp BSP_DISPLAY s11-H;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-C;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp BSP_DISPLAY s21-G;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp BSP_DISPLAY s1-C;") - qutest.expect("%timestamp BSP_DISPLAY s11-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s2-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s211-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp BSP_DISPLAY s2-C;") - qutest.expect("%timestamp BSP_DISPLAY s211-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s21-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s2-EXIT;") - qutest.expect("%timestamp BSP_DISPLAY s1-ENTRY;") - qutest.expect("%timestamp BSP_DISPLAY s1-INIT;") - qutest.expect("%timestamp BSP_DISPLAY s11-ENTRY;") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/qmsmtst/test_qmsm-funct.tcl b/examples/qutest/qmsmtst/test_qmsm-funct.tcl deleted file mode 100644 index 346cb836..00000000 --- a/examples/qutest/qmsmtst/test_qmsm-funct.tcl +++ /dev/null @@ -1,194 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - glb_filter UA - current_obj SM the_msm -} - -# tests... -test "QMsmTst init" -init -expect "%timestamp BSP_DISPLAY top-INIT;" -expect "%timestamp BSP_DISPLAY s-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-INIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -#------------------ -test "QMsmTst dispatch" -noreset - -dispatch A_SIG -expect "%timestamp BSP_DISPLAY s21-A;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s21-INIT;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp BSP_DISPLAY s21-B;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp BSP_DISPLAY s211-D;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-INIT;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp BSP_DISPLAY s-E;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp BSP_DISPLAY s1-I;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp BSP_DISPLAY s1-F;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp BSP_DISPLAY s2-I;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp BSP_DISPLAY s-I;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp BSP_DISPLAY s2-F;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch A_SIG -expect "%timestamp BSP_DISPLAY s1-A;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp BSP_DISPLAY s1-B;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp BSP_DISPLAY s1-D;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s-INIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp BSP_DISPLAY s11-D;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp BSP_DISPLAY s-E;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp BSP_DISPLAY s11-G;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp BSP_DISPLAY s211-H;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s-INIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp BSP_DISPLAY s11-H;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s-INIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp BSP_DISPLAY s1-C;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-INIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp BSP_DISPLAY s21-G;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp BSP_DISPLAY s1-C;" -expect "%timestamp BSP_DISPLAY s11-EXIT;" -expect "%timestamp BSP_DISPLAY s1-EXIT;" -expect "%timestamp BSP_DISPLAY s2-ENTRY;" -expect "%timestamp BSP_DISPLAY s2-INIT;" -expect "%timestamp BSP_DISPLAY s21-ENTRY;" -expect "%timestamp BSP_DISPLAY s211-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp BSP_DISPLAY s2-C;" -expect "%timestamp BSP_DISPLAY s211-EXIT;" -expect "%timestamp BSP_DISPLAY s21-EXIT;" -expect "%timestamp BSP_DISPLAY s2-EXIT;" -expect "%timestamp BSP_DISPLAY s1-ENTRY;" -expect "%timestamp BSP_DISPLAY s1-INIT;" -expect "%timestamp BSP_DISPLAY s11-ENTRY;" -expect "%timestamp Trg-Done QS_RX_EVENT" - -# the end -end - diff --git a/examples/qutest/qmsmtst/test_qmsm-struct.py b/examples/qutest/qmsmtst/test_qmsm-struct.py deleted file mode 100644 index 17cfd831..00000000 --- a/examples/qutest/qmsmtst/test_qmsm-struct.py +++ /dev/null @@ -1,225 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_reset(qutest): - qutest.glb_filter(FILTER.SM) - qutest.current_obj(QS_OBJ_KIND.SM,"the_msm") - - -def test_QMsmTst_init(qutest): - qutest.init() - qutest.expect("===RTC===> St-Init Obj=the_msm,State=NULL->QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp Init===> Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - -def test_QMsmTst_dispatch(qutest_noreset): - qutest = qutest_noreset # name change - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=A_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s21->QMsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=A_SIG,State=QMsmTst_s21->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=B_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=B_SIG,State=QMsmTst_s21->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s21->QMsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s211->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=E_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s11") - qutest.expect("%timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s1") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=F_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=F_SIG,State=QMsmTst_s1->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s211") - qutest.expect("%timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s2") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("I_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Unhnd Obj=the_msm,Sig=I_SIG,State=QMsmTst_s2") - qutest.expect("%timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("F_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=F_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=F_SIG,State=QMsmTst_s2->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("A_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=A_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=A_SIG,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("B_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=B_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=B_SIG,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Unhnd Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("D_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("E_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=E_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=G_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=G_SIG,State=QMsmTst_s11->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=H_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=H_SIG,State=QMsmTst_s211->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("H_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=H_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=H_SIG,State=QMsmTst_s11->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("G_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=G_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=G_SIG,State=QMsmTst_s21->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - qutest.dispatch("C_SIG") - qutest.expect("%timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") - qutest.expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") - qutest.expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") - qutest.expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") - qutest.expect("%timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s2->QMsmTst_s11") - qutest.expect("%timestamp Trg-Done QS_RX_EVENT") - - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/qmsmtst/test_qmsm-struct.tcl b/examples/qutest/qmsmtst/test_qmsm-struct.tcl deleted file mode 100644 index 5347fa71..00000000 --- a/examples/qutest/qmsmtst/test_qmsm-struct.tcl +++ /dev/null @@ -1,218 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_reset {} { - glb_filter SM - current_obj SM the_msm -} - -# tests... -test "QMsmTst init" -init -expect "===RTC===> St-Init Obj=the_msm,State=NULL->QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp Init===> Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -#------------------ -test "QMsmTst dispatch" -noreset - -dispatch A_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=A_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s21->QMsmTst_s211" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=A_SIG,State=QMsmTst_s21->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=B_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=B_SIG,State=QMsmTst_s21->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s21->QMsmTst_s211" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s211->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=E_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s11" -expect "%timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s1" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=F_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=F_SIG,State=QMsmTst_s1->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s211" -expect "%timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s2" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch I_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Unhnd Obj=the_msm,Sig=I_SIG,State=QMsmTst_s2" -expect "%timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch F_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=F_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=F_SIG,State=QMsmTst_s2->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch A_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=A_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=A_SIG,State=QMsmTst_s1->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch B_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=B_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=B_SIG,State=QMsmTst_s1->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Unhnd Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s1->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch D_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch E_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=E_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=G_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=G_SIG,State=QMsmTst_s11->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=H_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=H_SIG,State=QMsmTst_s211->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch H_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=H_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=H_SIG,State=QMsmTst_s11->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch G_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=G_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=G_SIG,State=QMsmTst_s21->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211" -expect "%timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211" -expect "%timestamp Trg-Done QS_RX_EVENT" - -dispatch C_SIG -expect "%timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21" -expect "===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1" -expect "===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11" -expect "===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11" -expect "%timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s2->QMsmTst_s11" -expect "%timestamp Trg-Done QS_RX_EVENT" - -# the end -end - diff --git a/examples/qutest/self_test/conftest.py b/examples/qutest/self_test/conftest.py deleted file mode 100644 index 48253da6..00000000 --- a/examples/qutest/self_test/conftest.py +++ /dev/null @@ -1,7 +0,0 @@ -# -# pytest configuration file for QUTest/Py unit testing harness, see: -# https://www.state-machine.com/qtools/qutest.html -# - -# Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset diff --git a/examples/qutest/self_test/posix.mak b/examples/qutest/self_test/posix.mak deleted file mode 100644 index cec8e40c..00000000 --- a/examples/qutest/self_test/posix.mak +++ /dev/null @@ -1,240 +0,0 @@ -############################################################################## -# Product: Makefile for QUTEST; QP/C on POSIX *Target* -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -f posix.mak # make and run the tests in the current directory -# make -f posix.mak HOST=192.168.1.65:6601 # make and run the executable -# make -f posix.mak norun # only make but not run the tests -# make -f posix.mak clean # cleanup the build -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_qutest - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix-qutest - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - test_qutest.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities - -MKDIR := mkdir -p -RM := rm -f - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -BIN_DIR := posix - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : clean show test run norun - -ifeq ($(MAKECMDGOALS),norun) - -all : $(TARGET_EXE) -norun : all - -else ifeq ($(MAKECMDGOALS),test) - -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -else - -all : $(TARGET_EXE) run - -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -# run the test fixture on a POSIX target in a loop, so that it is re-started -# after every test. The loop is terminated by pressing Ctrl-C on the keyboard. -# -run : $(TARGET_EXE) - set -e; while true; do \ - echo "restarting $(TARGET_EXE)"; \ - $(TARGET_EXE) "" $(HOST); \ - done - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),test) - ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo HOST = $(HOST) diff --git a/examples/qutest/self_test/posix_host.mak b/examples/qutest/self_test/posix_host.mak deleted file mode 100644 index 3b575035..00000000 --- a/examples/qutest/self_test/posix_host.mak +++ /dev/null @@ -1,256 +0,0 @@ -############################################################################## -# Product: Makefile for QUTEST; QP/C on POSIX *Host* -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# make -f posix_host.mak # make and run the tests in the current directory -# make -f posix_host.mak TESTS=philo*.tcl # make and run the selected tests -# make -f posix_host.mak SCRIPT=py # make and run the Python tests -# make -f posix_host.mak HOST=localhost:7705 # connect to host:port -# make -f posix_host.mak norun # only make but not run the tests -# make -f posix_host.mak clean # cleanup the build -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := test_qutest - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix-qutest - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - test_qutest.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qutest.c \ - qutest_port.c - -LIB_DIRS := -LIBS := - -# defines... -DEFINES := - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -# basic utilities - -MKDIR := mkdir -p -RM := rm -f - -ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest -else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -#----------------------------------------------------------------------------- -# build options -# - -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -BIN_DIR := posix_host - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY : run norun - -ifeq ($(MAKECMDGOALS),norun) -all : $(TARGET_EXE) -norun : all -else -all : $(TARGET_EXE) run -endif - -ifeq (, $(TESTS)) -ifeq ($(SCRIPT),py) -TESTS := *.py -else -TESTS := *.tcl -endif -endif - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -ifeq ($(SCRIPT),py) -run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - @echo QTOOLS = $(QTOOLS) - @echo QUTEST = $(QUTEST) - @echo TESTS = $(TESTS) - @echo HOST = $(HOST) - diff --git a/examples/qutest/self_test/test_command.py b/examples/qutest/self_test/test_command.py deleted file mode 100644 index 4006952a..00000000 --- a/examples/qutest/self_test/test_command.py +++ /dev/null @@ -1,28 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_setup(qutest): - qutest.expect("%timestamp ON_TEST_SETUP") - -def on_teardown(qutest): - qutest.expect("%timestamp ON_TEST_TEARDOWN") - - - -def test_Command(qutest): - qutest.command("COMMAND_X",1,2,3) - qutest.expect("%timestamp COMMAND_X 0") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) - diff --git a/examples/qutest/self_test/test_command.tcl b/examples/qutest/self_test/test_command.tcl deleted file mode 100644 index 3e6de3f6..00000000 --- a/examples/qutest/self_test/test_command.tcl +++ /dev/null @@ -1,21 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_setup {} { - expect "%timestamp ON_TEST_SETUP" -} -proc on_teardown {} { - expect "%timestamp ON_TEST_TEARDOWN" -} - -# tests... - -#---------- -test "Command" -command COMMAND_X 1 2 3 -expect "%timestamp COMMAND_X 0" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -# the end -end diff --git a/examples/qutest/self_test/test_peek-poke.py b/examples/qutest/self_test/test_peek-poke.py deleted file mode 100644 index 40c0ab98..00000000 --- a/examples/qutest/self_test/test_peek-poke.py +++ /dev/null @@ -1,73 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_setup(qutest): - qutest.expect("%timestamp ON_TEST_SETUP") - -def on_teardown(qutest): - qutest.expect("%timestamp ON_TEST_TEARDOWN") - - - -def test_Peek_Poke_Fill_uint8_t(qutest): - qutest.current_obj(QS_OBJ_KIND.AP,"buffer") - qutest.fill(0,1,100,0x1A) - qutest.peek(0,1,5) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=1,Num=5,Data=<1A,1A,1A,1A,1A>") - qutest.peek(95,1,5) - qutest.expect("%timestamp Trg-Peek Offs=95,Size=1,Num=5,Data=<1A,1A,1A,1A,1A>") - qutest.fill(2,1,95,0x1B) - qutest.peek(0,1,5) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=1,Num=5,Data=<1A,1A,1B,1B,1B>") - qutest.peek(95,1,5) - qutest.expect("%timestamp Trg-Peek Offs=95,Size=1,Num=5,Data=<1B,1B,1A,1A,1A>") - qutest.fill(0,1,100,0xA1) - qutest.poke(2,1,struct.pack('") - -def test_Peek_Poke_Fill_uint16_t(qutest_noreset): - qutest = qutest_noreset # name change - qutest.fill(0,2,50,0x2A2B) - qutest.peek(0,2,3) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=2,Num=3,Data=<2A2B,2A2B,2A2B>") - qutest.peek(94,2,3) - qutest.expect("%timestamp Trg-Peek Offs=94,Size=2,Num=3,Data=<2A2B,2A2B,2A2B>") - qutest.fill(2,2,48,0x2C2D) - qutest.peek(0,2,3) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=2,Num=3,Data=<2A2B,2C2D,2C2D>") - qutest.peek(94,2,3) - qutest.expect("%timestamp Trg-Peek Offs=94,Size=2,Num=3,Data=<2C2D,2C2D,2A2B>") - qutest.fill(0,2,50,0xA2B2) - qutest.poke(2,2,struct.pack('") - -def test_Peek_Poke_Fill_uint32_t(qutest_noreset): - qutest = qutest_noreset # name change - qutest.fill(0,4,25,0x4A4B4C4D) - qutest.peek(0,4,3) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=4,Num=3,Data=<4A4B4C4D,4A4B4C4D,4A4B4C4D>") - qutest.peek(88,4,3) - qutest.expect("%timestamp Trg-Peek Offs=88,Size=4,Num=3,Data=<4A4B4C4D,4A4B4C4D,4A4B4C4D>") - qutest.fill(4,4,23,0x4C4D4E4F) - qutest.peek(0,4,3) - qutest.expect("%timestamp Trg-Peek Offs=0,Size=4,Num=3,Data=<4A4B4C4D,4C4D4E4F,4C4D4E4F>") - qutest.peek(88,4,3) - qutest.expect("%timestamp Trg-Peek Offs=88,Size=4,Num=3,Data=<4C4D4E4F,4C4D4E4F,4A4B4C4D>") - qutest.fill(0,4,25,0xA4B4C4D4) - qutest.poke(4,4,struct.pack('") - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/self_test/test_peek-poke.tcl b/examples/qutest/self_test/test_peek-poke.tcl deleted file mode 100644 index e1ee9e3a..00000000 --- a/examples/qutest/self_test/test_peek-poke.tcl +++ /dev/null @@ -1,69 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_setup {} { - expect "%timestamp ON_TEST_SETUP" -} -proc on_teardown {} { - expect "%timestamp ON_TEST_TEARDOWN" -} - -# tests... - -#---------- -test "Peek/Poke/Fill uint8_t" -current_obj AP buffer -fill 0 1 100 0x1A -peek 0 1 5 -expect "%timestamp Trg-Peek Offs=0,Size=1,Num=5,Data=<1A,1A,1A,1A,1A>" -peek 95 1 5 -expect "%timestamp Trg-Peek Offs=95,Size=1,Num=5,Data=<1A,1A,1A,1A,1A>" -fill 2 1 95 0x1B -peek 0 1 5 -expect "%timestamp Trg-Peek Offs=0,Size=1,Num=5,Data=<1A,1A,1B,1B,1B>" -peek 95 1 5 -expect "%timestamp Trg-Peek Offs=95,Size=1,Num=5,Data=<1B,1B,1A,1A,1A>" -fill 0 1 100 0xA1 -poke 2 1 [binary format cccc 0xB1 0xC1 0xD1 0xE1] -peek 0 1 7 -expect "%timestamp Trg-Peek Offs=0,Size=1,Num=7,Data=" - -#---------- -test "Peek/Poke/Fill uint16_t" -noreset -fill 0 2 50 0x2A2B -peek 0 2 3 -expect "%timestamp Trg-Peek Offs=0,Size=2,Num=3,Data=<2A2B,2A2B,2A2B>" -peek 94 2 3 -expect "%timestamp Trg-Peek Offs=94,Size=2,Num=3,Data=<2A2B,2A2B,2A2B>" -fill 2 2 48 0x2C2D -peek 0 2 3 -expect "%timestamp Trg-Peek Offs=0,Size=2,Num=3,Data=<2A2B,2C2D,2C2D>" -peek 94 2 3 -expect "%timestamp Trg-Peek Offs=94,Size=2,Num=3,Data=<2C2D,2C2D,2A2B>" -fill 0 2 50 0xA2B2 -poke 2 2 [binary format ss 0xB2C2 0xD2E2] -peek 0 2 4 -expect "%timestamp Trg-Peek Offs=0,Size=2,Num=4,Data=" - -#---------- -test "Peek/Poke/Fill uint32_t" -noreset -fill 0 4 25 0x4A4B4C4D -peek 0 4 3 -expect "%timestamp Trg-Peek Offs=0,Size=4,Num=3,Data=<4A4B4C4D,4A4B4C4D,4A4B4C4D>" -peek 88 4 3 -expect "%timestamp Trg-Peek Offs=88,Size=4,Num=3,Data=<4A4B4C4D,4A4B4C4D,4A4B4C4D>" -fill 4 4 23 0x4C4D4E4F -peek 0 4 3 -expect "%timestamp Trg-Peek Offs=0,Size=4,Num=3,Data=<4A4B4C4D,4C4D4E4F,4C4D4E4F>" -peek 88 4 3 -expect "%timestamp Trg-Peek Offs=88,Size=4,Num=3,Data=<4C4D4E4F,4C4D4E4F,4A4B4C4D>" -fill 0 4 25 0xA4B4C4D4 -poke 4 4 [binary format ii 0xB4C4D4E4 0xB5C5D5E5] -peek 0 4 4 -expect "%timestamp Trg-Peek Offs=0,Size=4,Num=4,Data=" - - -# the end -end - diff --git a/examples/qutest/self_test/test_probe.py b/examples/qutest/self_test/test_probe.py deleted file mode 100644 index 66c512e9..00000000 --- a/examples/qutest/self_test/test_probe.py +++ /dev/null @@ -1,50 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -import sys -import pytest -import struct -from qspypy.qspy import FILTER, QS_OBJ_KIND - - -def on_setup(qutest): - qutest.expect("%timestamp ON_TEST_SETUP") - -def on_teardown(qutest): - qutest.expect("%timestamp ON_TEST_TEARDOWN") - - -def test_Single_Test_Probe(qutest): - qutest.command("COMMAND_X") - qutest.expect("%timestamp COMMAND_X 0") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.probe("myFun",1) - qutest.command("COMMAND_X") - qutest.expect("%timestamp TstProbe Fun=myFun,Data=1") - qutest.expect("%timestamp COMMAND_X 1") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("COMMAND_X") - qutest.expect("%timestamp COMMAND_X 0") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - -def test_Multiple_Test_Probes(qutest_noreset): - qutest = qutest_noreset # name change - qutest.probe("myFun",100022) - qutest.probe("myFun",200033) - qutest.command("COMMAND_X") - qutest.expect("%timestamp TstProbe Fun=myFun,Data=100022") - qutest.expect("%timestamp COMMAND_X 100022") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("COMMAND_X") - qutest.expect("%timestamp TstProbe Fun=myFun,Data=200033") - qutest.expect("%timestamp COMMAND_X 200033") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - qutest.command("COMMAND_X") - qutest.expect("%timestamp COMMAND_X 0") - qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") - - -if __name__ == "__main__": - options = ['-x', '-v', '--tb=short'] - options.extend(sys.argv) - pytest.main(options) diff --git a/examples/qutest/self_test/test_probe.tcl b/examples/qutest/self_test/test_probe.tcl deleted file mode 100644 index 3c60bc34..00000000 --- a/examples/qutest/self_test/test_probe.tcl +++ /dev/null @@ -1,46 +0,0 @@ -# test-script for QUTest unit testing harness -# see https://www.state-machine.com/qtools/qutest.html - -# preamble... -proc on_setup {} { - expect "%timestamp ON_TEST_SETUP" -} -proc on_teardown {} { - expect "%timestamp ON_TEST_TEARDOWN" -} - -# tests... - -#---------- -test "Single Test Probe" -command COMMAND_X -expect "%timestamp COMMAND_X 0" -expect "%timestamp Trg-Done QS_RX_COMMAND" -probe myFun 1 -command COMMAND_X -expect "%timestamp TstProbe Fun=myFun,Data=1" -expect "%timestamp COMMAND_X 1" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command COMMAND_X -expect "%timestamp COMMAND_X 0" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -#---------- -test "Multiple Test Probes" -noreset -probe myFun 100022 -probe myFun 200033 -command COMMAND_X -expect "%timestamp TstProbe Fun=myFun,Data=100022" -expect "%timestamp COMMAND_X 100022" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command COMMAND_X -expect "%timestamp TstProbe Fun=myFun,Data=200033" -expect "%timestamp COMMAND_X 200033" -expect "%timestamp Trg-Done QS_RX_COMMAND" -command COMMAND_X -expect "%timestamp COMMAND_X 0" -expect "%timestamp Trg-Done QS_RX_COMMAND" - -# the end -end - diff --git a/examples/qutest/self_test/test_qutest.c b/examples/qutest/self_test/test_qutest.c deleted file mode 100644 index 49a69e66..00000000 --- a/examples/qutest/self_test/test_qutest.c +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST self-test -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* 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 "qpc.h" /* for QUTEST */ - -Q_DEFINE_THIS_FILE - -/*--------------------------------------------------------------------------*/ -static uint8_t buffer[100]; -static uint32_t myFun(void); - -enum { - ON_TEST_SETUP = QS_USER, - ON_TEST_TEARDOWN, - COMMAND_X, - MY_RECORD, -}; - -/*--------------------------------------------------------------------------*/ -int main(int argc, char *argv[]) { - - QF_init(); /* initialize the framework */ - - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* global filter */ - QS_FILTER_ON(QS_ALL_RECORDS); /* enable all QS records */ - - /* dictionaries... */ - QS_OBJ_DICTIONARY(buffer); - QS_FUN_DICTIONARY(&myFun); - - QS_USR_DICTIONARY(ON_TEST_SETUP); - QS_USR_DICTIONARY(ON_TEST_TEARDOWN); - QS_USR_DICTIONARY(COMMAND_X); - QS_USR_DICTIONARY(MY_RECORD); - - return QF_run(); /* run the tests */ -} - -/*--------------------------------------------------------------------------*/ -void QS_onTestSetup(void) { - QS_BEGIN(ON_TEST_SETUP, (void *)0) - QS_END() -} -/*..........................................................................*/ -void QS_onTestTeardown(void) { - QS_BEGIN(ON_TEST_TEARDOWN, (void *)0) - QS_END() -} - -/*..........................................................................*/ -/*! callback function to execute user commands */ -void QS_onCommand(uint8_t cmdId, uint32_t param1, - uint32_t param2, uint32_t param3) -{ - (void)param1; - (void)param2; - (void)param3; - - switch (cmdId) { - case COMMAND_X: { - uint32_t x = myFun(); - QS_BEGIN(COMMAND_X, (void *)0) /* application-specific record */ - QS_U32(0, x); - /* ... */ - QS_END() - break; - } - default: - break; - } -} - -/*..........................................................................*/ -/*! callback function to "massage" the injected QP events (not used here) */ -void QS_onTestEvt(QEvt *e) { - (void)e; -} - -/*--------------------------------------------------------------------------*/ -static uint32_t myFun(void) { - QS_TEST_PROBE_DEF(&myFun) - QS_TEST_PROBE( - return qs_tp_; - ) - return 0; -} - diff --git a/examples/qutest/efm32-slstk3401a/flash.bat b/examples/qutest/target_efm32/flash.bat similarity index 100% rename from examples/qutest/efm32-slstk3401a/flash.bat rename to examples/qutest/target_efm32/flash.bat diff --git a/examples/qutest/efm32-slstk3401a/qutest_port.c b/examples/qutest/target_efm32/qutest_port.c similarity index 100% rename from examples/qutest/efm32-slstk3401a/qutest_port.c rename to examples/qutest/target_efm32/qutest_port.c diff --git a/examples/qutest/efm32-slstk3401a/test.icf b/examples/qutest/target_efm32/test.icf similarity index 100% rename from examples/qutest/efm32-slstk3401a/test.icf rename to examples/qutest/target_efm32/test.icf diff --git a/examples/qutest/efm32-slstk3401a/test.ld b/examples/qutest/target_efm32/test.ld similarity index 100% rename from examples/qutest/efm32-slstk3401a/test.ld rename to examples/qutest/target_efm32/test.ld diff --git a/examples/qutest/ek-tm4c123gxl/qutest_port.c b/examples/qutest/target_tm4c123/qutest_port.c similarity index 100% rename from examples/qutest/ek-tm4c123gxl/qutest_port.c rename to examples/qutest/target_tm4c123/qutest_port.c diff --git a/examples/qutest/ek-tm4c123gxl/test.ld b/examples/qutest/target_tm4c123/test.ld similarity index 100% rename from examples/qutest/ek-tm4c123gxl/test.ld rename to examples/qutest/target_tm4c123/test.ld diff --git a/examples/qutest/unity_basic/README.txt b/examples/qutest/unity_basic/README.txt new file mode 100644 index 00000000..741ac11f --- /dev/null +++ b/examples/qutest/unity_basic/README.txt @@ -0,0 +1,105 @@ +About This Example +================== +This example is based on "example_1" from the Unity unit testing framework. +The purpose is to illustrate testing of the same code (src/ProductionCode.c) +with Unity and with QUTest. + +*** NOTE *** +The provided Makefiles for building and running the tests are cross-platform +and will work on Windows as well as POSIX workstations (Linux/MacOS). Also, +it is assumed that you have installed the QTools collection on your computer +and that you have added the QTools/bin directory to your PATH, see: + https://www.state-machine.com/qtools + + +Directories and Files +--------------------- + +qpc/examples/qutest/unity_basic/ - this example +| ++-src/ - code under test (CUT) +| +-ProductionCode.h +| +-ProductionCode.c +| ++-test_qutest/ - testing with QUTest +| +-conftest.py - configuration file for Python +| +-Makefile - makefile for building and running the tests +| +-make_ef32 - makefile for building and running the tests EFM32 target +| +-make_tm4c123 - makefile for building and running the tests TM4C123 target +| +-test_ProductionCode.c - QUTest test fixture in C +| +-test_ProductionCode.py - QUTest test script in Python +| +-test_ProductionCode.tcl - QUTest test script in Tcl +| ++-test_unity/ - testing with Unity +| +-Makefile - makefile for building and running the tests +| +-TestProductionCode.c - Unity test fixture and test runner +| + + +Building the Code and Testing with Unity +---------------------------------------- +Open a terminal/command-prompt. Change directory to test_unity +(qpc/examples/qutest/unity_basic/test_unity). + +Type "make". The provided Makefile will build the code and run +the tests using the Unity framework. + +*** NOTE *** +For Windows, the make utility, the C compiler (MinGW) are included +in the QTools collection. For all platforms, you will also need +the Unity source code, which is also included in the QTools collection +and the provided Makefile takes it from there. + +*** NOTE *** +Some of the Unity tests fail, which is intentional to demonstrate +various failure modes. + + +Building the Code and Testing with QUTest +----------------------------------------- +Open terminal / command-prompt and launch the QSPY host utility +by typing: + +qspy -u -t + +Open *another* terminal / command-prompt and change directory to +test_qutest (qpc/examples/qutest/unity_example1/test_qutest). +Type: + +make + +to build the code with the provided Makefile and run the tests +using the Tcl test script (test_ProductionCode.tcl) + +*** NOTE *** +For Windows, the Tcl interpreter (tclsh 8.4) with the UDP extension +is included in the QTools collection, so you don't need to install +any additional software to run the Tcl tests. For other operating +systems (Linux/MacOS), Tcl is typically provided, but you need to +install the UDP extension, as described at: +https://www.state-machine.com/qtools/start.html#qtools_qspypy + +*** NOTE *** +Some of the QUTest tests fail, which is intentional to demonstrate +various failure modes, exactly as it is in the case of Unity tests. + + +If you prefer to use Python, add "SCRIPT=py" parameter to make: + +make SCRIPT=py + +this will build the code and run the tests +using the Python test script (test_ProductionCode.py) + +*** NOTE *** +In order to run the Python tests, you need to install Python on +your machine. Additionally, you need to enable Python support for +QUTest unit testing, as described at: +https://www.state-machine.com/qtools/start.html#qtools_qspypy + + +Contact Information +------------------- +https://www.state-machine.com +mailto:info@state-machine.com + diff --git a/examples/qutest/unity_basic/src/ProductionCode.c b/examples/qutest/unity_basic/src/ProductionCode.c new file mode 100644 index 00000000..623e67f4 --- /dev/null +++ b/examples/qutest/unity_basic/src/ProductionCode.c @@ -0,0 +1,23 @@ +#include "ProductionCode.h" + +int Counter = 0; +int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; //some obnoxious array to search that is 1-based indexing instead of 0. + +// This function is supposed to search through NumbersToFind and find a particular number. +// If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since +// NumbersToFind is indexed from 1. Unfortunately it's broken +// (and should therefore be caught by our tests) +int FindFunction_WhichIsBroken(int NumberToFind) +{ + int i = 0; + while (i < 8) //Notice I should have been in braces + i++; + if (NumbersToFind[i] == NumberToFind) //Yikes! I'm getting run after the loop finishes instead of during it! + return i; + return 0; +} + +int FunctionWhichReturnsLocalVariable(void) +{ + return Counter; +} diff --git a/examples/qutest/unity_basic/src/ProductionCode.h b/examples/qutest/unity_basic/src/ProductionCode.h new file mode 100644 index 00000000..250ca0dc --- /dev/null +++ b/examples/qutest/unity_basic/src/ProductionCode.h @@ -0,0 +1,3 @@ + +int FindFunction_WhichIsBroken(int NumberToFind); +int FunctionWhichReturnsLocalVariable(void); diff --git a/examples/qutest/unity_basic/test_qutest/Makefile b/examples/qutest/unity_basic/test_qutest/Makefile new file mode 100644 index 00000000..4311d39a --- /dev/null +++ b/examples/qutest/unity_basic/test_qutest/Makefile @@ -0,0 +1,267 @@ +############################################################################## +# Product: Makefile for QUTEST-QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# make # make and run the tests in the current directory +# make TESTS=test*.tcl # make and run the selected tests in the curr. dir. +# make SCRIPT=py # make and run the Python tests +# make HOST=localhost:7705 # connect to host:port +# make norun # only make but not run the tests +# make clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := test_basic + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH = . \ + ../src + +# list of all include directories needed by this project +INCLUDES = -I. \ + -I../src + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + ProductionCode.c \ + test_ProductionCode.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + QP_PORT_DIR := $(QPC)/ports/win32-qutest + LIB_DIRS += -L$(QP_PORT_DIR)/mingw + LIBS += -lqp -lwsock32 +QS_SRCS := +else + QP_PORT_DIR := $(QPC)/ports/posix-qutest + C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + + LIBS += -lpthread +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QPC)/src/qs $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +ifeq ($(SCRIPT),py) +QUTEST := qutest +else +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl +endif + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build options... + +BIN_DIR := build + +CFLAGS = -c -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +CPPFLAGS = -c -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : norun clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_EXE) +norun : all +else +all : $(TARGET_EXE) run +endif + +ifeq (, $(TESTS)) +ifeq ($(SCRIPT),py) +TESTS := *.py +else +TESTS := *.tcl +endif +endif + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +run : $(TARGET_EXE) + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + @echo QTOOLS = $(QTOOLS) + @echo QUTEST = $(QUTEST) + @echo TESTS = $(TESTS) + diff --git a/examples/qutest/TDDbook_Sprintf/conftest.py b/examples/qutest/unity_basic/test_qutest/conftest.py similarity index 69% rename from examples/qutest/TDDbook_Sprintf/conftest.py rename to examples/qutest/unity_basic/test_qutest/conftest.py index 48253da6..5a61638a 100644 --- a/examples/qutest/TDDbook_Sprintf/conftest.py +++ b/examples/qutest/unity_basic/test_qutest/conftest.py @@ -4,4 +4,4 @@ # # Load common fixtures used throughout testing -from qspypy.fixtures import session, reset, module, qutest, qutest_noreset +from qspypy.fixtures import * diff --git a/examples/qutest/unity_basic/test_qutest/log_py.txt b/examples/qutest/unity_basic/test_qutest/log_py.txt new file mode 100644 index 00000000..f4130926 --- /dev/null +++ b/examples/qutest/unity_basic/test_qutest/log_py.txt @@ -0,0 +1,84 @@ + +////////////////////////////////////////////////////////////////////////// +============================= test session starts ============================= +platform win32 -- Python 3.6.6, pytest-3.6.2, py-1.5.3, pluggy-0.6.0 -- c:\tools\python\py +thon.exe +cachedir: .pytest_cache +rootdir: C:\qp_lab\qpc\examples\qutest\unity_basic\test_qutest, inifile: +collected 5 items + +test_ProductionCode.py::test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode PASSED +test_ProductionCode.py::test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken FAILED +test_ProductionCode.py::test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken ERROR +test_ProductionCode.py::test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue ERROR +test_ProductionCode.py::test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain +Flushing text queue: +b'\x1c\x00B Trg-Ack QS_RX_TEST_SETUP' +PASSED +test_ProductionCode.py::test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed FAILED +test_ProductionCode.py::test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed ERROR + +=================================== ERRORS ==================================== + ERROR at teardown of test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken +c:\tools\python\lib\site-packages\qspypy\fixtures.py:109: in qutest + reset.call_on_teardown() +c:\tools\python\lib\site-packages\qspypy\qutest.py:258: in call_on_teardown + self.expect(' Trg-Ack QS_RX_TEST_TEARDOWN') +E Failed: Expect Match Failed! +E Expected:" Trg-Ack QS_RX_TEST_TEARDOWN" +E Received:"0000000002 Trg-Done QS_RX_COMMAND" + ERROR at setup of test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue +c:\tools\python\lib\site-packages\qspypy\fixtures.py:103: in qutest + reset.call_on_setup() +c:\tools\python\lib\site-packages\qspypy\qutest.py:249: in call_on_setup + self.expect(' Trg-Ack QS_RX_TEST_SETUP') +E Failed: Expect Match Failed! +E Expected:" Trg-Ack QS_RX_TEST_SETUP" +E Received:" Trg-Ack QS_RX_TEST_TEARDOWN" + ERROR at teardown of test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed +c:\tools\python\lib\site-packages\qspypy\fixtures.py:109: in qutest + reset.call_on_teardown() +c:\tools\python\lib\site-packages\qspypy\qutest.py:258: in call_on_teardown + self.expect(' Trg-Ack QS_RX_TEST_TEARDOWN') +E Failed: Expect Match Failed! +E Expected:" Trg-Ack QS_RX_TEST_TEARDOWN" +E Received:"0000000002 Trg-Done QS_RX_COMMAND" +================================== FAILURES =================================== + test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken +test_ProductionCode.py:38: in test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken + qutest.expect("%timestamp USER+000 FindFunction_WhichIsBroken 1 34") +E Failed: Expect Match Failed! +E Expected:"0000000001 USER+000 FindFunction_WhichIsBroken 1 34" +E Received:"0000000001 USER+000 FindFunction_WhichIsBroken 0 34" + test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed +test_ProductionCode.py:69: in test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed + qutest.expect("%timestamp USER+001 FunctionWhichReturnsLocalVariable 0x1234") +E Failed: Expect Match Failed! +E Expected:"0000000001 USER+001 FunctionWhichReturnsLocalVariable 0x1234" +E Received:"0000000001 USER+001 FunctionWhichReturnsLocalVariable 0x5A5A" +================= 2 failed, 2 passed, 3 error in 5.25 seconds ================= +make: *** [run] Error 1 + + +////////////////////////////////////////////////////////////////////////// + +tclsh C:\qp\qtools/qspy/tcl/qutest.tcl *.tcl build/test_basic.exe +QUTEST unit testing front-end 6.3.6 +Copyright (c) 2005-2018 Quantum Leaps +help at: https://state-machine.com/qtools/qutest.html +Attaching to QSPY...OK (UDP-Port=59165) +---------------------------------------------- +Group: test_ProductionCode.tcl +FindFunction_WhichIsBroken() Should Return Zero If Item Is Not In List, Which Works Even In Our Broken Code : passed (0.099s) +FindFunction_WhichIsBroken() Should Return The Index For Items In List, Which Will Fail Because Our Function Under Test Is Broken : ====> FAILED (0.972s) <==== +Expected: "0000000001 USER+000 FindFunction_WhichIsBroken 1 34" +Received: "0000000001 USER+000 FindFunction_WhichIsBroken 0 34" +FunctionWhichReturnsLocalVariable() Should Return The Current Counter Value : passed (0.099s) +FunctionWhichReturnsLocalVariable() Should Return The Current Counter Value Again : passed (0.1s) +FunctionWhichReturnsLocalVariable() Should Return Current Counter, But Fails Because This Test Is Actually Flawed : ====> FAILED (0.517s) <==== +Expected: "0000000001 USER+001 FunctionWhichReturnsLocalVariable 0x1234" +Received: "0000000001 USER+001 FunctionWhichReturnsLocalVariable 0x5A5A" +=========== Target: 181016_163545 ============ +1 Groups 5 Tests 2 Failures 0 Skipped (5.691s) +FAIL! +make: *** [run] Error 1 \ No newline at end of file diff --git a/examples/qutest/self_test/efm32-slstk3401a.mak b/examples/qutest/unity_basic/test_qutest/make_efm32 similarity index 81% rename from examples/qutest/self_test/efm32-slstk3401a.mak rename to examples/qutest/unity_basic/test_qutest/make_efm32 index ac7a38e3..ab10db69 100644 --- a/examples/qutest/self_test/efm32-slstk3401a.mak +++ b/examples/qutest/unity_basic/test_qutest/make_efm32 @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for EMF32-SLSTK3401A, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 +# Product: Makefile for EMF32, QUTEST, GNU-ARM +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -fefm32-slstk3401a.mak # make and run the tests in the current directory -# make -fefm32-slstk3401a.mak TESTS=philo*.tcl # make and run the selected tests -# make -fefm32-slstk3401a.mak SCRIPT=py # make and run the Python tests -# make -fefm32-slstk3401a.mak HOST=localhost:7705 # connect to host:port -# make -fefm32-slstk3401a.mak norun # only make but not run the tests -# make -fefm32-slstk3401a.mak clean # cleanup the build +# make -f make_efm32 # make and run the tests in the current directory +# make -f make_efm32 TESTS=philo*.tcl # make and run the selected tests +# make -f make_efm32 SCRIPT=py # make and run the Python tests +# make -f make_efm32 HOST=localhost:7705 # connect to host:port +# make -f make_efm32 norun # only make but not run the tests +# make -f make_efm32 clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -47,32 +47,34 @@ # #----------------------------------------------------------------------------- -# project name, binary output directory +# project name, target name, target directory: # -PROJECT := test_qutest -TARGET := efm32-slstk3401a +PROJECT := test_basic +TARGET := efm32 +TARGET_DIR := ..\..\target_efm32 #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) +# location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../.. +QPC := ../../../.. endif -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - # QP port used in this project QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + # list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ +VPATH := . \ + ../src \ + $(TARGET_DIR) \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ @@ -80,9 +82,9 @@ VPATH = \ $(QPC)/3rd_party/efm32pg1b/gnu # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ -I$(QPC)/include \ -I$(QPC)/src \ -I$(QP_PORT_DIR) \ @@ -90,7 +92,7 @@ INCLUDES = \ -I$(QPC)/3rd_party/efm32pg1b #----------------------------------------------------------------------------- -# files +# project files: # # assembler source files @@ -98,7 +100,8 @@ ASM_SRCS := # C source files C_SRCS := \ - test_qutest.c \ + ProductionCode.c \ + test_ProductionCode.c \ startup_efm32pg1b.c \ system_efm32pg1b.c \ em_cmu.c \ @@ -110,7 +113,7 @@ C_SRCS := \ CPP_SRCS := OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld +LD_SCRIPT := $(TARGET_DIR)/test.ld QP_SRCS := \ qep_hsm.c \ @@ -124,6 +127,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -171,10 +175,10 @@ BIN := $(GNU_ARM)/bin/arm-eabi-objcopy #----------------------------------------------------------------------------- # FLASH tool (NOTE: Requires the JLINK utility) -# see ../efm32-slstk3401a/flash.bat +# see $(TARGET_DIR)\flash.bat # -FLASH := ..\efm32-slstk3401a\flash.bat +FLASH := $(TARGET_DIR)\flash.bat ############################################################################## # Typically you should not need to change anything below this line @@ -186,11 +190,9 @@ MKDIR := mkdir RM := rm ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := python -m qspypy.qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif #----------------------------------------------------------------------------- @@ -201,15 +203,15 @@ endif C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) -BIN_DIR := $(TARGET) +BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST @@ -267,15 +269,9 @@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) flash : $(FLASH) $(TARGET_BIN) -ifeq ($(SCRIPT),py) run : $(TARGET_BIN) $(FLASH) $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/qutest/self_test/ek-tm4c123gxl.mak b/examples/qutest/unity_basic/test_qutest/make_tm4c123 similarity index 81% rename from examples/qutest/self_test/ek-tm4c123gxl.mak rename to examples/qutest/unity_basic/test_qutest/make_tm4c123 index cfc54fde..06f33e42 100644 --- a/examples/qutest/self_test/ek-tm4c123gxl.mak +++ b/examples/qutest/unity_basic/test_qutest/make_tm4c123 @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for EK-TM4C123GXL, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 +# Product: Makefile for TM4C123, QUTEST, GNU-ARM +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak SCRIPT=py # make and run the Python tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build +# make -f make_tm4c123 # make and run the tests in the current directory +# make -f make_tm4c123 TESTS=philo*.tcl # make and run the selected tests +# make -f make_tm4c123 SCRIPT=py # make and run the Python tests +# make -f make_tm4c123 HOST=localhost:7705 # connect to host:port +# make -f make_tm4c123 norun # only make but not run the tests +# make -f make_tm4c123 clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -47,32 +47,34 @@ # #----------------------------------------------------------------------------- -# project name, binary output directory +# project name, target name, target directory: # -PROJECT := test_qutest -TARGET := ek-tm4c123gxl +PROJECT := test_basic +TARGET := tm4c123 +TARGET_DIR := ..\..\target_tm4c123 #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) +# location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../.. +QPC := ../../../.. endif -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - # QP port used in this project QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + # list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ +VPATH := . \ + ../src \ + $(TARGET_DIR) \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ @@ -80,9 +82,9 @@ VPATH = \ $(QPC)/3rd_party/ek-tm4c123gxl/gnu # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ -I$(QPC)/include \ -I$(QPC)/src \ -I$(QP_PORT_DIR) \ @@ -90,7 +92,7 @@ INCLUDES = \ -I$(QPC)/3rd_party/ek-tm4c123gxl #----------------------------------------------------------------------------- -# files +# project files: # # assembler source files @@ -98,7 +100,8 @@ ASM_SRCS := # C source files C_SRCS := \ - test_qutest.c \ + ProductionCode.c \ + test_ProductionCode.c \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c @@ -106,7 +109,7 @@ C_SRCS := \ CPP_SRCS := OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld +LD_SCRIPT := $(TARGET_DIR)/test.ld QP_SRCS := \ qep_hsm.c \ @@ -120,6 +123,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -171,7 +175,7 @@ BIN := $(GNU_ARM)/bin/arm-eabi-objcopy # location of the LMFlash utility on your machine # ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe +FLASH := LMFlash.exe -q ek-tm4c123gxl endif @@ -185,11 +189,9 @@ MKDIR := mkdir RM := rm ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := python -m qspypy.qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif #----------------------------------------------------------------------------- @@ -200,15 +202,15 @@ endif C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) -BIN_DIR := $(TARGET) +BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST @@ -257,24 +259,18 @@ endif $(TARGET_BIN) : $(TARGET_ELF) $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ + $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) + $(FLASH) $(TARGET_BIN) -ifeq ($(SCRIPT),py) run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif + $(FLASH) -c $< + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/qutest/qmsmtst/test_qmsm.c b/examples/qutest/unity_basic/test_qutest/test_ProductionCode.c similarity index 53% rename from examples/qutest/qmsmtst/test_qmsm.c rename to examples/qutest/unity_basic/test_qutest/test_ProductionCode.c index 746af04f..95f13b28 100644 --- a/examples/qutest/qmsmtst/test_qmsm.c +++ b/examples/qutest/unity_basic/test_qutest/test_ProductionCode.c @@ -1,11 +1,11 @@ /***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 +* Purpose: example QUTEST fixture for the basic example from Unity +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-11 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -31,45 +31,34 @@ * https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ -#include "qpc.h" -#include "qmsmtst.h" +#include "qpc.h" /* QUTest interface */ +#include "ProductionCode.h" /* CUT interface */ Q_DEFINE_THIS_FILE -enum { - BSP_DISPLAY = QS_USER, -}; +/*--------------------------------------------------------------------------*/ +// sometimes you may want to get at local data in a module. +// for example: If you plan to pass by reference, this could be useful +// however, it should often be avoided +extern int Counter; /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ - QF_init(); /* initialize the framework */ + QF_init(); /* initialize the framework */ /* initialize the QS software tracing */ Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* dictionaries... */ - QS_OBJ_DICTIONARY(the_msm); - QS_USR_DICTIONARY(BSP_DISPLAY); + QS_FUN_DICTIONARY(&FindFunction_WhichIsBroken); + QS_FUN_DICTIONARY(&FunctionWhichReturnsLocalVariable); + QS_OBJ_DICTIONARY(&Counter); - QMsmTst_ctor(); /* instantiate the QHsmTst object */ + /* filter setup... */ + QS_FILTER_ON(QS_ALL_RECORDS); - return QF_run(); -} - -/*--------------------------------------------------------------------------*/ -void BSP_display(char const *msg) { - QS_BEGIN(BSP_DISPLAY, (void *)0) /* application-specific record */ - QS_STR(msg); - QS_END() -} - -/*..........................................................................*/ -void BSP_exit(void) { + return QF_run(); /* run the tests */ } /*--------------------------------------------------------------------------*/ @@ -78,37 +67,53 @@ void QS_onTestSetup(void) { /*..........................................................................*/ void QS_onTestTeardown(void) { } + /*..........................................................................*/ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)param1; + switch (cmdId) { + case 0: { /* call the CUT: FindFunction_WhichIsBroken */ + int ret = FindFunction_WhichIsBroken((int)param1); + QS_BEGIN(QS_USER + cmdId, (void *)0) /* user-specific record */ + QS_FUN(&FindFunction_WhichIsBroken); /* function called */ + QS_I32(0, (int32_t)ret); /* returned value */ + QS_I32(0, (int32_t)param1); /* parameter */ + QS_END() + break; + } + case 1: { /* call the CUT: FunctionWhichReturnsLocalVariable */ + int ret = FunctionWhichReturnsLocalVariable(); + QS_BEGIN(QS_USER + cmdId, (void *)0) /* user-specific record */ + QS_FUN(&FunctionWhichReturnsLocalVariable); /* function called */ + QS_U32_HEX(0, (uint32_t)ret); /* returned value */ + QS_END() + break; + } + default: + break; + } + + /* unused parametrers... */ + //(void)param1; (void)param2; (void)param3; - - //printf(" Command id=%d param=%d\n", (int)cmdId, (int)param); - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } } - /*..........................................................................*/ +/* host callback function to "massage" the event, if necessary */ +void QS_onTestEvt(QEvt *e) { + (void)e; #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ - -/*! host callback function to "massage" the event, if necessary */ -void QS_onTestEvt(QEvt *e) { - (void)e; -} - #else /* this test is compiled for an embedded Target system */ - -void QS_onTestEvt(QEvt *e) { - (void)e; -} - #endif - +} +/*..........................................................................*/ +/*! callback function to output the posted QP events (not used here) */ +void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status) +{ + (void)sender; + (void)recipient; + (void)e; + (void)status; +} diff --git a/examples/qutest/unity_basic/test_qutest/test_ProductionCode.py b/examples/qutest/unity_basic/test_qutest/test_ProductionCode.py new file mode 100644 index 00000000..67bf9b67 --- /dev/null +++ b/examples/qutest/unity_basic/test_qutest/test_ProductionCode.py @@ -0,0 +1,78 @@ +# QUTEST test script corresponding to the test_ProductionCode.c test fixture. +# see https://www.state-machine.com/qtools/qutest.html + +import sys +import pytest +import struct +from qspypy.qspy import * + +# preambe... +def on_setup(qutest): + # This is run before EACH TEST + qutest.current_obj(QS_OBJ_KIND.AP, 'Counter') + qutest.poke(0, 4, struct.pack(' $@ @@ -219,13 +205,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) diff --git a/examples/qutest/unity_basic/test_unity/TestProductionCode.c b/examples/qutest/unity_basic/test_unity/TestProductionCode.c new file mode 100644 index 00000000..908c8dd8 --- /dev/null +++ b/examples/qutest/unity_basic/test_unity/TestProductionCode.c @@ -0,0 +1,83 @@ +/* +* This file has been adapted from the Unity unit testing harness, +* from the directory examples/example_1/test/. The original file +* TestProductionCode.c has been augmented with the main() function +* to run the tests. This eliminates the need for a "test-runner". +* +* Quantum Leaps, state-machine.com, 2018-10-10 +*/ +#include "ProductionCode.h" +#include "unity.h" + +/* sometimes you may want to get at local data in a module. + * for example: If you plan to pass by reference, this could be useful + * however, it should often be avoided */ +extern int Counter; + +void setUp(void) +{ + /* This is run before EACH TEST */ + Counter = 0x5a5a; +} + +void tearDown(void) +{ + /* This is run after EACH TEST */ +} + +void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void) +{ + /* All of these should pass */ + TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(78)); + TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(1)); + TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(33)); + TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(999)); + TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(-1)); +} + +void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void) +{ + /* You should see this line fail in your test summary */ + TEST_ASSERT_EQUAL(1, FindFunction_WhichIsBroken(34)); + + /* Notice the rest of these didn't get a chance to run because the line above failed. + * Unit tests abort each test function on the first sign of trouble. + * Then NEXT test function runs as normal. */ + TEST_ASSERT_EQUAL(8, FindFunction_WhichIsBroken(8888)); +} + +void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void) +{ + /* This should be true because setUp set this up for us before this test */ + TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable()); + + /* This should be true because we can still change our answer */ + Counter = 0x1234; + TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable()); +} + +void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void) +{ + /* This should be true again because setup was rerun before this test (and after we changed it to 0x1234) */ + TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable()); +} + +void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void) +{ + /* Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell + * you what actually happened...which in this case was a failure to setup the initial condition. */ + TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable()); +} + +/* Let Unity run the tests and report the results ... */ +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode); + RUN_TEST(test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken); + RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue); + RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain); + RUN_TEST(test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed); + return UNITY_END(); +} + diff --git a/examples/qutest/unity_mock/README.txt b/examples/qutest/unity_mock/README.txt new file mode 100644 index 00000000..bf8fbd3b --- /dev/null +++ b/examples/qutest/unity_mock/README.txt @@ -0,0 +1,126 @@ +About This Example +================== +This example is loosely based on Matt Chernosky's blog "Test-Driving +with Mocks Instead of Hardware", which you can find at: +http://www.electronvector.com/blog/test-driving-with-mocks-instead-of-hardware +https://vimeo.com/256590562 + +The purpose is to illustrate the simpler alternative to building Mocks with +QUTest. + +*** NOTE *** +The provided Makefiles for building and running the tests are cross-platform +and will work on Windows as well as POSIX workstations (Linux/MacOS). Also, +it is assumed that you have installed the QTools collection on your computer +and that you have added the QTools/bin directory to your PATH, see: + https://www.state-machine.com/qtools + + +Directories and Files +--------------------- + +qpc/examples/qutest/unity_basic/ - this example +| ++-src/ - code under test (CUT) +| +-Led.h +| +-LedBar.h +| +-LedBar.c +| ++-test_qutest/ - testing with QUTest +| +-conftest.py - configuration file for Python +| +-Makefile - makefile for building and running the tests (host) +| +-make_ef32 - makefile for building and running the tests EFM32 target +| +-make_tm4c123 - makefile for building and running the tests TM4C123 target +| +-Makefile - makefile for building and running the tests +| +-spy_Led.c - QUTest "spy" test double for LED (replaces the mock) +| +-test_LedBar.c - QUTest test fixture for LedBar +| +-test_LedBar.py - QUTest test script in Python +| +-test_LedBare.tcl - QUTest test script in Tcl +| ++-test_unity/ - testing with Unity +| +-cmock/ - CMock source code needed in this example +| | +-cmock.h +| | +-cmock.c +| | +-cmock_internals.h +| | +| +-Makefile - makefile for building and running the tests +| +-make_ef32 - makefile for building and running the tests EFM32 target +| +-make_tm4c123 - makefile for building and running the tests TM4C123 target +| +-MockLed.h - interface of the LED-Mock (generated by CMock) +| +-MockLed.c - implementation of the LED-Mock (generated by CMock) +| +-TestLedBar.c - test fixture for the LedBar CUT +| +-TestLedBar_Runner.c - test runner for the LedBar (generated by CMock) +| + + +Building the Code and Testing with Unity +---------------------------------------- +Open a terminal/command-prompt. Change directory to test_unity +(qpc/examples/qutest/unity_mock/test_unity). + +Type "make". The provided Makefile will build the code and run +the tests using the Unity framework. + +*** NOTE *** +For Windows, the make utility, the C compiler (MinGW) are included +in the QTools collection. For all platforms, you will also need +the Unity source code, which is also included in the QTools collection +and the provided Makefile takes it from there. + +*** NOTE *** +Some of the Unity tests fail, which is intentional to demonstrate +various failure modes. + + +Building the Code and Testing with QUTest +----------------------------------------- +Open terminal / command-prompt and launch the QSPY host utility +by typing: + +qspy -u -t + +Open *another* terminal / command-prompt and change directory to +test_qutest (qpc/examples/qutest/unity_mock/test_qutest). +Type: + +make + +to build the code with the provided Makefile and run the tests +using the Tcl test script (test_LedBar.tcl) + +*** NOTE *** +For Windows, the Tcl interpreter (tclsh 8.4) with the UDP extension +is included in the QTools collection, so you don't need to install +any additional software to run the Tcl tests. For other operating +systems (Linux/MacOS), Tcl is typically provided, but you need to +install the UDP extension, as described at: +https://www.state-machine.com/qtools/start.html#qtools_qspypy + +*** NOTE *** +Some of the QUTest tests fail, which is intentional to demonstrate +various failure modes, exactly as it is in the case of Unity tests. + + +If you prefer to use Python, add "SCRIPT=py" parameter to make: + +make SCRIPT=py + +this will build the code and run the tests +using the Python test script (test_LedBar.py) + +*** NOTE *** +In order to run the Python tests, you need to install Python on +your machine. Additionally, you need to enable Python support for +QUTest unit testing, as described at: +https://www.state-machine.com/qtools/start.html#qtools_qspypy + + +Contact Information +------------------- +https://www.state-machine.com +mailto:info@state-machine.com + + + +http://www.electronvector.com/blog/test-driving-with-mocks-instead-of-hardware +https://vimeo.com/256590562 diff --git a/examples/qutest/unity_mock/src/Led.h b/examples/qutest/unity_mock/src/Led.h new file mode 100644 index 00000000..246c36a9 --- /dev/null +++ b/examples/qutest/unity_mock/src/Led.h @@ -0,0 +1,12 @@ +#ifndef LED_H +#define LED_H + +enum { MAX_LED = 5 }; + +/* turns a given LED on and retruns the power drawn by it in uW */ +uint32_t Led_on(uint8_t index); + +/* turns a given LED off */ +void Led_off(uint8_t index); + +#endif /* LED_H */ \ No newline at end of file diff --git a/examples/qutest/unity_mock/src/LedBar.c b/examples/qutest/unity_mock/src/LedBar.c new file mode 100644 index 00000000..a6e7df51 --- /dev/null +++ b/examples/qutest/unity_mock/src/LedBar.c @@ -0,0 +1,16 @@ +#include +#include "LedBar.h" +#include "Led.h" + +uint32_t LedBar_setPercent(uint8_t percent) { + uint8_t n = (uint8_t)((percent * MAX_LED) / 100); + uint8_t i; + uint32_t p = 0U; /* power draw in uW */ + for (i = 0U; i < n; ++i) { + p += Led_on(i); + } + for (i = n; i < MAX_LED; ++i) { + Led_off(i); + } + return p; +} diff --git a/examples/qutest/unity_mock/src/LedBar.h b/examples/qutest/unity_mock/src/LedBar.h new file mode 100644 index 00000000..249daab7 --- /dev/null +++ b/examples/qutest/unity_mock/src/LedBar.h @@ -0,0 +1,9 @@ +#ifndef LEDBAR_H +#define LEDBAR_H + +/* displays the percentage on the LED bar +* and returns the total power drawn by the LEDs in uW. +*/ +uint32_t LedBar_setPercent(uint8_t percent); + +#endif /* LEDBAR_H */ \ No newline at end of file diff --git a/examples/qutest/evt_par/Makefile b/examples/qutest/unity_mock/test_qutest/Makefile similarity index 65% rename from examples/qutest/evt_par/Makefile rename to examples/qutest/unity_mock/test_qutest/Makefile index 79258acd..dd206fa2 100644 --- a/examples/qutest/evt_par/Makefile +++ b/examples/qutest/unity_mock/test_qutest/Makefile @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for QUTEST; QP/C on Win32 host -# Last updated for version 6.3.3 -# Last updated on 2018-07-10 +# Product: Makefile for QUTEST-QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -47,113 +47,145 @@ # #----------------------------------------------------------------------------- -# project name +# project name: # -PROJECT := evt_par +PROJECT := test_mock #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qutest - # list of all source directories used by this project -VPATH = \ - . +VPATH = . \ + ../src # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include +INCLUDES = -I. \ + -I../src + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif #----------------------------------------------------------------------------- -# files +# project files: # # C source files... C_SRCS := \ - my_ao.c \ - test_evt_par.c + LedBar.c \ + spy_Led.c \ + test_LedBar.c # C++ source files... -CPP_SRCS := +CPP_SRCS := -LIB_DIRS := -LIBS := +LIB_DIRS := +LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API DEFINES := -DQP_API_VERSION=9999 #----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + QP_PORT_DIR := $(QPC)/ports/win32-qutest + LIB_DIRS += -L$(QP_PORT_DIR)/mingw + LIBS += -lqp -lwsock32 +QS_SRCS := +else + QP_PORT_DIR := $(QPC)/ports/posix-qutest + C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + + LIBS += -lpthread +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QPC)/src/qs $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: # # NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH # CC := gcc CPP := g++ LINK := gcc # for C programs #LINK := g++ # for C++ programs -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif -#============================================================================ -# Typically you should not need to change anything below this line - #----------------------------------------------------------------------------- -# build options +# basic utilities (depends on the OS this Makefile runs on): # - -BIN_DIR := mingw - -CFLAGS = -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -CPPFLAGS = -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ - -DQ_SPY -DQ_UTEST -DQ_HOST - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif #----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp -lwsock32 +# build options... +BIN_DIR := build + +CFLAGS = -c -g -O -Wall -Wstrict-prototypes -W $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +CPPFLAGS = -c -g -O -Wall -W -fno-rtti -fno-exceptions $(INCLUDES) $(DEFINES) \ + -DQ_SPY -DQ_UTEST -DQ_HOST + +LINKFLAGS := + +#----------------------------------------------------------------------------- C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) @@ -168,7 +200,7 @@ endif # rules # -.PHONY : run norun +.PHONY : norun clean show ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_EXE) @@ -186,16 +218,11 @@ endif endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) -ifeq ($(SCRIPT),py) run : $(TARGET_EXE) - $(PYTHON) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -else -run : $(TARGET_EXE) - $(TCLSH) $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) -endif + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ @@ -204,12 +231,10 @@ $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ $(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ + $(CPP) $(CPPFLAGS) $< -o $@ $(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -.PHONY : clean show norun + $(CC) $(CFLAGS) $< -o $@ # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) @@ -221,13 +246,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) @@ -242,5 +265,4 @@ show : @echo QTOOLS = $(QTOOLS) @echo QUTEST = $(QUTEST) @echo TESTS = $(TESTS) - @echo HOST = $(HOST) diff --git a/examples/qutest/unity_mock/test_qutest/conftest.py b/examples/qutest/unity_mock/test_qutest/conftest.py new file mode 100644 index 00000000..5a61638a --- /dev/null +++ b/examples/qutest/unity_mock/test_qutest/conftest.py @@ -0,0 +1,7 @@ +# +# pytest configuration file for QUTest/Py unit testing harness, see: +# https://www.state-machine.com/qtools/qutest.html +# + +# Load common fixtures used throughout testing +from qspypy.fixtures import * diff --git a/examples/qutest/qmsmtst/efm32-slstk3401a.mak b/examples/qutest/unity_mock/test_qutest/make_efm32 similarity index 81% rename from examples/qutest/qmsmtst/efm32-slstk3401a.mak rename to examples/qutest/unity_mock/test_qutest/make_efm32 index 5e3a2305..9c7f3bcd 100644 --- a/examples/qutest/qmsmtst/efm32-slstk3401a.mak +++ b/examples/qutest/unity_mock/test_qutest/make_efm32 @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for EMF32-SLSTK3401A, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.3 -# Date of the Last Update: 2018-07-10 +# Product: Makefile for EMF32, QUTEST, GNU-ARM +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -fefm32-slstk3401a.mak # make and run the tests in the current directory -# make -fefm32-slstk3401a.mak TESTS=philo*.tcl # make and run the selected tests -# make -fefm32-slstk3401a.mak SCRIPT=py # make and run the Python tests -# make -fefm32-slstk3401a.mak HOST=localhost:7705 # connect to host:port -# make -fefm32-slstk3401a.mak norun # only make but not run the tests -# make -fefm32-slstk3401a.mak clean # cleanup the build +# make -f make_efm32 # make and run the tests in the current directory +# make -f make_efm32 TESTS=philo*.tcl # make and run the selected tests +# make -f make_efm32 SCRIPT=py # make and run the Python tests +# make -f make_efm32 HOST=localhost:7705 # connect to host:port +# make -f make_efm32 norun # only make but not run the tests +# make -f make_efm32 clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -47,32 +47,34 @@ # #----------------------------------------------------------------------------- -# project name, binary output directory +# project name, target name, target directory: # -PROJECT := test_qmsm -TARGET := efm32-slstk3401a +PROJECT := test_mock +TARGET := efm32 +TARGET_DIR := ..\..\target_efm32 #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) +# location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../.. +QPC := ../../../.. endif -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - # QP port used in this project QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + # list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ +VPATH := . \ + ../src \ + $(TARGET_DIR) \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ @@ -80,9 +82,9 @@ VPATH = \ $(QPC)/3rd_party/efm32pg1b/gnu # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ -I$(QPC)/include \ -I$(QPC)/src \ -I$(QP_PORT_DIR) \ @@ -90,7 +92,7 @@ INCLUDES = \ -I$(QPC)/3rd_party/efm32pg1b #----------------------------------------------------------------------------- -# files +# project files: # # assembler source files @@ -98,8 +100,9 @@ ASM_SRCS := # C source files C_SRCS := \ - qmsmtst.c \ - test_qmsm.c \ + LedBar.c \ + spy_Led.c \ + test_LedBar.c \ startup_efm32pg1b.c \ system_efm32pg1b.c \ em_cmu.c \ @@ -111,7 +114,7 @@ C_SRCS := \ CPP_SRCS := OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld +LD_SCRIPT := $(TARGET_DIR)/test.ld QP_SRCS := \ qep_hsm.c \ @@ -125,6 +128,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -172,10 +176,10 @@ BIN := $(GNU_ARM)/bin/arm-eabi-objcopy #----------------------------------------------------------------------------- # FLASH tool (NOTE: Requires the JLINK utility) -# see ../efm32-slstk3401a/flash.bat +# see $(TARGET_DIR)\flash.bat # -FLASH := ..\efm32-slstk3401a\flash.bat +FLASH := $(TARGET_DIR)\flash.bat ############################################################################## # Typically you should not need to change anything below this line @@ -187,11 +191,9 @@ MKDIR := mkdir RM := rm ifeq ($(SCRIPT),py) -PYTHON := python -m -QUTEST := qspypy.qutest +QUTEST := python -m qspypy.qutest else -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl endif #----------------------------------------------------------------------------- @@ -202,15 +204,15 @@ endif C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) -BIN_DIR := $(TARGET) +BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST @@ -268,15 +270,9 @@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) flash : $(FLASH) $(TARGET_BIN) -ifeq ($(SCRIPT),py) run : $(TARGET_BIN) $(FLASH) $(TARGET_BIN) - $(PYTHON) $(QUTEST) $(TESTS) "" $(HOST) -else -run : $(TARGET_BIN) - $(FLASH) $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) -endif + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/qutest/qmsmtst/ek-tm4c123gxl.mak b/examples/qutest/unity_mock/test_qutest/make_tm4c123 similarity index 80% rename from examples/qutest/qmsmtst/ek-tm4c123gxl.mak rename to examples/qutest/unity_mock/test_qutest/make_tm4c123 index a3629cab..e74992d4 100644 --- a/examples/qutest/qmsmtst/ek-tm4c123gxl.mak +++ b/examples/qutest/unity_mock/test_qutest/make_tm4c123 @@ -1,11 +1,11 @@ ############################################################################## -# Product: Makefile for EK-TM4C123GXL, QUTEST, GNU-ARM -# Last Updated for Version: 6.3.0 -# Date of the Last Update: 2018-05-10 +# Product: Makefile for TM4C123, QUTEST, GNU-ARM +# Last updated for version 6.3.6 +# Last updated on 2018-10-16 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -33,11 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -fek-tm4c123gxl.mak # make and run the tests in the current directory -# make -fek-tm4c123gxl.mak TESTS=philo*.tcl # make and run the selected tests -# make -fek-tm4c123gxl.mak HOST=localhost:7705 # connect to host:port -# make -fek-tm4c123gxl.mak norun # only make but not run the tests -# make -fek-tm4c123gxl.mak clean # cleanup the build +# make -f make_tm4c123 # make and run the tests in the current directory +# make -f make_tm4c123 TESTS=philo*.tcl # make and run the selected tests +# make -f make_tm4c123 SCRIPT=py # make and run the Python tests +# make -f make_tm4c123 HOST=localhost:7705 # connect to host:port +# make -f make_tm4c123 norun # only make but not run the tests +# make -f make_tm4c123 clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -46,32 +47,34 @@ # #----------------------------------------------------------------------------- -# project name, binary output directory +# project name, target name, target directory: # -PROJECT := test_qmsm -TARGET := ek-tm4c123gxl +PROJECT := test_mock +TARGET := tm4c123 +TARGET_DIR := ..\..\target_tm4c123 #----------------------------------------------------------------------------- -# project directories +# project directories: # -# location of the QP/C framework (if not provided in an environemnt var.) +# location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../.. +QPC := ../../../.. endif -# location of the QTOOLS directory (if not provided in an environemnt var.) -ifeq ($(QTOOLS),) -QTOOLS := c:/qp/qtools -endif - - # QP port used in this project QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + # list of all source directories used by this project -VPATH = \ - ../$(TARGET) \ +VPATH := . \ + ../src \ + $(TARGET_DIR) \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ @@ -79,9 +82,9 @@ VPATH = \ $(QPC)/3rd_party/ek-tm4c123gxl/gnu # list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I../$(TARGET) \ +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ -I$(QPC)/include \ -I$(QPC)/src \ -I$(QP_PORT_DIR) \ @@ -89,7 +92,7 @@ INCLUDES = \ -I$(QPC)/3rd_party/ek-tm4c123gxl #----------------------------------------------------------------------------- -# files +# project files: # # assembler source files @@ -97,8 +100,9 @@ ASM_SRCS := # C source files C_SRCS := \ - qmsmtst.c \ - test_qmsm.c \ + LedBar.c \ + spy_Led.c \ + test_LedBar.c \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c @@ -106,7 +110,7 @@ C_SRCS := \ CPP_SRCS := OUTPUT := $(PROJECT) -LD_SCRIPT := ../$(TARGET)/test.ld +LD_SCRIPT := $(TARGET_DIR)/test.ld QP_SRCS := \ qep_hsm.c \ @@ -120,6 +124,7 @@ QP_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ @@ -171,7 +176,7 @@ BIN := $(GNU_ARM)/bin/arm-eabi-objcopy # location of the LMFlash utility on your machine # ifeq ($(LMFLASH),) -LMFLASH := LMFlash.exe +FLASH := LMFlash.exe -q ek-tm4c123gxl endif @@ -183,8 +188,12 @@ endif MKDIR := mkdir RM := rm -TCLSH := tclsh -QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl + +ifeq ($(SCRIPT),py) +QUTEST := python -m qspypy.qutest +else +QUTEST := tclsh $(QTOOLS)/qspy/tcl/qutest.tcl +endif #----------------------------------------------------------------------------- # build options @@ -194,15 +203,15 @@ QUTEST := $(QTOOLS)/qspy/tcl/qutest.tcl C_SRCS += $(QP_SRCS) ASM_SRCS += $(QP_ASMS) -BIN_DIR := $(TARGET) +BIN_DIR := build_$(TARGET) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST -CPPFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST @@ -242,23 +251,27 @@ all : $(TARGET_BIN) run endif ifeq (, $(TESTS)) +ifeq ($(SCRIPT),py) +TESTS := *.py +else TESTS := *.tcl endif +endif $(TARGET_BIN) : $(TARGET_ELF) $(BIN) -O binary $< $@ - $(LMFLASH) -q ek-tm4c123gxl $@ + $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : - $(LMFLASH) -q ek-tm4c123gxl $(TARGET_BIN) + $(FLASH) $(TARGET_BIN) run : $(TARGET_BIN) - $(LMFLASH) -q ek-tm4c123gxl -c $(TARGET_BIN) - $(TCLSH) $(QUTEST) $(TESTS) "" $(HOST) + $(FLASH) -c $< + $(QUTEST) $(TESTS) $(TARGET_EXE) $(HOST) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/qutest/unity_mock/test_qutest/spy_Led.c b/examples/qutest/unity_mock/test_qutest/spy_Led.c new file mode 100644 index 00000000..744bcc9a --- /dev/null +++ b/examples/qutest/unity_mock/test_qutest/spy_Led.c @@ -0,0 +1,82 @@ +/***************************************************************************** +* Purpose: example QUTEST "spy" test double implementation +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-11 +* +* 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 "qpc.h" /* QUTest interface */ +#include "Led.h" /* original interface */ + +//Q_DEFINE_THIS_FILE + +enum { + LED_MOD = QS_USER1 /* QS app-specific record for the LED module */ +}; + +static uint32_t led_power[MAX_LED] = { + 10, 20, 10, 20, 10 +}; + +/*--------------------------------------------------------------------------*/ +void Led_DICTIONARY(void) { + QS_FUN_DICTIONARY(&Led_on); + QS_FUN_DICTIONARY(&Led_off); + QS_USR_DICTIONARY(LED_MOD); + QS_OBJ_DICTIONARY(&led_power); +} + +/*--------------------------------------------------------------------------*/ +/* turns a given LED off */ +void Led_off(uint8_t index) { + QS_BEGIN(LED_MOD, (void *)0) /* user-specific record */ + QS_FUN(&Led_off); /* function called */ + QS_U8 (0, index); /* parameter */ + QS_END() +} + +/* turns a given LED on and retruns the power drawn by it in uW */ +uint32_t Led_on(uint8_t index) { + QS_TEST_PROBE_DEF(&Led_on) + uint32_t ret = led_power[index]; /* assume */ + + /* tweak the returned power draw from the test probe */ + QS_TEST_PROBE( + ret = (uint32_t)qs_tp_; + ) + + QS_BEGIN(LED_MOD, (void *)0) /* user-specific record */ + QS_FUN(&Led_on); /* function called */ + QS_U32(0, ret); /* value returned */ + QS_U8 (0, index); /* parameter */ + QS_END() + + return ret; +} + diff --git a/examples/qutest/qhsmtst/test_qhsm.c b/examples/qutest/unity_mock/test_qutest/test_LedBar.c similarity index 62% rename from examples/qutest/qhsmtst/test_qhsm.c rename to examples/qutest/unity_mock/test_qutest/test_LedBar.c index f04e7583..8995d992 100644 --- a/examples/qutest/qhsmtst/test_qhsm.c +++ b/examples/qutest/unity_mock/test_qutest/test_LedBar.c @@ -1,11 +1,11 @@ /***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 6.3.1 -* Date of the Last Update: 2018-05-21 +* Purpose: example QUTEST fixture for the mock example from Unity +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-11 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -31,46 +31,30 @@ * https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ -#include "qpc.h" -#include "qhsmtst.h" +#include "qpc.h" /* QUTest interface */ +#include "LedBar.h" /* CUT interface */ Q_DEFINE_THIS_FILE -enum { - BSP_DISPLAY = QS_USER, -}; +/*--------------------------------------------------------------------------*/ +void Led_DICTIONARY(void); /* dictionaries for the Led "spy " test double */ /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ - QF_init(); /* initialize the framework */ + QF_init(); /* initialize the framework */ /* initialize the QS software tracing */ Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* dictionaries... */ - QS_FUN_DICTIONARY(&QHsm_top); - QS_OBJ_DICTIONARY(the_hsm); - QS_USR_DICTIONARY(BSP_DISPLAY); + Led_DICTIONARY(); + QS_FUN_DICTIONARY(&LedBar_setPercent); - QHsmTst_ctor(); /* instantiate the QHsmTst object */ + /* filter setup... */ + QS_FILTER_ON(QS_ALL_RECORDS); - return QF_run(); -} - -/*--------------------------------------------------------------------------*/ -void BSP_display(char const *msg) { - QS_BEGIN(BSP_DISPLAY, (void *)0) /* application-specific record */ - QS_STR(msg); - QS_END() -} - -/*..........................................................................*/ -void BSP_exit(void) { + return QF_run(); /* run the tests */ } /*--------------------------------------------------------------------------*/ @@ -79,37 +63,45 @@ void QS_onTestSetup(void) { /*..........................................................................*/ void QS_onTestTeardown(void) { } + /*..........................................................................*/ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)param1; + switch (cmdId) { + case 0: { /* call the CUT: LedBar_setPercent */ + uint32_t ret = LedBar_setPercent((uint8_t)param1); + QS_BEGIN(QS_USER + cmdId, (void *)0) /* user-specific record */ + QS_FUN(&LedBar_setPercent); /* function called */ + QS_U32(0, ret); /* value returned */ + QS_U8 (0, (uint8_t)param1); /* parameter */ + QS_END() + break; + } + default: + break; + } + + /* unused parametrers... */ + //(void)param1; (void)param2; (void)param3; - - //printf(" Command id=%d param=%d\n", (int)cmdId, (int)param); - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } } - /*..........................................................................*/ +/* host callback function to "massage" the event, if necessary */ +void QS_onTestEvt(QEvt *e) { + (void)e; #ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ - -/*! host callback function to "massage" the event, if necessary */ -void QS_onTestEvt(QEvt *e) { - (void)e; -} - #else /* this test is compiled for an embedded Target system */ - -void QS_onTestEvt(QEvt *e) { - (void)e; -} - #endif - +} +/*..........................................................................*/ +/*! callback function to output the posted QP events (not used here) */ +void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status) +{ + (void)sender; + (void)recipient; + (void)e; + (void)status; +} diff --git a/examples/qutest/unity_mock/test_qutest/test_LedBar.py b/examples/qutest/unity_mock/test_qutest/test_LedBar.py new file mode 100644 index 00000000..24ee9b8e --- /dev/null +++ b/examples/qutest/unity_mock/test_qutest/test_LedBar.py @@ -0,0 +1,89 @@ +# QUTEST test script corresponding to the test_LedBar.c test fixture. +# see https://www.state-machine.com/qtools/qutest.html + +import sys +import pytest +import struct +from qspypy.qspy import * + +# preambe... + +# tests... + +def test_LedBar_0_percent_all_off(qutest): + qutest.command(0, 0) + qutest.expect("%timestamp LED_MOD Led_off 0") + qutest.expect("%timestamp LED_MOD Led_off 1") + qutest.expect("%timestamp LED_MOD Led_off 2") + qutest.expect("%timestamp LED_MOD Led_off 3") + qutest.expect("%timestamp LED_MOD Led_off 4") + qutest.expect("%timestamp USER+000 LedBar_setPercent 0 0") + qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") + +def test_LedBar_100_percent_all_on(qutest_noreset): + qutest = qutest_noreset # name change + qutest.command(0, 100) + qutest.expect("%timestamp LED_MOD Led_on 10 0") + qutest.expect("%timestamp LED_MOD Led_on 20 1") + qutest.expect("%timestamp LED_MOD Led_on 10 2") + qutest.expect("%timestamp LED_MOD Led_on 20 3") + qutest.expect("%timestamp LED_MOD Led_on 10 4") + qutest.expect("%timestamp USER+000 LedBar_setPercent 70 100") + qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") + +def test_LedBar_19_percent_all_off(qutest_noreset): + qutest = qutest_noreset # name change + qutest.command(0, 19) + qutest.expect("%timestamp LED_MOD Led_off 0") + qutest.expect("%timestamp LED_MOD Led_off 1") + qutest.expect("%timestamp LED_MOD Led_off 2") + qutest.expect("%timestamp LED_MOD Led_off 3") + qutest.expect("%timestamp LED_MOD Led_off 4") + qutest.expect("%timestamp USER+000 LedBar_setPercent 0 19") + qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") + +def test_LedBar_20_percent_one_on(qutest_noreset): + qutest = qutest_noreset # name change + qutest.command(0, 20) + qutest.expect("%timestamp LED_MOD Led_on 10 0") + qutest.expect("%timestamp LED_MOD Led_off 1") + qutest.expect("%timestamp LED_MOD Led_off 2") + qutest.expect("%timestamp LED_MOD Led_off 3") + qutest.expect("%timestamp LED_MOD Led_off 4") + qutest.expect("%timestamp USER+000 LedBar_setPercent 10 20") + qutest.expect("%timestamp Trg-Done QS_RX_COMMAND") + +def test_LedBar_50_percent_two_on(qutest_noreset): + qutest = qutest_noreset # name change + qutest.current_obj(QS_OBJ_KIND.AP, 'led_power') + qutest.poke(0, 4, struct.pack(' $@ @@ -219,13 +210,11 @@ endif clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.map \ $(TARGET_EXE) show : @echo PROJECT = $(PROJECT) @echo TARGET_EXE = $(TARGET_EXE) - @echo CONF = $(CONF) @echo VPATH = $(VPATH) @echo C_SRCS = $(C_SRCS) @echo CPP_SRCS = $(CPP_SRCS) diff --git a/examples/qutest/unity_mock/test_unity/MockLed.c b/examples/qutest/unity_mock/test_unity/MockLed.c new file mode 100644 index 00000000..41d223f7 --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/MockLed.c @@ -0,0 +1,123 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#include +#include +#include +#include "unity.h" +#include "cmock.h" +#include "MockLed.h" + +static const char* CMockString_Led_off = "Led_off"; +static const char* CMockString_Led_on = "Led_on"; +static const char* CMockString_index = "index"; + +typedef struct _CMOCK_Led_on_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + uint32_t ReturnVal; + uint8_t Expected_index; + +} CMOCK_Led_on_CALL_INSTANCE; + +typedef struct _CMOCK_Led_off_CALL_INSTANCE +{ + UNITY_LINE_TYPE LineNumber; + uint8_t Expected_index; + +} CMOCK_Led_off_CALL_INSTANCE; + +static struct MockLedInstance +{ + CMOCK_MEM_INDEX_TYPE Led_on_CallInstance; + CMOCK_MEM_INDEX_TYPE Led_off_CallInstance; +} Mock; + +extern jmp_buf AbortFrame; + +void MockLed_Verify(void) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + UNITY_SET_DETAIL(CMockString_Led_on); + UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.Led_on_CallInstance, cmock_line, CMockStringCalledLess); + UNITY_SET_DETAIL(CMockString_Led_off); + UNITY_TEST_ASSERT(CMOCK_GUTS_NONE == Mock.Led_off_CallInstance, cmock_line, CMockStringCalledLess); +} + +void MockLed_Init(void) +{ + MockLed_Destroy(); +} + +void MockLed_Destroy(void) +{ + CMock_Guts_MemFreeAll(); + memset(&Mock, 0, sizeof(Mock)); +} + +uint32_t Led_on(uint8_t index) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_Led_on_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_Led_on); + cmock_call_instance = (CMOCK_Led_on_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.Led_on_CallInstance); + Mock.Led_on_CallInstance = CMock_Guts_MemNext(Mock.Led_on_CallInstance); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + { + UNITY_SET_DETAILS(CMockString_Led_on,CMockString_index); + UNITY_TEST_ASSERT_EQUAL_HEX8(cmock_call_instance->Expected_index, index, cmock_line, CMockStringMismatch); + } + UNITY_CLR_DETAILS(); + return cmock_call_instance->ReturnVal; +} + +void CMockExpectParameters_Led_on(CMOCK_Led_on_CALL_INSTANCE* cmock_call_instance, uint8_t index) +{ + cmock_call_instance->Expected_index = index; +} + +void Led_on_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint8_t index, uint32_t cmock_to_return) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Led_on_CALL_INSTANCE)); + CMOCK_Led_on_CALL_INSTANCE* cmock_call_instance = (CMOCK_Led_on_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.Led_on_CallInstance = CMock_Guts_MemChain(Mock.Led_on_CallInstance, cmock_guts_index); + cmock_call_instance->LineNumber = cmock_line; + CMockExpectParameters_Led_on(cmock_call_instance, index); + cmock_call_instance->ReturnVal = cmock_to_return; + UNITY_CLR_DETAILS(); +} + +void Led_off(uint8_t index) +{ + UNITY_LINE_TYPE cmock_line = TEST_LINE_NUM; + CMOCK_Led_off_CALL_INSTANCE* cmock_call_instance; + UNITY_SET_DETAIL(CMockString_Led_off); + cmock_call_instance = (CMOCK_Led_off_CALL_INSTANCE*)CMock_Guts_GetAddressFor(Mock.Led_off_CallInstance); + Mock.Led_off_CallInstance = CMock_Guts_MemNext(Mock.Led_off_CallInstance); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringCalledMore); + cmock_line = cmock_call_instance->LineNumber; + { + UNITY_SET_DETAILS(CMockString_Led_off,CMockString_index); + UNITY_TEST_ASSERT_EQUAL_HEX8(cmock_call_instance->Expected_index, index, cmock_line, CMockStringMismatch); + } + UNITY_CLR_DETAILS(); +} + +void CMockExpectParameters_Led_off(CMOCK_Led_off_CALL_INSTANCE* cmock_call_instance, uint8_t index) +{ + cmock_call_instance->Expected_index = index; +} + +void Led_off_CMockExpect(UNITY_LINE_TYPE cmock_line, uint8_t index) +{ + CMOCK_MEM_INDEX_TYPE cmock_guts_index = CMock_Guts_MemNew(sizeof(CMOCK_Led_off_CALL_INSTANCE)); + CMOCK_Led_off_CALL_INSTANCE* cmock_call_instance = (CMOCK_Led_off_CALL_INSTANCE*)CMock_Guts_GetAddressFor(cmock_guts_index); + UNITY_TEST_ASSERT_NOT_NULL(cmock_call_instance, cmock_line, CMockStringOutOfMemory); + memset(cmock_call_instance, 0, sizeof(*cmock_call_instance)); + Mock.Led_off_CallInstance = CMock_Guts_MemChain(Mock.Led_off_CallInstance, cmock_guts_index); + cmock_call_instance->LineNumber = cmock_line; + CMockExpectParameters_Led_off(cmock_call_instance, index); + UNITY_CLR_DETAILS(); +} + diff --git a/examples/qutest/unity_mock/test_unity/MockLed.h b/examples/qutest/unity_mock/test_unity/MockLed.h new file mode 100644 index 00000000..b8cb26d5 --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/MockLed.h @@ -0,0 +1,38 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ +#ifndef _MOCKLED_H +#define _MOCKLED_H + +#include +#include "Led.h" + +/* Ignore the following warnings, since we are copying code */ +#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) +#pragma GCC diagnostic push +#endif +#if !defined(__clang__) +#pragma GCC diagnostic ignored "-Wpragmas" +#endif +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wduplicate-decl-specifier" +#endif + +void MockLed_Init(void); +void MockLed_Destroy(void); +void MockLed_Verify(void); + + + + +#define Led_on_ExpectAndReturn(index, cmock_retval) Led_on_CMockExpectAndReturn(__LINE__, index, cmock_retval) +void Led_on_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, uint8_t index, uint32_t cmock_to_return); +#define Led_off_Expect(index) Led_off_CMockExpect(__LINE__, index) +void Led_off_CMockExpect(UNITY_LINE_TYPE cmock_line, uint8_t index); + +#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) +#pragma GCC diagnostic pop +#endif +#endif + +#endif diff --git a/examples/qutest/unity_mock/test_unity/TestLedBar.c b/examples/qutest/unity_mock/test_unity/TestLedBar.c new file mode 100644 index 00000000..9e74bcbb --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/TestLedBar.c @@ -0,0 +1,87 @@ +#include +#include "LedBar.h" +#include "unity.h" +#include "MockLed.h" + +void setUp(void) +{ + /* This is run before EACH TEST */ +} + +void tearDown(void) +{ + /* This is run after EACH TEST */ +} + +void test_LedBar_0_percent_all_off(void) +{ + Led_off_Expect(0); + Led_off_Expect(1); + Led_off_Expect(2); + Led_off_Expect(3); + Led_off_Expect(4); + + LedBar_setPercent(0); +} + +void test_LedBar_100_percent_all_on(void) +{ + Led_on_ExpectAndReturn(0, 10); + Led_on_ExpectAndReturn(1, 20); + Led_on_ExpectAndReturn(2, 10); + Led_on_ExpectAndReturn(3, 20); + Led_on_ExpectAndReturn(4, 10); + + TEST_ASSERT_EQUAL(70, LedBar_setPercent(100)); +} + +void test_LedBar_19_percent_all_off(void) +{ + Led_off_Expect(0); + Led_off_Expect(1); + Led_off_Expect(2); + Led_off_Expect(3); + Led_off_Expect(4); + + TEST_ASSERT_EQUAL(0, LedBar_setPercent(19)); +} + +void test_LedBar_20_percent_one_on(void) +{ + Led_on_ExpectAndReturn(0, 10); + Led_off_Expect(1); + Led_off_Expect(2); + Led_off_Expect(3); + Led_off_Expect(4); + + TEST_ASSERT_EQUAL(10, LedBar_setPercent(20)); +} + +void test_LedBar_50_percent_two_on(void) +{ + Led_on_ExpectAndReturn(0, 23); + Led_on_ExpectAndReturn(1, 17); + Led_off_Expect(2); + Led_off_Expect(3); + Led_off_Expect(4); + + TEST_ASSERT_EQUAL(40, LedBar_setPercent(50)); +} + +void test_LedBar_99_percent_four_on(void) +{ + Led_on_ExpectAndReturn(0, 10); + Led_on_ExpectAndReturn(1, 20); + Led_on_ExpectAndReturn(2, 10); + Led_on_ExpectAndReturn(3, 20); + Led_off_Expect(4); + + TEST_ASSERT_EQUAL(60, LedBar_setPercent(99)); +} + + +/* NOTE: +* The Mock example requires a specific "test runner", which +* is provided in the file TestLedBar_Runner.c. +*/ + diff --git a/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c b/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c new file mode 100644 index 00000000..01895039 --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c @@ -0,0 +1,107 @@ +/* AUTOGENERATED FILE. DO NOT EDIT. */ + +/*=======Test Runner Used To Run Each Test Below=====*/ +#define RUN_TEST(TestFunc, TestLineNum) \ +{ \ + Unity.CurrentTestName = #TestFunc; \ + Unity.CurrentTestLineNumber = TestLineNum; \ + Unity.NumberOfTests++; \ + CMock_Init(); \ + UNITY_CLR_DETAILS(); \ + if (TEST_PROTECT()) \ + { \ + setUp(); \ + TestFunc(); \ + } \ + if (TEST_PROTECT()) \ + { \ + tearDown(); \ + CMock_Verify(); \ + } \ + CMock_Destroy(); \ + UnityConcludeTest(); \ +} + +/*=======Automagically Detected Files To Include=====*/ +#ifdef __WIN32__ +#define UNITY_INCLUDE_SETUP_STUBS +#endif +#include "unity.h" +#include "cmock.h" +#include +#include +#include +#include "LedBar.h" +#include +#include "MockLed.h" + +/*=======External Functions This Runner Calls=====*/ +extern void setUp(void); +extern void tearDown(void); +extern void test_LedBar_0_percent_all_off(void); +extern void test_LedBar_100_percent_all_on(void); +extern void test_LedBar_19_percent_all_off(void); +extern void test_LedBar_20_percent_one_on(void); +extern void test_LedBar_50_percent_two_on(void); +extern void test_LedBar_99_percent_four_on(void); + + +/*=======Mock Management=====*/ +static void CMock_Init(void) +{ + MockLed_Init(); +} +static void CMock_Verify(void) +{ + MockLed_Verify(); +} +static void CMock_Destroy(void) +{ + MockLed_Destroy(); +} + +/*=======Suite Setup=====*/ +static void suite_setup(void) +{ +#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA) + suiteSetUp(); +#endif +} + +/*=======Suite Teardown=====*/ +static int suite_teardown(int num_failures) +{ +#if defined(UNITY_WEAK_ATTRIBUTE) || defined(UNITY_WEAK_PRAGMA) + return suiteTearDown(num_failures); +#else + return num_failures; +#endif +} + +/*=======Test Reset Option=====*/ +void resetTest(void); +void resetTest(void) +{ + CMock_Verify(); + CMock_Destroy(); + tearDown(); + CMock_Init(); + setUp(); +} + + +/*=======MAIN=====*/ +int main(void) +{ + suite_setup(); + UnityBegin("test/TestLedBar.c"); + RUN_TEST(test_LedBar_0_percent_all_off, 16); + RUN_TEST(test_LedBar_100_percent_all_on, 27); + RUN_TEST(test_LedBar_19_percent_all_off, 38); + RUN_TEST(test_LedBar_20_percent_one_on, 49); + RUN_TEST(test_LedBar_50_percent_two_on, 60); + RUN_TEST(test_LedBar_99_percent_four_on, 71); + + CMock_Guts_MemFreeFinal(); + return suite_teardown(UnityEnd()); +} diff --git a/examples/qutest/unity_mock/test_unity/cmock/cmock.c b/examples/qutest/unity_mock/test_unity/cmock/cmock.c new file mode 100644 index 00000000..318f4c7a --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/cmock/cmock.c @@ -0,0 +1,210 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#include "unity.h" +#include "cmock.h" + +//public constants to be used by mocks +const char* CMockStringOutOfMemory = "CMock has run out of memory. Please allocate more."; +const char* CMockStringCalledMore = "Called more times than expected."; +const char* CMockStringCalledLess = "Called less times than expected."; +const char* CMockStringCalledEarly = "Called earlier than expected."; +const char* CMockStringCalledLate = "Called later than expected."; +const char* CMockStringCallOrder = "Called out of order."; +const char* CMockStringIgnPreExp = "IgnoreArg called before Expect."; +const char* CMockStringPtrPreExp = "ReturnThruPtr called before Expect."; +const char* CMockStringPtrIsNULL = "Pointer is NULL."; +const char* CMockStringExpNULL = "Expected NULL."; +const char* CMockStringMismatch = "Function called with unexpected argument value."; + +//private variables +#ifdef CMOCK_MEM_DYNAMIC +static unsigned char* CMock_Guts_Buffer = NULL; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr; +#else +static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferArray[(CMOCK_MEM_SIZE + CMOCK_MEM_INDEX_SIZE - 1) / CMOCK_MEM_INDEX_SIZE]; +#define CMock_Guts_Buffer ((unsigned char*)CMock_Guts_BufferArray) +static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE; +static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr; +#endif + +//------------------------------------------------------- +// CMock_Guts_MemNew +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size) +{ + CMOCK_MEM_INDEX_TYPE index; + + //verify arguments valid (we must be allocating space for at least 1 byte, and the existing chain must be in memory somewhere) + if (size < 1) + return CMOCK_GUTS_NONE; + + //verify we have enough room + size = size + CMOCK_MEM_INDEX_SIZE; + if (size & CMOCK_MEM_ALIGN_MASK) + size = (size + CMOCK_MEM_ALIGN_MASK) & ~CMOCK_MEM_ALIGN_MASK; + if ((CMock_Guts_BufferSize - CMock_Guts_FreePtr) < size) + { +#ifndef CMOCK_MEM_DYNAMIC + return CMOCK_GUTS_NONE; // nothing we can do; our static buffer is out of memory +#else + // our dynamic buffer does not have enough room; request more via realloc() + CMOCK_MEM_INDEX_TYPE new_buffersize = CMock_Guts_BufferSize + CMOCK_MEM_SIZE + size; + unsigned char* new_buffer = realloc(CMock_Guts_Buffer, (size_t)new_buffersize); + if (new_buffer == NULL) + return CMOCK_GUTS_NONE; // realloc() failed; out of memory + CMock_Guts_Buffer = new_buffer; + CMock_Guts_BufferSize = new_buffersize; +#endif + } + + //determine where we're putting this new block, and init its pointer to be the end of the line + index = CMock_Guts_FreePtr + CMOCK_MEM_INDEX_SIZE; + *(CMOCK_MEM_INDEX_TYPE*)(&CMock_Guts_Buffer[CMock_Guts_FreePtr]) = CMOCK_GUTS_NONE; + CMock_Guts_FreePtr += size; + + return index; +} + +//------------------------------------------------------- +// CMock_Guts_MemChain +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index) +{ + CMOCK_MEM_INDEX_TYPE index; + void* root; + void* obj; + void* next; + + if (root_index == CMOCK_GUTS_NONE) + { + //if there is no root currently, we return this object as the root of the chain + return obj_index; + } + else + { + //reject illegal nodes + if ((root_index < CMOCK_MEM_ALIGN_SIZE) || (root_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + if ((obj_index < CMOCK_MEM_ALIGN_SIZE) || (obj_index >= CMock_Guts_FreePtr)) + { + return CMOCK_GUTS_NONE; + } + + root = (void*)(&CMock_Guts_Buffer[root_index]); + obj = (void*)(&CMock_Guts_Buffer[obj_index]); + + //find the end of the existing chain and add us + next = root; + do { + index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE); + if (index >= CMock_Guts_FreePtr) + return CMOCK_GUTS_NONE; + if (index > 0) + next = (void*)(&CMock_Guts_Buffer[index]); + } while (index > 0); + *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE) = (CMOCK_MEM_INDEX_TYPE)((CMOCK_MEM_PTR_AS_INT)obj - (CMOCK_MEM_PTR_AS_INT)CMock_Guts_Buffer); + return root_index; + } +} + +//------------------------------------------------------- +// CMock_Guts_MemNext +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index) +{ + CMOCK_MEM_INDEX_TYPE index; + void* previous_item; + + //There is nothing "next" if the pointer isn't from our buffer + if ((previous_item_index < CMOCK_MEM_ALIGN_SIZE) || (previous_item_index >= CMock_Guts_FreePtr)) + return CMOCK_GUTS_NONE; + previous_item = (void*)(&CMock_Guts_Buffer[previous_item_index]); + + //if the pointer is good, then use it to look up the next index + //(we know the first element always goes in zero, so NEXT must always be > 1) + index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)previous_item - CMOCK_MEM_INDEX_SIZE); + if ((index > 1) && (index < CMock_Guts_FreePtr)) + return index; + else + return CMOCK_GUTS_NONE; +} + +//------------------------------------------------------- +// CMock_Guts_MemEndOfChain +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index) +{ + CMOCK_MEM_INDEX_TYPE index = root_index; + CMOCK_MEM_INDEX_TYPE next_index; + + for (next_index = root_index; + next_index != CMOCK_GUTS_NONE; + next_index = CMock_Guts_MemNext(index)) + { + index = next_index; + } + + return index; +} + +//------------------------------------------------------- +// CMock_GetAddressFor +//------------------------------------------------------- +void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index) +{ + if ((index >= CMOCK_MEM_ALIGN_SIZE) && (index < CMock_Guts_FreePtr)) + { + return (void*)(&CMock_Guts_Buffer[index]); + } + else + { + return NULL; + } +} + +//------------------------------------------------------- +// CMock_Guts_MemBytesFree +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void) +{ + return CMock_Guts_BufferSize - CMock_Guts_FreePtr; +} + +//------------------------------------------------------- +// CMock_Guts_MemBytesUsed +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void) +{ + return CMock_Guts_FreePtr - CMOCK_MEM_ALIGN_SIZE; +} + +//------------------------------------------------------- +// CMock_Guts_MemFreeAll +//------------------------------------------------------- +void CMock_Guts_MemFreeAll(void) +{ + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; //skip the very beginning +} + +//------------------------------------------------------- +// CMock_Guts_MemFreeFinal +//------------------------------------------------------- +void CMock_Guts_MemFreeFinal(void) +{ + CMock_Guts_FreePtr = CMOCK_MEM_ALIGN_SIZE; +#ifdef CMOCK_MEM_DYNAMIC + if (CMock_Guts_Buffer) + { + free(CMock_Guts_Buffer); + CMock_Guts_Buffer = NULL; + } +#endif +} + diff --git a/examples/qutest/unity_mock/test_unity/cmock/cmock.h b/examples/qutest/unity_mock/test_unity/cmock/cmock.h new file mode 100644 index 00000000..a3134480 --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/cmock/cmock.h @@ -0,0 +1,38 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef CMOCK_FRAMEWORK_H +#define CMOCK_FRAMEWORK_H + +#include "cmock_internals.h" + +//should be big enough to index full range of CMOCK_MEM_MAX +#ifndef CMOCK_MEM_INDEX_TYPE +#define CMOCK_MEM_INDEX_TYPE unsigned int +#endif + +#define CMOCK_GUTS_NONE (0) + +#define CMOCK_ARG_MODE CMOCK_MEM_INDEX_TYPE +#define CMOCK_ARG_ALL 0 +#define CMOCK_ARG_NONE ((CMOCK_MEM_INDEX_TYPE)(~0U)) + +//------------------------------------------------------- +// Memory API +//------------------------------------------------------- +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNew(CMOCK_MEM_INDEX_TYPE size); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemChain(CMOCK_MEM_INDEX_TYPE root_index, CMOCK_MEM_INDEX_TYPE obj_index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemNext(CMOCK_MEM_INDEX_TYPE previous_item_index); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemEndOfChain(CMOCK_MEM_INDEX_TYPE root_index); + +void* CMock_Guts_GetAddressFor(CMOCK_MEM_INDEX_TYPE index); + +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesFree(void); +CMOCK_MEM_INDEX_TYPE CMock_Guts_MemBytesUsed(void); +void CMock_Guts_MemFreeAll(void); +void CMock_Guts_MemFreeFinal(void); + +#endif //CMOCK_FRAMEWORK diff --git a/examples/qutest/unity_mock/test_unity/cmock/cmock_internals.h b/examples/qutest/unity_mock/test_unity/cmock/cmock_internals.h new file mode 100644 index 00000000..5c922adf --- /dev/null +++ b/examples/qutest/unity_mock/test_unity/cmock/cmock_internals.h @@ -0,0 +1,89 @@ +/* ========================================== + CMock Project - Automatic Mock Generation for C + Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef CMOCK_FRAMEWORK_INTERNALS_H +#define CMOCK_FRAMEWORK_INTERNALS_H + +//These are constants that the generated mocks have access to +extern const char* CMockStringOutOfMemory; +extern const char* CMockStringCalledMore; +extern const char* CMockStringCalledLess; +extern const char* CMockStringCalledEarly; +extern const char* CMockStringCalledLate; +extern const char* CMockStringCallOrder; +extern const char* CMockStringIgnPreExp; +extern const char* CMockStringPtrPreExp; +extern const char* CMockStringPtrIsNULL; +extern const char* CMockStringExpNULL; +extern const char* CMockStringMismatch; + +//define CMOCK_MEM_DYNAMIC to grab memory as needed with malloc +//when you do that, CMOCK_MEM_SIZE is used for incremental size instead of total +#ifdef CMOCK_MEM_STATIC +#undef CMOCK_MEM_DYNAMIC +#endif + +#ifdef CMOCK_MEM_DYNAMIC +#include +#endif + +//this is used internally during pointer arithmetic. make sure this type is the same size as the target's pointer type +#ifndef CMOCK_MEM_PTR_AS_INT +#ifdef UNITY_POINTER_WIDTH +#ifdef UNITY_INT_WIDTH +#if UNITY_POINTER_WIDTH == UNITY_INT_WIDTH +#define CMOCK_MEM_PTR_AS_INT unsigned int +#endif +#endif +#endif +#endif + +#ifndef CMOCK_MEM_PTR_AS_INT +#ifdef UNITY_POINTER_WIDTH +#ifdef UNITY_LONG_WIDTH +#if UNITY_POINTER_WIDTH == UNITY_LONG_WIDTH +#define CMOCK_MEM_PTR_AS_INT unsigned long +#endif +#if UNITY_POINTER_WIDTH > UNITY_LONG_WIDTH +#define CMOCK_MEM_PTR_AS_INT unsigned long long +#endif +#endif +#endif +#endif + +#ifndef CMOCK_MEM_PTR_AS_INT +#define CMOCK_MEM_PTR_AS_INT unsigned long +#endif + +//0 for no alignment, 1 for 16-bit, 2 for 32-bit, 3 for 64-bit +#ifndef CMOCK_MEM_ALIGN + #ifdef UNITY_LONG_WIDTH + #if (UNITY_LONG_WIDTH == 16) + #define CMOCK_MEM_ALIGN (1) + #elif (UNITY_LONG_WIDTH == 32) + #define CMOCK_MEM_ALIGN (2) + #elif (UNITY_LONG_WIDTH == 64) + #define CMOCK_MEM_ALIGN (3) + #else + #define CMOCK_MEM_ALIGN (2) + #endif + #else + #define CMOCK_MEM_ALIGN (2) + #endif +#endif + +//amount of memory to allow cmock to use in its internal heap +#ifndef CMOCK_MEM_SIZE +#define CMOCK_MEM_SIZE (32768) +#endif + +//automatically calculated defs for easier reading +#define CMOCK_MEM_ALIGN_SIZE (CMOCK_MEM_INDEX_TYPE)(1u << CMOCK_MEM_ALIGN) +#define CMOCK_MEM_ALIGN_MASK (CMOCK_MEM_INDEX_TYPE)(CMOCK_MEM_ALIGN_SIZE - 1) +#define CMOCK_MEM_INDEX_SIZE (CMOCK_MEM_INDEX_TYPE)(CMOCK_MEM_PTR_AS_INT)((sizeof(CMOCK_MEM_INDEX_TYPE) > CMOCK_MEM_ALIGN_SIZE) ? sizeof(CMOCK_MEM_INDEX_TYPE) : CMOCK_MEM_ALIGN_SIZE) + + +#endif //CMOCK_FRAMEWORK_INTERNALS diff --git a/examples/ti-rtos/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/ti-rtos/arm-cm/dpp_ek-tm4c123gxl/main.c index ce944f4f..b7649be0 100644 --- a/examples/ti-rtos/arm-cm/dpp_ek-tm4c123gxl/main.c +++ b/examples/ti-rtos/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -49,15 +49,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/ucos-ii/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/ucos-ii/arm-cm/dpp_ek-tm4c123gxl/main.c index ab7373a9..18f31837 100644 --- a/examples/ucos-ii/arm-cm/dpp_ek-tm4c123gxl/main.c +++ b/examples/ucos-ii/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -54,15 +54,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* init publish-subscribe */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/ucos-ii/arm-cm/dpp_nucleo-l152re/main.c b/examples/ucos-ii/arm-cm/dpp_nucleo-l152re/main.c index f1300559..8c950946 100644 --- a/examples/ucos-ii/arm-cm/dpp_nucleo-l152re/main.c +++ b/examples/ucos-ii/arm-cm/dpp_nucleo-l152re/main.c @@ -54,15 +54,6 @@ int main() { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* init publish-subscribe */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/win32-qv/README.url b/examples/win32-qv/README.url deleted file mode 100644 index 96043037..00000000 --- a/examples/win32-qv/README.url +++ /dev/null @@ -1,3 +0,0 @@ -[InternetShortcut] -URL=http://www.state-machine.com/qpc/exa_win32-qv.html -IconFile=http://www.state-machine.com/qp.ico diff --git a/examples/win32-qv/blinky/README.txt b/examples/win32-qv/blinky/README.txt deleted file mode 100644 index 1fb4aeac..00000000 --- a/examples/win32-qv/blinky/README.txt +++ /dev/null @@ -1,7 +0,0 @@ -The Win32 version of the "Blinky" example is now located in the directory: - -examples\arm-cm\blinky_ek-tm4c123gxl\win32-qv\ - -This co-location of the Win32 emulation with the embedded code running -on the actual board demonstrates better the "dual targeting" development -approach. \ No newline at end of file diff --git a/examples/win32-qv/dpp-gui/README.txt b/examples/win32-qv/dpp-gui/README.txt deleted file mode 100644 index a4fad98e..00000000 --- a/examples/win32-qv/dpp-gui/README.txt +++ /dev/null @@ -1,10 +0,0 @@ -The Win32-QV GUI emulation of the Dining Philosopers Problem (DPP) example -for the EFM32-SLSTK3401A board from Silicon Labs is now located in the -directory: - -examples\arm-cm\dpp_efm32-slstk3401a\win32-qv\ - - -This co-location of the Win32 emulation with the embedded code running -on the actual board demonstrates better the "dual targeting" development -approach. \ No newline at end of file diff --git a/examples/win32-qv/dpp/Makefile b/examples/win32-qv/dpp/Makefile deleted file mode 100644 index eec137e8..00000000 --- a/examples/win32-qv/dpp/Makefile +++ /dev/null @@ -1,261 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, DPP console, Win32-QV, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := dpp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qv - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32-qv/dpp/bsp.c b/examples/win32-qv/dpp/bsp.c deleted file mode 100644 index 8d1436af..00000000 --- a/examples/win32-qv/dpp/bsp.c +++ /dev/null @@ -1,244 +0,0 @@ - /***************************************************************************** -* Product: DPP example, Windows (console) -* Last updated for version 5.8.0 -* Last updated on 2016-11-29 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - static uint8_t l_running; - static uint8_t const l_clock_tick = 0U; -#endif - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - int ch = _getch(); - if (ch == '\33') { /* see if the ESC key pressed */ - BSP_terminate(0); - } - else if (ch == 'p') { - QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - } - else if (ch == 's') { - QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - } - } -} -/*..........................................................................*/ -void Q_onAssert(char const * const module, int_t loc) { - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - fprintf(stderr, "Assertion failed in %s, line %d", module, loc); - exit(-1); -} -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - - printf("Dining Philosophers Problem example" - "\nQP %s\n" - "Press 'p' to pause\n" - "Press 's' to serve\n" - "Press ESC to quit...\n", - QP_versionStr); - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : "")); - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -#ifdef Q_SPY - l_running = (uint8_t)0; /* stop the QS output thread */ -#endif - QF_stop(); /* stop the main "ticker thread" */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - printf("Philosopher %2d is %s\n", (int)n, stat); - - QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - printf("Paused is %s\n", paused ? "ON" : "OFF"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -#include "qspy.h" -#include - -#define WIN32_LEAN_AND_MEAN -#include /* Win32 API for multithreading */ - -static uint8_t l_running; - -/*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); - l_running = (uint8_t)1; - while (l_running) { - uint16_t nBytes = 256; - uint8_t const *block; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - if (block != (uint8_t *)0) { - QSPY_parse(block, nBytes); - } - Sleep(10U); /* wait for a clock tick */ - } - return 0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* 4K buffer for Quantum Spy */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - - /* here 'arg' is ignored, but this command-line parameter can be used - * to setup the QSP_config(), to set up the QS filters, or for any - * other purpose. - */ - (void)arg; - - QSPY_config(QP_VERSION, // version - QS_OBJ_PTR_SIZE, // objPtrSize - QS_FUN_PTR_SIZE, // funPtrSize - QS_TIME_SIZE, // tstampSize - Q_SIGNAL_SIZE, // sigSize, - QF_EVENT_SIZ_SIZE, // evtSize - QF_EQUEUE_CTR_SIZE, // queueCtrSize - QF_MPOOL_CTR_SIZE, // poolCtrSize - QF_MPOOL_SIZ_SIZE, // poolBlkSize - QF_TIMEEVT_CTR_SIZE,// tevtCtrSize - (void *)0, // matFile, - (void *)0, // mscFile - (QSPY_CustParseFun)0); // no customized parser function - - /* 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PHILO_STAT); - - return CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0; /* return the status of creating the idle thread */ -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - QSPY_stop(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - for (;;) { - uint16_t nBytes = 1024; - uint8_t const *block; - - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t const *)0) { - QSPY_parse(block, nBytes); - nBytes = 1024; - } - else { - break; - } - } -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -void QSPY_onPrintLn(void) { - fputs(QSPY_line, stdout); - fputc('\n', stdout); -} -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ diff --git a/examples/win32-qv/dpp/dpp.h b/examples/win32-qv/dpp/dpp.h deleted file mode 100644 index b258597c..00000000 --- a/examples/win32-qv/dpp/dpp.h +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************** -* Model: dpp.qm -* File: ./dpp.h -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::dpp.h} ..............................................................*/ -#ifndef dpp_h -#define dpp_h - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${Events::TableEvt} ......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t philoNum; -} TableEvt; - - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); - -extern QMActive * const AO_Philo[N_PHILO]; - - -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); - -extern QActive * const AO_Table; - - -#ifdef qxk_h - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* qxk_h */ - -#endif /* dpp_h */ diff --git a/examples/win32-qv/dpp/dpp.qm b/examples/win32-qv/dpp/dpp.qm deleted file mode 100644 index 4cc4237f..00000000 --- a/examples/win32-qv/dpp/dpp.qm +++ /dev/null @@ -1,445 +0,0 @@ - - - Dining Philosopher Problem example -NOTE: Requries QP5. - - - - - - - - - - - - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)e; /* suppress the compiler warning about unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - /* 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); -QACTIVE_POST(AO_Table, &pe->super, 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)); - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QF_PUBLISH(&pe->super, me); - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - - uint8_t n; -(void)e; /* suppress the compiler warning about unused parameter */ - -QS_OBJ_DICTIONARY(&l_table); -QS_FUN_DICTIONARY(&QHsm_top); -QS_FUN_DICTIONARY(&Table_initial); -QS_FUN_DICTIONARY(&Table_active); -QS_FUN_DICTIONARY(&Table_serving); -QS_FUN_DICTIONARY(&Table_paused); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - - - - Q_ERROR(); - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QF_PUBLISH(&te->super, me); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QF_PUBLISH(&pe->super, me); -BSP_displayPhilStat(n, "eating "); - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); -} - - - - - - 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->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - #ifndef dpp_h -#define dpp_h - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -$declare(Events::TableEvt) - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) - -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) - -#ifdef qxk_h - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* qxk_h */ - -#endif /* dpp_h */ - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) - - - diff --git a/examples/win32-qv/dpp/dpp.vcxproj.filters b/examples/win32-qv/dpp/dpp.vcxproj.filters deleted file mode 100644 index ee9630d1..00000000 --- a/examples/win32-qv/dpp/dpp.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - QSPY - - - - - - - - - {76cb74d9-2f6d-42d1-98bb-e99763c51a65} - - - {d7f10ffa-a6c9-4edf-b9f9-c01f977f17cf} - - - - - QP - - - QP - - - QP - - - \ No newline at end of file diff --git a/examples/win32-qv/dpp/philo.c b/examples/win32-qv/dpp/philo.c deleted file mode 100644 index 67c2ac69..00000000 --- a/examples/win32-qv/dpp/philo.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************** -* Model: dpp.qm -* File: ./philo.c -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::philo.c} ............................................................*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - QTimeEvt timeEvt; -} Philo; - -/* protected: */ -static QState Philo_initial(Philo * const me, QEvt const * const e); -static QState Philo_thinking(Philo * const me, QEvt const * const e); -static QState Philo_hungry(Philo * const me, QEvt const * const e); -static QState Philo_eating(Philo * const me, QEvt const * const e); - - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QMActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*${AOs::Philo} ............................................................*/ -/*${AOs::Philo::SM} ........................................................*/ -static QState Philo_initial(Philo * const me, QEvt const * const e) { - /* ${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)e; /* suppress the compiler warning about unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - - QActive_subscribe(&me->super, EAT_SIG); - QActive_subscribe(&me->super, TEST_SIG); - return Q_TRAN(&Philo_thinking); -} -/*${AOs::Philo::SM::thinking} ..............................................*/ -static QState Philo_thinking(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Philo::SM::thinking} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::thinking} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::thinking::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_hungry); - break; - } - /* ${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::thinking::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Philo::SM::hungry} ................................................*/ -static QState Philo_hungry(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Philo::SM::hungry} */ - case Q_ENTRY_SIG: { - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::hungry::EAT} */ - case EAT_SIG: { - /* ${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { - status_ = Q_TRAN(&Philo_eating); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /* ${AOs::Philo::SM::hungry::DONE} */ - case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Philo::SM::eating} ................................................*/ -static QState Philo_eating(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Philo::SM::eating} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::eating} */ - case Q_EXIT_SIG: { - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); - QF_PUBLISH(&pe->super, me); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Philo::SM::eating::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_thinking); - break; - } - /* ${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - diff --git a/examples/win32-qv/dpp/table.c b/examples/win32-qv/dpp/table.c deleted file mode 100644 index fe8b1a84..00000000 --- a/examples/win32-qv/dpp/table.c +++ /dev/null @@ -1,296 +0,0 @@ -/***************************************************************************** -* Model: dpp.qm -* File: ./table.c -* -* This code has been generated by QM tool (see state-machine.com/qm). -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -*****************************************************************************/ -/*${.::table.c} ............................................................*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; -} Table; - -/* protected: */ -static QState Table_initial(Table * const me, QEvt const * const e); -static QState Table_active(Table * const me, QEvt const * const e); -static QState Table_serving(Table * const me, QEvt const * const e); -static QState Table_paused(Table * const me, QEvt const * const e); - - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QMActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - } -} -/*${AOs::Table} ............................................................*/ -/*${AOs::Table::SM} ........................................................*/ -static QState Table_initial(Table * const me, QEvt const * const e) { - /* ${AOs::Table::SM::initial} */ - uint8_t n; - (void)e; /* suppress the compiler warning about unused parameter */ - - QS_OBJ_DICTIONARY(&l_table); - QS_FUN_DICTIONARY(&QHsm_top); - QS_FUN_DICTIONARY(&Table_initial); - QS_FUN_DICTIONARY(&Table_active); - QS_FUN_DICTIONARY(&Table_serving); - QS_FUN_DICTIONARY(&Table_paused); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - - QActive_subscribe(&me->super, DONE_SIG); - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); - } - return Q_TRAN(&Table_serving); -} -/*${AOs::Table::SM::active} ................................................*/ -static QState Table_active(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Table::SM::active::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*${AOs::Table::SM::active::serving} .......................................*/ -static QState Table_serving(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Table::SM::active::serving} */ - case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QF_PUBLISH(&te->super, me); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } - } - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::serving::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /* ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ - if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; - me->fork[m] = USED; - me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(n, "eating "); - status_ = Q_HANDLED(); - } - /* ${AOs::Table::SM::active::serving::HUNGRY::[else]} */ - else { - me->isHungry[n] = 1U; - status_ = Q_HANDLED(); - } - break; - } - /* ${AOs::Table::SM::active::serving::DONE} */ - case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ - - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); - } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QF_PUBLISH(&pe->super, me); - BSP_displayPhilStat(m, "eating "); - } - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::serving::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::serving::PAUSE} */ - case PAUSE_SIG: { - status_ = Q_TRAN(&Table_paused); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} -/*${AOs::Table::SM::active::paused} ........................................*/ -static QState Table_paused(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /* ${AOs::Table::SM::active::paused} */ - case Q_ENTRY_SIG: { - BSP_displayPaused(1U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::paused} */ - case Q_EXIT_SIG: { - BSP_displayPaused(0U); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::paused::SERVE} */ - case SERVE_SIG: { - status_ = Q_TRAN(&Table_serving); - break; - } - /* ${AOs::Table::SM::active::paused::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); - status_ = Q_HANDLED(); - break; - } - /* ${AOs::Table::SM::active::paused::DONE} */ - case DONE_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} - diff --git a/examples/win32-qv/game-gui/README.txt b/examples/win32-qv/game-gui/README.txt deleted file mode 100644 index 88f44ab0..00000000 --- a/examples/win32-qv/game-gui/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -The Win32 GUI emulation of the "Fly 'n' Shoot" game example for the -EFM32-SLSTK3401A board from Silicon Labs is now located in the directory: - -examples\arm-cm\game_efm32-slstk3401a\win32-qv\ - -**** -NOTE: The EFM32-SLSTK3401A board replaces the EK-LM3S811 board, which -has been discontinued. -**** - -This co-location of the Win32 emulation with the embedded code running -on the actual board demonstrates better the "dual targeting" development -approach. \ No newline at end of file diff --git a/examples/win32-qv/reminder2/Makefile b/examples/win32-qv/reminder2/Makefile deleted file mode 100644 index 31c73209..00000000 --- a/examples/win32-qv/reminder2/Makefile +++ /dev/null @@ -1,259 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Reminder2 Pattern console, Win32-QV, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := reminder2 - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32-qv - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - reminder2.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32-qv/reminder2/reminder2.c b/examples/win32-qv/reminder2/reminder2.c deleted file mode 100644 index 05cbe243..00000000 --- a/examples/win32-qv/reminder2/reminder2.c +++ /dev/null @@ -1,198 +0,0 @@ -/***************************************************************************** -* Product: Reminder2 state pattern example -* Last Updated for Version: 5.4.2 -* Date of the Last Update: 2015-06-03 -* -* 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: -* Web : https://state-machine.com -* Email: info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -enum ReminderSignals { - CRUNCH_SIG = Q_USER_SIG, /* the invented reminder signal */ - ECHO_SIG, /* check the responsiveness of the system */ - TERMINATE_SIG /* terminate the application */ -}; - -typedef struct ReminderEvtTag { - QEvt super; - uint32_t iter; /* the next iteration to perform */ -} ReminderEvt; - -/*..........................................................................*/ -typedef struct { /* the Cruncher active object */ - QActive super; /* inherit QActive */ - double sum; /* internal variable */ -} Cruncher; - -void Cruncher_ctor(Cruncher * const me); - -/* hierarchical state machine ... */ -static QState Cruncher_initial (Cruncher * const me, QEvt const * const e); -static QState Cruncher_processing(Cruncher * const me, QEvt const * const e); -static QState Cruncher_final (Cruncher * const me, QEvt const * const e); - -/*--------------------------------------------------------------------------*/ -void Cruncher_ctor(Cruncher * const me) { - QActive_ctor(&me->super, Q_STATE_CAST(&Cruncher_initial)); -} -/*..........................................................................*/ -QState Cruncher_initial(Cruncher * const me, QEvt const * const e) { - (void)e; /* unused parameter */ - return Q_TRAN(&Cruncher_processing); -} -/*..........................................................................*/ -QState Cruncher_processing(Cruncher * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); - reminder->iter = 0U; - QACTIVE_POST((QActive *)me, (QEvt const *)reminder, me); - me->sum = 0.0; - status = Q_HANDLED(); - break; - } - case CRUNCH_SIG: { - uint32_t i = ((ReminderEvt const *)e)->iter; - uint32_t n = i; - i += 100U; - for (; n < i; ++n) { - if ((n & 1U) == 0U) { - me->sum += 1.0/(2*n + 1); - } - else { - me->sum -= 1.0/(2*n + 1); - } - } - if (i < 0x07000000U) { - ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); - reminder->iter = i; - QACTIVE_POST((QActive *)me, (QEvt const *)reminder, me); - status = Q_HANDLED(); - } - else { - printf("pi=%16.14f\n", 4.0*me->sum); - fflush(stdout); - status = Q_TRAN(&Cruncher_processing); - } - break; - } - case ECHO_SIG: { - printf("Echo! pi=%16.14f\n", 4.0*me->sum); - fflush(stdout); - status = Q_HANDLED(); - break; - } - case TERMINATE_SIG: { - status = Q_TRAN(&Cruncher_final); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Cruncher_final(Cruncher * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - printf("final-ENTRY;\n"); - fflush(stdout); - QF_stop(); /* terminate the application */ - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} - -/* test harness ============================================================*/ - -/* Local-scope objects -----------------------------------------------------*/ -static Cruncher l_cruncher; /* the Cruncher active object */ -QEvt const *l_cruncherQSto[10]; /* Event queue storage for Cruncher AO */ -static QF_MPOOL_EL(ReminderEvt) l_smlPoolSto[20]; /* storage for small pool */ - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - printf("Reminder state pattern\nQP version: %s\n" - "Press 'e' to echo the current value...\n" - "Press ESC to quit...\n", - QP_versionStr); - fflush(stdout); - - Cruncher_ctor(&l_cruncher); - - BSP_init(argc, argv); /* initialize the BSP */ - - QF_init();/* initialize the framework and the underlying RT kernel */ - - /* publish-subscribe not used, no call to QF_psInit() */ - - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - /* instantiate and start the active objects... */ - QACTIVE_START(&l_cruncher.super, - 1U, - l_cruncherQSto, Q_DIM(l_cruncherQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); /* run the QF application */ -} -/*..........................................................................*/ -void BSP_onKeyboardInput(uint8_t key) { - switch (key) { - case 'e': { - static QEvt const echoEvt = { ECHO_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_cruncher, &echoEvt, (void *)0); - break; - } - case '\033': { /* ESC pressed? */ - /* NOTE: this constant event is statically pre-allocated. - * It can be posted/published as any other event. - */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_cruncher, &terminateEvt, (void *)0); - break; - } - } -} diff --git a/examples/win32/README.txt b/examples/win32/README.txt deleted file mode 100644 index 96ca2404..00000000 --- a/examples/win32/README.txt +++ /dev/null @@ -1,43 +0,0 @@ -The examples in the win32 directory can be built either with the -GNU comiler (MinGW) or Microsoft Visual C++ (Express 2013). - -The Visual C++ toolset is supported by the VC++ solution and project -files files (.sln, and .vcxproj files) also provided with some -example projects. - -The MinGW toolset is supported by the Makefiles provided for every -example project. The Makefile requires the GNU make uitility for -Windows. Both the MinGW compiler and the make utility are are included -in the Qtools collection, which is available for a separate download -from: - -http://sourceforge.net/projects/qpc/files/Qtools/ - -The \qtools\bin directory should be added to the system -PATH, and the QTOOLS environment variable should be defined to point -to \qtools. - - -The QP Libraries -================ -All projects in this directory link to the QP/C framework, which is -provided in pre-built libraries for the three supported build -configurations (dbg, rel, and spy). The pre-compiled libraries -for are located in the following directoires: - -qpc\ports\win32\dbg\libqp.a - MinGW, Debug build configuration -qpc\ports\win32\rel\libqp.a - MinGW, Release build configuration -qpc\ports\win32\spy\libqp.a - MinGW, Spy build configuration - -qpc\ports\win32\Debug\qp.lib - VC++, Debug build configuration -qpc\ports\win32\Release\qp.lib - VC++, Release build configuration -qpc\ports\win32\QSpy\qp.lib - VC++, Spy build configuration - -Typically these libraries can be used "as is" for your projects - -Howver, if you want to change the QP settings, or if you want to use -different compiler options, you need to re-bulid the QP libraries from -sources. The QP port directory qpc\ports\win32 contains the -Makefile for re-building the QP libraries with MinGW as well as the -VC++ solution file to re-build QP libraries with Visual C++. - diff --git a/examples/win32/README.url b/examples/win32/README.url deleted file mode 100644 index b9b4011a..00000000 --- a/examples/win32/README.url +++ /dev/null @@ -1,3 +0,0 @@ -[InternetShortcut] -URL=http://www.state-machine.com/qpc/exa_win32.html -IconFile=http://www.state-machine.com/qp.ico diff --git a/examples/win32/blinky/Makefile b/examples/win32/blinky/Makefile deleted file mode 100644 index 83aa6e02..00000000 --- a/examples/win32/blinky/Makefile +++ /dev/null @@ -1,239 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Blinky console, POSIX target, GNU compiler -# Last updated for version 6.3.3a -# Last updated on 2018-07-27 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# 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 -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := blinky - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/posix - -# list of all source directories used by this project -VPATH = \ - . \ - $(QPC)/src/qf \ - $(QPC)/src/qs \ - $(QP_PORT_DIR) - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -I$(QPC)/src \ - -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - blinky.c - -# C++ source files... -CPP_SRCS := - -QP_SRCS := \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# GNU toolset -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -MKDIR := mkdir -p -RM := rm -f - -#----------------------------------------------------------------------------- -# build options for various configurations -# -# combine all the soruces... -C_SRCS += $(QP_SRCS) - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -CPPFLAGS = -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -pthread -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -C_SRCS += $(QS_SRCS) - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -CPPFLAGS = -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -pthread - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -#----------------------------------------------------------------------------- -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lpthread - -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/* - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - diff --git a/examples/win32/blinky/README.txt b/examples/win32/blinky/README.txt deleted file mode 100644 index 2bbadb81..00000000 --- a/examples/win32/blinky/README.txt +++ /dev/null @@ -1,11 +0,0 @@ -This example corresponds to the QM Tutorial at: - -https://www.state-machine.com/qm/gs_tut.html - - -Specifically the files are as follows: - -blinky.qm - the QM model for the Blinky active object -blinky.c - the generated code for the Blinky application -make.bat - the batch file for building Blinky on Windows -Makefile - the makefile to build Blinky on Linux diff --git a/examples/win32/blinky/make.bat b/examples/win32/blinky/make.bat deleted file mode 100644 index 3ba04c4d..00000000 --- a/examples/win32/blinky/make.bat +++ /dev/null @@ -1,3 +0,0 @@ -set QPC=C:\qp\qpc -set QTOOLS=C:\qp\qtools -%QTOOLS%\bin\gcc blinky.c -oblinky.exe -I%QPC%\include -I%QPC%\ports\win32 -L%QPC%\ports\win32\dbg -lqp \ No newline at end of file diff --git a/examples/win32/calc/Makefile b/examples/win32/calc/Makefile deleted file mode 100644 index 6e7f89bd..00000000 --- a/examples/win32/calc/Makefile +++ /dev/null @@ -1,260 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Calc console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := calc - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - calc.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/calc1/Makefile b/examples/win32/calc1/Makefile deleted file mode 100644 index 514a1cc8..00000000 --- a/examples/win32/calc1/Makefile +++ /dev/null @@ -1,260 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Calc1 console, Win32, MinGW -# Last Updated for Version: 5.7.0 -# Date of the Last Update: 2016-08-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := calc1 - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - calc1.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/calc1_sub/Makefile b/examples/win32/calc1_sub/Makefile deleted file mode 100644 index fcec9c40..00000000 --- a/examples/win32/calc1_sub/Makefile +++ /dev/null @@ -1,260 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Calc1 console, Win32, MinGW -# Last Updated for Version: 5.7.0 -# Date of the Last Update: 2016-08-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := calc1_sub - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - calc1_sub.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/comp/Makefile b/examples/win32/comp/Makefile deleted file mode 100644 index 58e35299..00000000 --- a/examples/win32/comp/Makefile +++ /dev/null @@ -1,260 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Orthogonal Component console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := comp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - alarm.c \ - comp.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 530 means the API 5.3.0 -DEFINES := -DQP_API_VERSION=530 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/comp/alarm.c b/examples/win32/comp/alarm.c deleted file mode 100644 index a5ea8a94..00000000 --- a/examples/win32/comp/alarm.c +++ /dev/null @@ -1,144 +0,0 @@ -/***************************************************************************** -* Product: Orthogonal Component state pattern example -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-16 -* -* 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: -* Web: www.state-machine.com -* Email: info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "alarm.h" -#include "clock.h" - -#include - -Q_DEFINE_THIS_FILE - -/* FSM state-handler functions */ -static QState Alarm_initial(Alarm * const me, QEvt const * const e); -static QState Alarm_off (Alarm * const me, QEvt const * const e); -static QState Alarm_on (Alarm * const me, QEvt const * const e); - -/*..........................................................................*/ -void Alarm_ctor(Alarm * const me) { - QFsm_ctor(&me->super, Q_STATE_CAST(&Alarm_initial)); -} - -/* FSM definition ----------------------------------------------------------*/ -QState Alarm_initial(Alarm * const me, QEvt const * const e) { - (void)e; /* avoid compiler warning about unused parameter */ - me->alarm_time = 12*60; - return Q_TRAN(&Alarm_off); -} -/*..........................................................................*/ -QState Alarm_off(Alarm * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - /* while in the off state, the alarm is kept in decimal format */ - me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; - printf("*** Alarm OFF %02d:%02d\n", - me->alarm_time/100, me->alarm_time%100); - fflush(stdout); - status = Q_HANDLED(); - break; - } - case Q_EXIT_SIG: { - /* upon exit, the alarm is converted to binary format */ - me->alarm_time = (me->alarm_time/100)*60 + me->alarm_time%100; - status = Q_HANDLED(); - break; - } - case ALARM_ON_SIG: { - /* alarm in range? */ - if ((me->alarm_time / 100 < 24) && (me->alarm_time % 100 < 60)) { - status = Q_TRAN(&Alarm_on); - } - else { /* alarm out of range -- clear and don't transition */ - me->alarm_time = 0; - printf("*** Alarm reset %02d:%02d\n", - me->alarm_time/100, me->alarm_time%100); - status = Q_HANDLED(); - } - break; - } - case ALARM_SET_SIG: { - /* while setting, the alarm is kept in decimal format */ - me->alarm_time = (10 * me->alarm_time - + ((SetEvt const *)e)->digit) % 10000; - printf("*** Alarm SET %02d:%02d\n", - me->alarm_time/100, me->alarm_time%100); - fflush(stdout); - status = Q_HANDLED(); - break; - } - default: { - status = Q_IGNORED(); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Alarm_on(Alarm * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - printf("*** Alarm ON %02d:%02d\n", - me->alarm_time/60, me->alarm_time%60); - fflush(stdout); - status = Q_HANDLED(); - break; - } - case ALARM_SET_SIG: { - printf("*** Cannot set Alarm when it is ON\n"); - fflush(stdout); - status = Q_HANDLED(); - break; - } - case ALARM_OFF_SIG: { - status = Q_TRAN(&Alarm_off); - break; - } - case TIME_SIG: { - if (((TimeEvt *)e)->current_time == me->alarm_time) { - printf("ALARM!!!\n"); - /* asynchronously post the event to the container AO */ - QACTIVE_POST(APP_alarmClock, Q_NEW(QEvt, ALARM_SIG), me); - } - status = Q_HANDLED(); - break; - } - default: { - status = Q_IGNORED(); - break; - } - } - return status; -} diff --git a/examples/win32/comp/alarm.h b/examples/win32/comp/alarm.h deleted file mode 100644 index f0e9fbd2..00000000 --- a/examples/win32/comp/alarm.h +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************** -* Product: Orthogonal Component state pattern example -* Last updated for version 5.4.0 -* Last updated on 2015-03-25 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com -*****************************************************************************/ -#ifndef alarm_h -#define alarm_h - -typedef struct { /* the FSM version of the Alarm component */ - QFsm super; /* inherit QFsm */ - uint32_t alarm_time; -} Alarm; - -void Alarm_ctor(Alarm * const me); - -#endif /* alarm_h */ diff --git a/examples/win32/comp/clock.h b/examples/win32/comp/clock.h deleted file mode 100644 index a6c30c38..00000000 --- a/examples/win32/comp/clock.h +++ /dev/null @@ -1,62 +0,0 @@ -/***************************************************************************** -* Product: Orthogonal Component state pattern example -* Last Updated for Version: 4.5.00 -* Date of the Last Update: May 18, 2012 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 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: -* Quantum Leaps Web sites: http://www.quantum-leaps.com -* https://state-machine.com -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#ifndef clock_h -#define clock_h - -enum AlarmClockSignals { - TICK_SIG = Q_USER_SIG, /* time tick event */ - ALARM_SET_SIG, /* set the alarm */ - ALARM_ON_SIG, /* turn the alarm on */ - ALARM_OFF_SIG, /* turn the alarm off */ - ALARM_SIG, /* alarm event from Alarm component to AlarmClock container */ - CLOCK_12H_SIG, /* set the clock in 12H mode */ - CLOCK_24H_SIG, /* set the clock in 24H mode */ - TIME_SIG, /* time event sent to Alarm (contains current time) */ - TERMINATE_SIG /* terminate the application */ -}; -/*..........................................................................*/ -typedef struct SetEvtTag { - QEvt super; /* derive from QEvt */ - uint8_t digit; -} SetEvt; - -typedef struct TimeEvtTag { - QEvt super; /* derive from QEvt */ - uint32_t current_time; -} TimeEvt; - -extern QActive *APP_alarmClock; /* AlarmClock container active object */ - -#endif /* clock_h */ diff --git a/examples/win32/comp/comp.c b/examples/win32/comp/comp.c deleted file mode 100644 index 6373535b..00000000 --- a/examples/win32/comp/comp.c +++ /dev/null @@ -1,303 +0,0 @@ -/***************************************************************************** -* Product: Orthogonal Component state pattern example -* Last updated for version 5.4.2 -* Last updated on 2015-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "alarm.h" -#include "clock.h" - -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -typedef struct AlarmClockTag { /* the AlarmClock active object */ - QActive super; /* inherit QActive */ - - uint32_t current_time; /* the current time in seconds */ - Alarm alarm; /* Alarm orthogonal component */ - QTimeEvt timeEvt; /* time event generator (generates time ticks) */ -} AlarmClock; - -void AlarmClock_ctor(AlarmClock * const me); /* default ctor */ - -/* hierarchical state machine ... */ -static QState AlarmClock_initial(AlarmClock * const me, QEvt const * const e); -static QState AlarmClock_timekeeping(AlarmClock*const me, QEvt const*const e); -static QState AlarmClock_mode12hr(AlarmClock * const me, QEvt const *const e); -static QState AlarmClock_mode24hr(AlarmClock * const me, QEvt const *const e); -static QState AlarmClock_final (AlarmClock * const me, QEvt const *const e); - -/*..........................................................................*/ -void AlarmClock_ctor(AlarmClock * const me) { /* default ctor */ - QActive_ctor(&me->super, Q_STATE_CAST(&AlarmClock_initial)); - Alarm_ctor(&me->alarm); /* orthogonal component ctor */ - /* private time event ctor */ - QTimeEvt_ctorX(&me->timeEvt, &me->super, TICK_SIG, 0U); -} -/* HSM definition ----------------------------------------------------------*/ -QState AlarmClock_initial(AlarmClock * const me, QEvt const * const e) { - (void)e; /* unused parameter */ - me->current_time = 0U; - - /* take the top-most initial transition in the component */ - QMSM_INIT(&me->alarm.super, (QEvt *)0); - - return Q_TRAN(&AlarmClock_timekeeping); -} -/*..........................................................................*/ -QState AlarmClock_final(AlarmClock * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - printf("-> final\n"); - QF_stop(); /* terminate the application */ - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - /* periodic timeout every second and every second */ - QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC, BSP_TICKS_PER_SEC); - status = Q_HANDLED(); - break; - } - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status = Q_HANDLED(); - break; - } - case Q_INIT_SIG: { - status = Q_TRAN(&AlarmClock_mode24hr); - break; - } - case CLOCK_12H_SIG: { - status = Q_TRAN(&AlarmClock_mode12hr); - break; - } - case CLOCK_24H_SIG: { - status = Q_TRAN(&AlarmClock_mode24hr); - break; - } - case ALARM_SIG: { - printf("Wake up!!!\n"); - status = Q_HANDLED(); - break; - } - case ALARM_SET_SIG: - case ALARM_ON_SIG: - case ALARM_OFF_SIG: { - /* synchronously dispatch to the orthogonal component */ - QMSM_DISPATCH(&me->alarm.super, e); - status = Q_HANDLED(); - break; - } - case TERMINATE_SIG: { - status = Q_TRAN(&AlarmClock_final); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState AlarmClock_mode24hr(AlarmClock * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - printf("*** 24-hour mode\n"); - status = Q_HANDLED(); - break; - } - case TICK_SIG: { - TimeEvt pe; /* temporary synchronous event for the component */ - - /* roll over in 24-hr mode? */ - if (++me->current_time == 24U*60U) { - me->current_time = 0U; - } - printf("%02d:%02d\n", - me->current_time / 60U, me->current_time % 60U); - pe.super.sig = TIME_SIG; - pe.current_time = me->current_time; - - /* synchronously dispatch to the orthogonal component */ - QMSM_DISPATCH(&me->alarm.super, (QEvt *)&pe); - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&AlarmClock_timekeeping); - break; - } - } - return status; -} -/*..........................................................................*/ -QState AlarmClock_mode12hr(AlarmClock * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - printf("*** 12-hour mode\n"); - status = Q_HANDLED(); - break; - } - case TICK_SIG: { - TimeEvt pe; /* temporary synchronous event for the component */ - uint32_t h; /* temporary variable to hold hour */ - - /* roll over in 12-hr mode? */ - if (++me->current_time == 12U * 60U) { - me->current_time = 0U; - } - h = me->current_time / 60U; - printf("%02d:%02d %s\n", (h % 12U) ? (h % 12U) : 12U, - me->current_time % 60U, (h / 12) ? "PM" : "AM"); - pe.super.sig = TIME_SIG; - pe.current_time = me->current_time; - - /* synchronously dispatch to the orthogonal component */ - QMSM_DISPATCH(&me->alarm.super, (QEvt *)&pe); - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&AlarmClock_timekeeping); - break; - } - } - return status; -} - -/* test harness ============================================================*/ - -/* Local-scope objects -----------------------------------------------------*/ -static AlarmClock l_alarmClock; /* the AlarmClock active object */ -static QEvt const *l_alarmClockQSto[10]; /* queue storage for AlarmClock */ -static QF_MPOOL_EL(TimeEvt) l_smlPoolSto[10]; /* storage for small pool */ - -/* Global-scope objects (opaque pointer to the AlarmClock container) -------*/ -QActive *APP_alarmClock= &l_alarmClock.super;/* AlarmClock container AO */ - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - printf("Orthogonal Component pattern\nQP version: %s\n" - "Press 'o' to turn the Alarm ON\n" - "Press 'f' to turn the Alarm OFF\n" - "Press '0'..'9' to set the Alarm time\n" - "Press 'a' to set the Clock in 12-hour mode\n" - "Press 'b' to set the Clock in 24-hour mode\n" - "Press ESC to quit...\n", - QP_versionStr); - - BSP_init(argc, argv); /* initialize the BSP */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* publish-subscribe not used, no call to QF_psInit() */ - - /* initialize event pools... */ - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - /* instantiate and start the active objects... */ - AlarmClock_ctor(&l_alarmClock); - QACTIVE_START(&l_alarmClock.super, - 1U, - l_alarmClockQSto, Q_DIM(l_alarmClockQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); /* run the QF application */ -} -/*..........................................................................*/ -void BSP_onKeyboardInput(uint8_t key) { - switch (key) { - case 'o': { /* 'o': Alarm on event? */ - QACTIVE_POST((QActive *)&l_alarmClock, - Q_NEW(QEvt, ALARM_ON_SIG), (void *)0); - break; - } - case 'f': { /* 'f': Alarm off event? */ - QACTIVE_POST((QActive *)&l_alarmClock, - Q_NEW(QEvt, ALARM_OFF_SIG), (void *)0); - break; - } - case '1': /* '1' */ - case '2': /* '2' */ - case '3': /* '3' */ - case '4': /* '4' */ - case '5': /* '5' */ - case '6': /* '6' */ - case '7': /* '7' */ - case '8': /* '8' */ - case '9': { /* '9' */ - SetEvt *e = Q_NEW(SetEvt, ALARM_SET_SIG); - e->digit = (uint8_t)(key - '0'); - QACTIVE_POST((QActive *)&l_alarmClock, (QEvt *)e, (void *)0); - break; - } - case '0': { /* '0' */ - SetEvt *e = Q_NEW(SetEvt, ALARM_SET_SIG); - e->digit = 0; - QACTIVE_POST((QActive *)&l_alarmClock, (QEvt *)e, (void *)0); - break; - } - case 'a': { /* 'a': Clock 12H event? */ - QACTIVE_POST((QActive *)&l_alarmClock, - Q_NEW(QEvt, CLOCK_12H_SIG), (void *)0); - break; - } - case 'b': { /* 'b': Clock 24H event? */ - QACTIVE_POST((QActive *)&l_alarmClock, - Q_NEW(QEvt, CLOCK_24H_SIG), (void *)0); - break; - } - case '\33': { /* ESC pressed? */ - QACTIVE_POST((QActive *)&l_alarmClock, - Q_NEW(QEvt, TERMINATE_SIG), (void *)0); - break; - } - } -} diff --git a/examples/win32/comp_qm/Makefile b/examples/win32/comp_qm/Makefile deleted file mode 100644 index 77244271..00000000 --- a/examples/win32/comp_qm/Makefile +++ /dev/null @@ -1,261 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Orthogonal Component console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := comp_qm - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - alarm.c \ - clock.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/defer/Makefile b/examples/win32/defer/Makefile deleted file mode 100644 index 1dcd9cd3..00000000 --- a/examples/win32/defer/Makefile +++ /dev/null @@ -1,259 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Deferred Event console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := defer - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - defer.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/dpp-comp/Makefile b/examples/win32/dpp-comp/Makefile deleted file mode 100644 index 22c26c59..00000000 --- a/examples/win32/dpp-comp/Makefile +++ /dev/null @@ -1,263 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, DPP console, Win32, MinGW -# Last Updated for Version: 6.0.1 -# Date of the Last Update: 2017-10-29 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := dpp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = . \ - cont \ - comp - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include \ - -Icont - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/dpp/Makefile b/examples/win32/dpp/Makefile deleted file mode 100644 index e318fb80..00000000 --- a/examples/win32/dpp/Makefile +++ /dev/null @@ -1,261 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, DPP console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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 -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := dpp - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/dpp/bsp.c b/examples/win32/dpp/bsp.c deleted file mode 100644 index f3bfa1da..00000000 --- a/examples/win32/dpp/bsp.c +++ /dev/null @@ -1,246 +0,0 @@ - /***************************************************************************** -* Product: DPP example, Windows (console) -* Last updated for version 5.9.7 -* Last updated on 2017-08-25 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - static uint8_t l_running; - static uint8_t const l_clock_tick = 0U; -#endif - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - int ch = _getch(); - if (ch == '\33') { /* see if the ESC key pressed */ - BSP_terminate(0); - } - else if (ch == 'p') { - QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - } - else if (ch == 's') { - QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - } - } -} -/*..........................................................................*/ -void Q_onAssert(char const * const module, int_t loc) { - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - fprintf(stderr, "Assertion failed in %s, line %d", module, loc); - exit(-1); -} -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; - (void)argv; - - printf("Dining Philosophers Problem example" - "\nQP %s\n" - "Press 'p' to pause\n" - "Press 's' to serve\n" - "Press ESC to quit...\n", - QP_versionStr); - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : "")); - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -#ifdef Q_SPY - l_running = (uint8_t)0; /* stop the QS output thread */ -#endif - QF_stop(); /* stop the main "ticker thread" */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - printf("Philosopher %2d is %s\n", (int)n, stat); - - QS_BEGIN(PHILO_STAT, AO_Philo[n]) /* application-specific record begin */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - printf("Paused is %s\n", paused ? "ON" : "OFF"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -#include "qspy.h" -#include - -#define WIN32_LEAN_AND_MEAN -#include /* Win32 API for multithreading */ - -static uint8_t l_running; - -/*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); - l_running = (uint8_t)1; - while (l_running) { - uint16_t nBytes = 256; - uint8_t const *block; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - if (block != (uint8_t *)0) { - QSPY_parse(block, nBytes); - } - Sleep(10U); /* wait for a clock tick */ - } - return 0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* 4K buffer for Quantum Spy */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - - /* here 'arg' is ignored, but this command-line parameter can be used - * to setup the QSP_config(), to set up the QS filters, or for any - * other purpose. - */ - (void)arg; - - QSPY_config(QP_VERSION, // version - QS_OBJ_PTR_SIZE, // objPtrSize - QS_FUN_PTR_SIZE, // funPtrSize - QS_TIME_SIZE, // tstampSize - Q_SIGNAL_SIZE, // sigSize, - QF_EVENT_SIZ_SIZE, // evtSize - QF_EQUEUE_CTR_SIZE, // queueCtrSize - QF_MPOOL_CTR_SIZE, // poolCtrSize - QF_MPOOL_SIZ_SIZE, // poolBlkSize - QF_TIMEEVT_CTR_SIZE,// tevtCtrSize - (void *)0, // matFile, - (void *)0, // mscFile - (QSPY_CustParseFun)0); // no customized parser function - - /* 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PHILO_STAT); - - return CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0; /* return the status of creating the idle thread */ -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - QSPY_stop(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - for (;;) { - uint16_t nBytes = 1024; - uint8_t const *block; - - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t const *)0) { - QSPY_parse(block, nBytes); - nBytes = 1024; - } - else { - break; - } - } -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -void QSPY_onPrintLn(void) { - fputs(QSPY_line, stdout); - fputc('\n', stdout); -} -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ diff --git a/examples/win32/dpp/bsp.h b/examples/win32/dpp/bsp.h deleted file mode 100644 index cc3c352e..00000000 --- a/examples/win32/dpp/bsp.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 4.5.02 -* Date of the Last Update: Jul 04, 2012 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 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: -* Quantum Leaps Web sites: http://www.quantum-leaps.com -* https://state-machine.com -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#ifndef bsp_h -#define bsp_h - -#define BSP_TICKS_PER_SEC 50U - -void BSP_init(int argc, char *argv[]); -void BSP_displayPaused(uint8_t paused); -void BSP_displayPhilStat(uint8_t n, char_t const *stat); -void BSP_terminate(int16_t result); - -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ - -#endif /* bsp_h */ diff --git a/examples/win32/dpp/dpp.sln b/examples/win32/dpp/dpp.sln deleted file mode 100644 index 845e32cf..00000000 --- a/examples/win32/dpp/dpp.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dpp", "dpp.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - QSpy|Win32 = QSpy|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.ActiveCfg = Release|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.Build.0 = Release|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.ActiveCfg = QSpy|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.Build.0 = QSpy|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/examples/win32/dpp/dpp.vcxproj b/examples/win32/dpp/dpp.vcxproj deleted file mode 100644 index 2f95ea1a..00000000 --- a/examples/win32/dpp/dpp.vcxproj +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - QSpy - Win32 - - - - {8CC465F7-872E-4D03-B93C-1B64858B4E11} - dpp - Win32Proj - - - - Application - NotSet - v120 - - - Application - NotSet - true - v120 - - - Application - NotSet - v120 - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - - - - Disabled - .;../../../include;../../../ports/win32;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - Default - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - MaxSpeed - true - .;../../../include;../../../ports/win32;%(AdditionalIncludeDirectories) - NDEBUG;snprintf=_snprintf;WIN32;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - true - NotUsing - Level4 - ProgramDatabase - 4127 - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - Disabled - .;../../../include;../../../ports/win32;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) - Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - true - true - - - - - - - - - - - - - - true - - - true - true - - - true - - - - - - \ No newline at end of file diff --git a/examples/win32/dpp/dpp.vcxproj.filters b/examples/win32/dpp/dpp.vcxproj.filters deleted file mode 100644 index ee9630d1..00000000 --- a/examples/win32/dpp/dpp.vcxproj.filters +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - QSPY - - - - - - - - - {76cb74d9-2f6d-42d1-98bb-e99763c51a65} - - - {d7f10ffa-a6c9-4edf-b9f9-c01f977f17cf} - - - - - QP - - - QP - - - QP - - - \ No newline at end of file diff --git a/examples/win32/dpp/main.c b/examples/win32/dpp/main.c deleted file mode 100644 index 515fc000..00000000 --- a/examples/win32/dpp/main.c +++ /dev/null @@ -1,110 +0,0 @@ -/***************************************************************************** -* Product: DPP example for Windows -* Last Updated for Version: 5.7.5 -* Date of the Last Update: 2016-11-08 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO*WIN_FUDGE_FACTOR]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR]; - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ diff --git a/examples/win32/history_qhsm/Makefile b/examples/win32/history_qhsm/Makefile deleted file mode 100644 index a98d2baf..00000000 --- a/examples/win32/history_qhsm/Makefile +++ /dev/null @@ -1,259 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, History with QHsm console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := history_qhsm - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - main.c \ - history.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/history_qmsm/Makefile b/examples/win32/history_qmsm/Makefile deleted file mode 100644 index 8bcbba3a..00000000 --- a/examples/win32/history_qmsm/Makefile +++ /dev/null @@ -1,259 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, History with QMsm console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := history_qmsm - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - main.c \ - history.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/history_qmsm/history.sln b/examples/win32/history_qmsm/history.sln deleted file mode 100644 index e41a70fb..00000000 --- a/examples/win32/history_qmsm/history.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "history", "history.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - QSpy|Win32 = QSpy|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.ActiveCfg = Release|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.Build.0 = Release|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.ActiveCfg = QSpy|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.Build.0 = QSpy|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/examples/win32/qhsmtst/Makefile b/examples/win32/qhsmtst/Makefile deleted file mode 100644 index 60f90917..00000000 --- a/examples/win32/qhsmtst/Makefile +++ /dev/null @@ -1,250 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, QHsmTst console, Win32, MinGW -# Last Updated for Version: 6.3.0 -# Date of the Last Update: 2018-05-07 -# -# 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://www.state-machine.com -# mailto:info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := qhsmtst - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - main.c \ - qhsmtst.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/qhsmtst/qhsmtst.vcxproj.filters b/examples/win32/qhsmtst/qhsmtst.vcxproj.filters deleted file mode 100644 index f07cc67e..00000000 --- a/examples/win32/qhsmtst/qhsmtst.vcxproj.filters +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - {76cb74d9-2f6d-42d1-98bb-e99763c51a65} - - - - - QP - - - QP - - - QP - - - \ No newline at end of file diff --git a/examples/win32/qmsmtst/Makefile b/examples/win32/qmsmtst/Makefile deleted file mode 100644 index cdfb17e4..00000000 --- a/examples/win32/qmsmtst/Makefile +++ /dev/null @@ -1,250 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, QMsmTst console, Win32, MinGW -# Last Updated for Version: 6.3.0 -# Date of the Last Update: 2018-05-07 -# -# 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://www.state-machine.com -# mailto:info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := qmsmtst - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - main.c \ - qmsmtst.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/reminder/Makefile b/examples/win32/reminder/Makefile deleted file mode 100644 index b93d1d20..00000000 --- a/examples/win32/reminder/Makefile +++ /dev/null @@ -1,259 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Reminder Pattern console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := reminder - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - reminder.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/reminder/bsp.c b/examples/win32/reminder/bsp.c deleted file mode 100644 index d47736d8..00000000 --- a/examples/win32/reminder/bsp.c +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP, MinGW -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - BSP_onKeyboardInput(_getch()); - } -} -/*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - QF_stop(); -} - diff --git a/examples/win32/reminder/bsp.h b/examples/win32/reminder/bsp.h deleted file mode 100644 index 6a1dd357..00000000 --- a/examples/win32/reminder/bsp.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last updated for version 5.4.2 -* Last updated on 2015-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com -*****************************************************************************/ -#ifndef bsp_h -#define bsp_h - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char *argv[]); -void BSP_onKeyboardInput(uint8_t key); /* process the keyboard scan code */ - -#endif /* bsp_h */ diff --git a/examples/win32/reminder2/Makefile b/examples/win32/reminder2/Makefile deleted file mode 100644 index 2dc43c53..00000000 --- a/examples/win32/reminder2/Makefile +++ /dev/null @@ -1,259 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C, Reminder2 Pattern console, Win32, MinGW -# Last Updated for Version: 5.6.4 -# Date of the Last Update: 2016-05-04 -# -# 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: -# Web: www.state-machine.com -# Email: info@state-machine.com -############################################################################## -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# -# cleaning configurations: Debug (default), Release, and Spy -# make clean -# make CONF=rel clean -# make CONF=spy clean -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# - -#----------------------------------------------------------------------------- -# project name -# -PROJECT := reminder2 - -#----------------------------------------------------------------------------- -# project directories -# - -# location of the QP/C framework (if not provided in an environemnt var.) -ifeq ($(QPC),) -QPC := ../../.. -endif - -# QP port used in this project -QP_PORT_DIR := $(QPC)/ports/win32 - -# list of all source directories used by this project -VPATH = \ - . \ - -# list of all include directories needed by this project -INCLUDES = \ - -I. \ - -I$(QPC)/include - -# list of resource include directories needed by this project -RCINCLUDES = \ - -IRes - - -#----------------------------------------------------------------------------- -# files -# - -# C source files... -C_SRCS := \ - bsp.c \ - reminder2.c - -# C++ source files... -CPP_SRCS := - -# Resource files... -RC_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -#----------------------------------------------------------------------------- -# MinGW toolset (NOTE: assumed to be on your PATH) -# -# NOTE: -# MinGW toolset is included in the Qtools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/Qtools/ -# -# NOTE: -# This Makefile assumes that the windres utility is available on the -# PATH (NOTE: windres is available in the Qtools collection for Windows) -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs -RC := windres - -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools - -MKDIR := mkdir -RM := rm - -#----------------------------------------------------------------------------- -# build options for various configurations -# - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := rel - -CFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -ffunction-sections -fdata-sections \ - -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -# make sure that QTOOLS exists... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable) -endif - -INCLUDES += -I$(QTOOLS)/qspy/include -VPATH += $(QTOOLS)/qspy/source -C_SRCS += qspy.c - -BIN_DIR := spy - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration .......................................... - -BIN_DIR := dbg - -CFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -CPPFLAGS = -g -ffunction-sections -fdata-sections \ - -O -Wall -W $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections - -# is it a GUI application (any GUI resources provided?) ... -ifneq (,$(RC_SRCS)) -LINKFLAGS += -mwindows -DEFINES += -DQWIN_GUI -endif - -#----------------------------------------------------------------------------- - -# combine all the soruces... -INCLUDES += -I$(QP_PORT_DIR) -LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR) -LIBS += -lqp - -C_OBJS := $(patsubst %.c, %.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS)) -RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS)) - -TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin -TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) -RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS)) - -# create $(BIN_DIR) if it does not exist -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif - -#----------------------------------------------------------------------------- -# rules -# - -all: $(TARGET_EXE) -#all: $(TARGET_BIN) - -$(TARGET_BIN): $(TARGET_EXE) - $(BIN) -O binary $< $@ - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT) - $(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -$(BIN_DIR)/%.o : %.rc - $(RC) $(RCINCLUDES) -i $< -o $@ - -# include dependency files only if our goal depends on their existence -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif -endif - -.PHONY : clean -clean: - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(BIN_DIR)/*.exe \ - $(BIN_DIR)/*.map - -show: - @echo PROJECT = $(PROJECT) - @echo CONF = $(CONF) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo RC_OBJS_EXT = $(RC_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) diff --git a/examples/win32/reminder2/bsp.c b/examples/win32/reminder2/bsp.c deleted file mode 100644 index d47736d8..00000000 --- a/examples/win32/reminder2/bsp.c +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP, MinGW -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 -* -* 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 -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include -#include -#include -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - BSP_onKeyboardInput(_getch()); - } -} -/*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - QF_stop(); -} - diff --git a/examples/win32/reminder2/bsp.h b/examples/win32/reminder2/bsp.h deleted file mode 100644 index 6a1dd357..00000000 --- a/examples/win32/reminder2/bsp.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last updated for version 5.4.2 -* Last updated on 2015-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com -*****************************************************************************/ -#ifndef bsp_h -#define bsp_h - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char *argv[]); -void BSP_onKeyboardInput(uint8_t key); /* process the keyboard scan code */ - -#endif /* bsp_h */ diff --git a/examples/workstation/README.txt b/examples/workstation/README.txt new file mode 100644 index 00000000..d5509004 --- /dev/null +++ b/examples/workstation/README.txt @@ -0,0 +1,106 @@ +ABOUT THE "Workstation" EXAMPLES +================================ +The examples in the "workstation" directory can be built on any workstation +(Windows, Linux, and MacOS). The provided Makefiles support the +GNU GCC toolchain. + +*** NOTE *** +For Windows, the make utility and the GNU GCC toolchain (MinGW) are provided +in the QTools collection, which is available for a separate download from: + +http://sourceforge.net/projects/qpc/files/QTools/ + +*** NOTE *** +The code can be also built with other tools as well, such as the +Microsoft Visual Studio 2013 and newer. + + +The QP/C Code +============= +For Windows, the QP/C framework used in the examples comes pre-compiled +into a library. + +For POSIX platforms (Linux and MacOS), the QP/C framework is built from +sources in every provided project. + + +Single-Threaded and Multi-Threaded QP/C Ports +--------------------------------------------- +Each of the examples can be linked to either the single-threaded QP/C ports +(win32-qv or posix-qv) or multi-threaded ports (win32 or posix). The choice +is made in the Makefiles, by editing the line, which defines the +QP_PORT_DIR symbol. For example, the following lines select the win32-qv +port and leave the win32 port commented-out: + +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 + +To reverse the selection, you need to move the comment '#' character. + +*** NOTE *** +The single-threaded QP/C ports (win32-qv and posix-qv) are recommended for +emulating software intended for deeply-embedded targets. + +The multi-threaded QP/C ports (win32 and posix) are intended for the +actual applications that run on (embedded)Windows or (embedded)Linux. + + +Debug, Release, and Spy Build Configurations +============================================ +The Makefiles for the examples generally support the following three build +configurations: + +Debug Configuration +------------------- +This is the default build configuration, with full debugging information and +minimal optimization. To build this configuration, type: + +make + +To clean this build, type + +make clean + +The object files and the executable is located in the 'build' sub-directory. + + +Release Configuration +--------------------- +This configuration is built with no debugging information and high +optimization. Single-stepping and debugging might be difficult due +to the lack of debugging information and optimized code. To build +this configuration, type: + +make CONF=rel + +To clean this build, type + +make CONF=rel clean + +The object files and the executable is located in the 'build_rel' directory. + +Spy Configuration +----------------- +This configuration is built with the QP's Q-SPY trace functionality. +The QP/Spy output is performed by a TCP/IP socket and requires launching +the QSPY host application with the -t option. To build this configuration, +type: + +make CONF=spy + +To clean this build, type + +make CONF=spy clean + +The object files and the executable are located in the 'build_spy' directory. + +*** NOTE *** +Only specific examples support the Spy build configuration. The examples +that don't support it, will report an error or will fail the linking stage. + + +Support and Contact Information +=============================== +https://sourceforge.net/p/qpc/discussion/668726/ +https://www.state-machine.com +info@state-machine.com diff --git a/examples/workstation/blinky/Makefile b/examples/workstation/blinky/Makefile new file mode 100644 index 00000000..60a005b3 --- /dev/null +++ b/examples/workstation/blinky/Makefile @@ -0,0 +1,285 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := blinky + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + blinky.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/posix/blinky/README.txt b/examples/workstation/blinky/README.txt similarity index 77% rename from examples/posix/blinky/README.txt rename to examples/workstation/blinky/README.txt index 536ddb72..e20a39a0 100644 --- a/examples/posix/blinky/README.txt +++ b/examples/workstation/blinky/README.txt @@ -7,4 +7,4 @@ Specifically the files are as follows: blinky.qm - the QM model for the Blinky active object blinky.c - the generated code for the Blinky application -Makefile - Makefile for building Blinky on Linux +Makefile - the makefile to build Blinky on Windows/Linux/MaxOS diff --git a/examples/win32/blinky/blinky.c b/examples/workstation/blinky/blinky.c similarity index 98% rename from examples/win32/blinky/blinky.c rename to examples/workstation/blinky/blinky.c index 9a49158c..28dc73b5 100644 --- a/examples/win32/blinky/blinky.c +++ b/examples/workstation/blinky/blinky.c @@ -3,7 +3,7 @@ * Model: blinky.qm * File: ${.::blinky.c} * -* This code has been generated by QM 4.3.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/win32/blinky/blinky.qm b/examples/workstation/blinky/blinky.qm similarity index 98% rename from examples/win32/blinky/blinky.qm rename to examples/workstation/blinky/blinky.qm index ed23b0ab..3165a028 100644 --- a/examples/win32/blinky/blinky.qm +++ b/examples/workstation/blinky/blinky.qm @@ -1,5 +1,5 @@ - + Blinky model diff --git a/examples/workstation/calc/Makefile b/examples/workstation/calc/Makefile new file mode 100644 index 00000000..f39ba2d7 --- /dev/null +++ b/examples/workstation/calc/Makefile @@ -0,0 +1,287 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := calc + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + main.c \ + calc.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/calc1/bsp.c b/examples/workstation/calc/bsp.c similarity index 83% rename from examples/win32/calc1/bsp.c rename to examples/workstation/calc/bsp.c index 70e9a177..569a496f 100644 --- a/examples/win32/calc1/bsp.c +++ b/examples/workstation/calc/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 5.4.0 -* Last updated on 2015-04-26 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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, www.state-machine.com. +* 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,9 +28,10 @@ * along with this program. If not, see . * * Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ +#include "qpc.h" #include "bsp.h" #include @@ -72,9 +73,10 @@ void BSP_display(void) { } /*..........................................................................*/ void BSP_exit(void) { - printf("\nBye! Bye!"); + printf("\nBye! Bye!\n"); fflush(stdout); - _exit(0); + QF_onCleanup(); + exit(0); } /*..........................................................................*/ double BSP_get_value(void) { @@ -126,9 +128,23 @@ int BSP_eval(double operand1, int oper, double operand2) { void BSP_message(char const *msg) { printf(msg); } + +/*..........................................................................*/ +void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { +} + /*..........................................................................*/ /* this function is used by the QP embedded systems-friendly assertions */ void Q_onAssert(char const * const file, int line) { printf("Assertion failed in %s, line %d", file, line); - _exit(-1); + QF_onCleanup(); + exit(-1); } diff --git a/examples/win32/calc/bsp.h b/examples/workstation/calc/bsp.h similarity index 100% rename from examples/win32/calc/bsp.h rename to examples/workstation/calc/bsp.h diff --git a/examples/win32/calc/calc.c b/examples/workstation/calc/calc.c similarity index 100% rename from examples/win32/calc/calc.c rename to examples/workstation/calc/calc.c diff --git a/examples/win32/calc/calc.h b/examples/workstation/calc/calc.h similarity index 100% rename from examples/win32/calc/calc.h rename to examples/workstation/calc/calc.h diff --git a/examples/win32/calc/calc.qm b/examples/workstation/calc/calc.qm similarity index 100% rename from examples/win32/calc/calc.qm rename to examples/workstation/calc/calc.qm diff --git a/examples/win32/calc/main.c b/examples/workstation/calc/main.c similarity index 88% rename from examples/win32/calc/main.c rename to examples/workstation/calc/main.c index 82f5c81b..aaa757a6 100644 --- a/examples/win32/calc/main.c +++ b/examples/workstation/calc/main.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: calc Example -* Last Updated for Version: 5.8.0 -* Date of the Last Update: 2016-11-29 +* Product: calc1_sub Example +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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) 2002-2016 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,20 +28,20 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com -* mailto:info@quantum-leaps.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ -#include "qep_port.h" +#include "qpc.h" #include "bsp.h" #include "calc.h" #include -#include -#include /*..........................................................................*/ int main() { - Calc_ctor(); /* explicitly instantiate the calculator object */ + + QF_init(); + QF_onStartup(); printf("Calculator example, QEP version: %s\n" "Press '0' .. '9' to enter a digit\n" @@ -56,6 +56,7 @@ int main() { "Press to quit.\n\n", QEP_getVersion()); + Calc_ctor(); /* explicitly instantiate the calculator object */ QHSM_INIT(the_calc, (QEvt *)0); /* trigger initial transition */ for (;;) { /* event loop */ @@ -65,8 +66,8 @@ int main() { printf(": "); fflush(stdout); - e.key_code = (uint8_t)_getche(); /* get a char with echo */ - printf(" "); + e.key_code = (uint8_t)QF_consoleWaitForKey(); + printf("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); switch (e.key_code) { case 'c': /* intentionally fall through */ @@ -125,5 +126,7 @@ int main() { QHSM_DISPATCH(the_calc, (QEvt *)&e); /* dispatch event */ } } + + QF_onCleanup(); return 0; } diff --git a/examples/workstation/calc1/Makefile b/examples/workstation/calc1/Makefile new file mode 100644 index 00000000..3d9c19b6 --- /dev/null +++ b/examples/workstation/calc1/Makefile @@ -0,0 +1,287 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := calc1 + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + main.c \ + calc1.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/calc1_sub/bsp.c b/examples/workstation/calc1/bsp.c similarity index 83% rename from examples/win32/calc1_sub/bsp.c rename to examples/workstation/calc1/bsp.c index 70e9a177..4a190357 100644 --- a/examples/win32/calc1_sub/bsp.c +++ b/examples/workstation/calc1/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 5.4.0 -* Last updated on 2015-04-26 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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, www.state-machine.com. +* 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,10 +28,11 @@ * along with this program. If not, see . * * Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ #include "bsp.h" +#include "qpc.h" #include #include @@ -72,9 +73,10 @@ void BSP_display(void) { } /*..........................................................................*/ void BSP_exit(void) { - printf("\nBye! Bye!"); + printf("\nBye! Bye!\n"); fflush(stdout); - _exit(0); + QF_onCleanup(); + exit(0); } /*..........................................................................*/ double BSP_get_value(void) { @@ -126,9 +128,22 @@ int BSP_eval(double operand1, int oper, double operand2) { void BSP_message(char const *msg) { printf(msg); } + +/*..........................................................................*/ +void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { +} + /*..........................................................................*/ /* this function is used by the QP embedded systems-friendly assertions */ void Q_onAssert(char const * const file, int line) { printf("Assertion failed in %s, line %d", file, line); - _exit(-1); + exit(-1); } diff --git a/examples/win32/calc1/bsp.h b/examples/workstation/calc1/bsp.h similarity index 100% rename from examples/win32/calc1/bsp.h rename to examples/workstation/calc1/bsp.h diff --git a/examples/win32/calc1/calc1.c b/examples/workstation/calc1/calc1.c similarity index 100% rename from examples/win32/calc1/calc1.c rename to examples/workstation/calc1/calc1.c diff --git a/examples/win32/calc1/calc1.h b/examples/workstation/calc1/calc1.h similarity index 100% rename from examples/win32/calc1/calc1.h rename to examples/workstation/calc1/calc1.h diff --git a/examples/win32/calc1/calc1.qm b/examples/workstation/calc1/calc1.qm similarity index 100% rename from examples/win32/calc1/calc1.qm rename to examples/workstation/calc1/calc1.qm diff --git a/examples/win32/calc1/main.c b/examples/workstation/calc1/main.c similarity index 88% rename from examples/win32/calc1/main.c rename to examples/workstation/calc1/main.c index c2fd03f0..4d28da7b 100644 --- a/examples/win32/calc1/main.c +++ b/examples/workstation/calc1/main.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: calc1 Example -* Last Updated for Version: 5.8.0 -* Date of the Last Update: 2016-11-29 +* Product: calc1_sub Example +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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) 2002-2016 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,20 +28,20 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com -* mailto:info@quantum-leaps.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ -#include "qep_port.h" +#include "qpc.h" #include "bsp.h" #include "calc1.h" #include -#include -#include /*..........................................................................*/ int main() { - Calc_ctor(); /* explicitly instantiate the calculator object */ + + QF_init(); + QF_onStartup(); printf("Calculator example, QEP version: %s\n" "Press '0' .. '9' to enter a digit\n" @@ -56,6 +56,7 @@ int main() { "Press to quit.\n\n", QEP_getVersion()); + Calc_ctor(); /* explicitly instantiate the calculator object */ QHSM_INIT(the_calc, (QEvt *)0); /* trigger initial transition */ for (;;) { /* event loop */ @@ -65,8 +66,8 @@ int main() { printf(": "); fflush(stdout); - e.key_code = (uint8_t)_getche(); /* get a char with echo */ - printf(" "); + e.key_code = (uint8_t)QF_consoleWaitForKey(); + printf("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); switch (e.key_code) { case 'c': /* intentionally fall through */ @@ -125,5 +126,7 @@ int main() { QHSM_DISPATCH(the_calc, (QEvt *)&e); /* dispatch event */ } } + + QF_onCleanup(); return 0; } diff --git a/examples/workstation/calc1_sub/Makefile b/examples/workstation/calc1_sub/Makefile new file mode 100644 index 00000000..db05a884 --- /dev/null +++ b/examples/workstation/calc1_sub/Makefile @@ -0,0 +1,287 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := calc1_sub + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + main.c \ + calc1_sub.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/calc1_sub/SM of Calc.png b/examples/workstation/calc1_sub/SM of Calc.png similarity index 100% rename from examples/win32/calc1_sub/SM of Calc.png rename to examples/workstation/calc1_sub/SM of Calc.png diff --git a/examples/win32/calc1_sub/SubM operand of Calc.png b/examples/workstation/calc1_sub/SubM operand of Calc.png similarity index 100% rename from examples/win32/calc1_sub/SubM operand of Calc.png rename to examples/workstation/calc1_sub/SubM operand of Calc.png diff --git a/examples/win32/calc/bsp.c b/examples/workstation/calc1_sub/bsp.c similarity index 83% rename from examples/win32/calc/bsp.c rename to examples/workstation/calc1_sub/bsp.c index 70e9a177..4a190357 100644 --- a/examples/win32/calc/bsp.c +++ b/examples/workstation/calc1_sub/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 5.4.0 -* Last updated on 2015-04-26 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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, www.state-machine.com. +* 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,10 +28,11 @@ * along with this program. If not, see . * * Contact information: -* Web: www.state-machine.com -* Email: info@state-machine.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ #include "bsp.h" +#include "qpc.h" #include #include @@ -72,9 +73,10 @@ void BSP_display(void) { } /*..........................................................................*/ void BSP_exit(void) { - printf("\nBye! Bye!"); + printf("\nBye! Bye!\n"); fflush(stdout); - _exit(0); + QF_onCleanup(); + exit(0); } /*..........................................................................*/ double BSP_get_value(void) { @@ -126,9 +128,22 @@ int BSP_eval(double operand1, int oper, double operand2) { void BSP_message(char const *msg) { printf(msg); } + +/*..........................................................................*/ +void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { +} + /*..........................................................................*/ /* this function is used by the QP embedded systems-friendly assertions */ void Q_onAssert(char const * const file, int line) { printf("Assertion failed in %s, line %d", file, line); - _exit(-1); + exit(-1); } diff --git a/examples/win32/calc1_sub/bsp.h b/examples/workstation/calc1_sub/bsp.h similarity index 100% rename from examples/win32/calc1_sub/bsp.h rename to examples/workstation/calc1_sub/bsp.h diff --git a/examples/win32/calc1_sub/calc1_sub.c b/examples/workstation/calc1_sub/calc1_sub.c similarity index 100% rename from examples/win32/calc1_sub/calc1_sub.c rename to examples/workstation/calc1_sub/calc1_sub.c diff --git a/examples/win32/calc1_sub/calc1_sub.h b/examples/workstation/calc1_sub/calc1_sub.h similarity index 100% rename from examples/win32/calc1_sub/calc1_sub.h rename to examples/workstation/calc1_sub/calc1_sub.h diff --git a/examples/win32/calc1_sub/calc1_sub.qm b/examples/workstation/calc1_sub/calc1_sub.qm similarity index 100% rename from examples/win32/calc1_sub/calc1_sub.qm rename to examples/workstation/calc1_sub/calc1_sub.qm diff --git a/examples/win32/calc1_sub/main.c b/examples/workstation/calc1_sub/main.c similarity index 88% rename from examples/win32/calc1_sub/main.c rename to examples/workstation/calc1_sub/main.c index fa08f462..ca237fb5 100644 --- a/examples/win32/calc1_sub/main.c +++ b/examples/workstation/calc1_sub/main.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: calc1_sub Example -* Last Updated for Version: 5.8.0 -* Date of the Last Update: 2016-11-29 +* Product: calc1_sub Example +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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) 2002-2016 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,20 +28,20 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com -* mailto:info@quantum-leaps.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ -#include "qep_port.h" +#include "qpc.h" #include "bsp.h" #include "calc1_sub.h" #include -#include -#include /*..........................................................................*/ int main() { - Calc_ctor(); /* explicitly instantiate the calculator object */ + + QF_init(); + QF_onStartup(); printf("Calculator example, QEP version: %s\n" "Press '0' .. '9' to enter a digit\n" @@ -56,6 +56,7 @@ int main() { "Press to quit.\n\n", QEP_getVersion()); + Calc_ctor(); /* explicitly instantiate the calculator object */ QHSM_INIT(the_calc, (QEvt *)0); /* trigger initial transition */ for (;;) { /* event loop */ @@ -65,8 +66,8 @@ int main() { printf(": "); fflush(stdout); - e.key_code = (uint8_t)_getche(); /* get a char with echo */ - printf(" "); + e.key_code = (uint8_t)QF_consoleWaitForKey(); + printf("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); switch (e.key_code) { case 'c': /* intentionally fall through */ @@ -125,5 +126,7 @@ int main() { QHSM_DISPATCH(the_calc, (QEvt *)&e); /* dispatch event */ } } + + QF_onCleanup(); return 0; } diff --git a/examples/workstation/comp/Makefile b/examples/workstation/comp/Makefile new file mode 100644 index 00000000..4b1a8097 --- /dev/null +++ b/examples/workstation/comp/Makefile @@ -0,0 +1,288 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := comp + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + main.c \ + bsp.c \ + alarm.c \ + clock.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/comp_qm/alarm.c b/examples/workstation/comp/alarm.c similarity index 75% rename from examples/win32/comp_qm/alarm.c rename to examples/workstation/comp/alarm.c index 7ac82255..c535f1dc 100644 --- a/examples/win32/comp_qm/alarm.c +++ b/examples/workstation/comp/alarm.c @@ -1,8 +1,9 @@ -/***************************************************************************** +/*$file${.::alarm.c} #######################################################*/ +/* * Model: comp.qm -* File: ./alarm.c +* File: ${.::alarm.c} * -* This code has been generated by QM tool (see state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -13,29 +14,31 @@ * 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. -*****************************************************************************/ -/*${.::alarm.c} ............................................................*/ +*/ +/*$endhead${.::alarm.c} ####################################################*/ #include "qpc.h" #include "bsp.h" #include "alarm.h" #include "clock.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* Alarm component --------------------*/ - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required +/* Check for the minimum required QP version */ +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 6.3.0 or higher required #endif +/*$define${Components::Alarm} ##############################################*/ /*${Components::Alarm} .....................................................*/ /*${Components::Alarm::ctor} ...............................................*/ void Alarm_ctor(Alarm * const me) { QHsm_ctor(&me->super, Q_STATE_CAST(&Alarm_initial)); } + /*${Components::Alarm::SM} .................................................*/ QState Alarm_initial(Alarm * const me, QEvt const * const e) { - /* ${Components::Alarm::SM::initial} */ + /*${Components::Alarm::SM::initial} */ me->alarm_time = 12U*60U; (void)e; /* avoid compiler warning about unused parameter */ return Q_TRAN(&Alarm_off); @@ -44,7 +47,7 @@ QState Alarm_initial(Alarm * const me, QEvt const * const e) { QState Alarm_off(Alarm * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${Components::Alarm::SM::off} */ + /*${Components::Alarm::SM::off} */ case Q_ENTRY_SIG: { /* while in the off state, the alarm is kept in decimal format */ me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; @@ -52,22 +55,22 @@ QState Alarm_off(Alarm * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /* ${Components::Alarm::SM::off} */ + /*${Components::Alarm::SM::off} */ case Q_EXIT_SIG: { /* upon exit, the alarm is converted to binary format */ me->alarm_time = (me->alarm_time/100U)*60U + me->alarm_time%100U; status_ = Q_HANDLED(); break; } - /* ${Components::Alarm::SM::off::ALARM_ON} */ + /*${Components::Alarm::SM::off::ALARM_ON} */ case ALARM_ON_SIG: { - /* ${Components::Alarm::SM::off::ALARM_ON::[alarminrange?]} */ + /*${Components::Alarm::SM::off::ALARM_ON::[alarminrange?]} */ if ((me->alarm_time / 100U < 24U) && (me->alarm_time % 100U < 60U)) { status_ = Q_TRAN(&Alarm_on); } - /* ${Components::Alarm::SM::off::ALARM_ON::[else]} */ + /*${Components::Alarm::SM::off::ALARM_ON::[else]} */ else { me->alarm_time = 0U; BSP_showTime24H("*** Alarm reset", me->alarm_time, 100U); @@ -75,7 +78,7 @@ QState Alarm_off(Alarm * const me, QEvt const * const e) { } break; } - /* ${Components::Alarm::SM::off::ALARM_SET} */ + /*${Components::Alarm::SM::off::ALARM_SET} */ case ALARM_SET_SIG: { /* while setting, the alarm is kept in decimal format */ me->alarm_time = (10U * me->alarm_time @@ -95,26 +98,26 @@ QState Alarm_off(Alarm * const me, QEvt const * const e) { QState Alarm_on(Alarm * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${Components::Alarm::SM::on} */ + /*${Components::Alarm::SM::on} */ case Q_ENTRY_SIG: { BSP_showTime24H("*** Alarm ON ", me->alarm_time, 60U); status_ = Q_HANDLED(); break; } - /* ${Components::Alarm::SM::on::ALARM_OFF} */ + /*${Components::Alarm::SM::on::ALARM_OFF} */ case ALARM_OFF_SIG: { status_ = Q_TRAN(&Alarm_off); break; } - /* ${Components::Alarm::SM::on::ALARM_SET} */ + /*${Components::Alarm::SM::on::ALARM_SET} */ case ALARM_SET_SIG: { BSP_showMsg("*** Cannot set Alarm when it is ON"); status_ = Q_HANDLED(); break; } - /* ${Components::Alarm::SM::on::TIME} */ + /*${Components::Alarm::SM::on::TIME} */ case TIME_SIG: { - /* ${Components::Alarm::SM::on::TIME::[Q_EVT_CAST(TimeEvt)->current_ti~} */ + /*${Components::Alarm::SM::on::TIME::[Q_EVT_CAST(TimeEvt)->current_ti~} */ if (Q_EVT_CAST(TimeEvt)->current_time == me->alarm_time) { BSP_showMsg("ALARM!!!"); @@ -134,4 +137,4 @@ QState Alarm_on(Alarm * const me, QEvt const * const e) { } return status_; } - +/*$enddef${Components::Alarm} ##############################################*/ diff --git a/examples/win32/comp_qm/alarm.h b/examples/workstation/comp/alarm.h similarity index 62% rename from examples/win32/comp_qm/alarm.h rename to examples/workstation/comp/alarm.h index 9e777e36..3e846493 100644 --- a/examples/win32/comp_qm/alarm.h +++ b/examples/workstation/comp/alarm.h @@ -1,8 +1,9 @@ -/***************************************************************************** +/*$file${.::alarm.h} #######################################################*/ +/* * Model: comp.qm -* File: ./alarm.h +* File: ${.::alarm.h} * -* This code has been generated by QM tool (see state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -13,16 +14,12 @@ * 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. -*****************************************************************************/ -/*${.::alarm.h} ............................................................*/ +*/ +/*$endhead${.::alarm.h} ####################################################*/ #ifndef alarm_h #define alarm_h - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - +/*$declare${Components::Alarm} #############################################*/ /*${Components::Alarm} .....................................................*/ typedef struct { /* protected: */ @@ -39,9 +36,10 @@ void Alarm_ctor(Alarm * const me); QState Alarm_initial(Alarm * const me, QEvt const * const e); QState Alarm_off(Alarm * const me, QEvt const * const e); QState Alarm_on(Alarm * const me, QEvt const * const e); +/*$enddecl${Components::Alarm} #############################################*/ - +/*$declare${Components::Alarm::ctor} #######################################*/ void Alarm_ctor(Alarm * const me); +/*$enddecl${Components::Alarm::ctor} #######################################*/ - -#endif /* alarm_h */ +#endif /* alarm_h */ \ No newline at end of file diff --git a/examples/win32/comp_qm/bsp.c b/examples/workstation/comp/bsp.c similarity index 86% rename from examples/win32/comp_qm/bsp.c rename to examples/workstation/comp/bsp.c index a9589feb..b7cd4657 100644 --- a/examples/win32/comp_qm/bsp.c +++ b/examples/workstation/comp/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: Console-based BSP, MinGW -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 +* Product: Console-based BSP +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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,19 +28,17 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ #include "qpc.h" #include "clock.h" #include "bsp.h" -#include -#include #include -#include +#include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ void BSP_init(int argc, char *argv[]) { @@ -70,17 +68,20 @@ void BSP_showTime12H(char_t const *str, uint32_t time, uint32_t base) { } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ + QF_consoleSetup(); } /*..........................................................................*/ void QF_onCleanup(void) { printf("\nBye! Bye!\n"); + QF_consoleCleanup(); } /*..........................................................................*/ void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - BSP_onKeyboardInput(_getch()); + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ + int key = QF_consoleGetKey(); + if (key != 0) { /* any key pressed? */ + BSP_onKeyboardInput((uint8_t)key); } } /*..........................................................................*/ @@ -137,6 +138,6 @@ void BSP_onKeyboardInput(uint8_t key) { /*..........................................................................*/ void Q_onAssert(char const * const file, int line) { fprintf(stderr, "Assertion failed in %s, line %d", file, line); - QF_stop(); + exit(-1); } diff --git a/examples/win32/comp_qm/bsp.h b/examples/workstation/comp/bsp.h similarity index 100% rename from examples/win32/comp_qm/bsp.h rename to examples/workstation/comp/bsp.h diff --git a/examples/win32/comp_qm/clock.c b/examples/workstation/comp/clock.c similarity index 76% rename from examples/win32/comp_qm/clock.c rename to examples/workstation/comp/clock.c index e1d6b07b..22ac08a8 100644 --- a/examples/win32/comp_qm/clock.c +++ b/examples/workstation/comp/clock.c @@ -1,8 +1,9 @@ -/***************************************************************************** +/*$file${.::clock.c} #######################################################*/ +/* * Model: comp.qm -* File: ./clock.c +* File: ${.::clock.c} * -* This code has been generated by QM tool (see state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -13,8 +14,8 @@ * 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. -*****************************************************************************/ -/*${.::clock.c} ............................................................*/ +*/ +/*$endhead${.::clock.c} ####################################################*/ #include "qpc.h" #include "bsp.h" #include "alarm.h" @@ -22,14 +23,10 @@ #include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* Active object class -----------------------------------------------------*/ - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - +/*$declare${Components::AlarmClock} ########################################*/ /*${Components::AlarmClock} ................................................*/ typedef struct { /* protected: */ @@ -49,14 +46,23 @@ static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e); static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e); static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e); - +/*$enddecl${Components::AlarmClock} ########################################*/ /* Local objects -----------------------------------------------------------*/ static AlarmClock l_alarmClock; /* the single instance of the AO */ /* Global-scope objects ----------------------------------------------------*/ -QMActive * const APP_alarmClock = &l_alarmClock.super; /* "opaque" pointer */ +/* Check for the minimum required QP version */ +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 6.3.0 or higher required +#endif +/*$define${Components::APP_alarmClock} #####################################*/ +/*${Components::APP_alarmClock} ............................................*/ +QActive * const APP_alarmClock = &l_alarmClock.super; +/*$enddef${Components::APP_alarmClock} #####################################*/ + +/*$define${Components::AlarmClock_ctor} ####################################*/ /*${Components::AlarmClock_ctor} ...........................................*/ void AlarmClock_ctor(void) { AlarmClock * const me = &l_alarmClock; @@ -67,12 +73,14 @@ void AlarmClock_ctor(void) { /* private time event ctor */ QTimeEvt_ctorX(&me->timeEvt, &me->super, TICK_SIG, 0U); } +/*$enddef${Components::AlarmClock_ctor} ####################################*/ /*..........................................................................*/ +/*$define${Components::AlarmClock} #########################################*/ /*${Components::AlarmClock} ................................................*/ /*${Components::AlarmClock::SM} ............................................*/ static QState AlarmClock_initial(AlarmClock * const me, QEvt const * const e) { - /* ${Components::AlarmClock::SM::initial} */ + /*${Components::AlarmClock::SM::initial} */ (void)e; /* avoid compiler warning about unused parameter */ me->current_time = 0U; @@ -84,7 +92,7 @@ static QState AlarmClock_initial(AlarmClock * const me, QEvt const * const e) { static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${Components::AlarmClock::SM::timekeeping} */ + /*${Components::AlarmClock::SM::timekeeping} */ case Q_ENTRY_SIG: { /* periodic timeout every second */ QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC, @@ -92,34 +100,34 @@ static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e status_ = Q_HANDLED(); break; } - /* ${Components::AlarmClock::SM::timekeeping} */ + /*${Components::AlarmClock::SM::timekeeping} */ case Q_EXIT_SIG: { QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /* ${Components::AlarmClock::SM::timekeeping::initial} */ + /*${Components::AlarmClock::SM::timekeeping::initial} */ case Q_INIT_SIG: { status_ = Q_TRAN(&AlarmClock_mode24h); break; } - /* ${Components::AlarmClock::SM::timekeeping::CLOCK_24H} */ + /*${Components::AlarmClock::SM::timekeeping::CLOCK_24H} */ case CLOCK_24H_SIG: { status_ = Q_TRAN(&AlarmClock_mode24h); break; } - /* ${Components::AlarmClock::SM::timekeeping::CLOCK_12H} */ + /*${Components::AlarmClock::SM::timekeeping::CLOCK_12H} */ case CLOCK_12H_SIG: { status_ = Q_TRAN(&AlarmClock_mode12h); break; } - /* ${Components::AlarmClock::SM::timekeeping::ALARM} */ + /*${Components::AlarmClock::SM::timekeeping::ALARM} */ case ALARM_SIG: { BSP_showMsg("Wake up!!!"); status_ = Q_HANDLED(); break; } - /* ${Components::AlarmClock::SM::timekeeping::ALARM_SET, ALARM_ON, ALARM_OFF} */ + /*${Components::AlarmClock::SM::timekeeping::ALARM_SET, ALARM_ON, ALARM_OFF} */ case ALARM_SET_SIG: /* intentionally fall through */ case ALARM_ON_SIG: /* intentionally fall through */ case ALARM_OFF_SIG: { @@ -128,7 +136,7 @@ static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e status_ = Q_HANDLED(); break; } - /* ${Components::AlarmClock::SM::timekeeping::TERMINATE} */ + /*${Components::AlarmClock::SM::timekeeping::TERMINATE} */ case TERMINATE_SIG: { BSP_showMsg("--> final"); status_ = Q_TRAN(&AlarmClock_final); @@ -145,13 +153,13 @@ static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${Components::AlarmClock::SM::timekeeping::mode24h} */ + /*${Components::AlarmClock::SM::timekeeping::mode24h} */ case Q_ENTRY_SIG: { BSP_showMsg("*** 24-hour mode"); status_ = Q_HANDLED(); break; } - /* ${Components::AlarmClock::SM::timekeeping::mode24h::TICK} */ + /*${Components::AlarmClock::SM::timekeeping::mode24h::TICK} */ case TICK_SIG: { TimeEvt pe; /* temporary synchronous event for the component */ @@ -179,13 +187,13 @@ static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e) { static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${Components::AlarmClock::SM::timekeeping::mode12h} */ + /*${Components::AlarmClock::SM::timekeeping::mode12h} */ case Q_ENTRY_SIG: { BSP_showMsg("*** 12-hour mode"); status_ = Q_HANDLED(); break; } - /* ${Components::AlarmClock::SM::timekeeping::mode12h::TICK} */ + /*${Components::AlarmClock::SM::timekeeping::mode12h::TICK} */ case TICK_SIG: { TimeEvt pe; /* temporary synchronous event for the component */ @@ -213,7 +221,7 @@ static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e) { static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${Components::AlarmClock::SM::final} */ + /*${Components::AlarmClock::SM::final} */ case Q_ENTRY_SIG: { QF_stop(); /* terminate the application */ status_ = Q_HANDLED(); @@ -226,4 +234,4 @@ static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e) { } return status_; } - +/*$enddef${Components::AlarmClock} #########################################*/ diff --git a/examples/win32/comp_qm/clock.h b/examples/workstation/comp/clock.h similarity index 63% rename from examples/win32/comp_qm/clock.h rename to examples/workstation/comp/clock.h index cae83d35..7bbaba9e 100644 --- a/examples/win32/comp_qm/clock.h +++ b/examples/workstation/comp/clock.h @@ -1,8 +1,9 @@ -/***************************************************************************** +/*$file${.::clock.h} #######################################################*/ +/* * Model: comp.qm -* File: ./clock.h +* File: ${.::clock.h} * -* This code has been generated by QM tool (see state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -13,8 +14,8 @@ * 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. -*****************************************************************************/ -/*${.::clock.h} ............................................................*/ +*/ +/*$endhead${.::clock.h} ####################################################*/ #ifndef clock_h #define clock_h @@ -30,11 +31,7 @@ enum AlarmClockSignals { TERMINATE_SIG /* terminate the application */ }; - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - +/*$declare${Events::SetEvt} ################################################*/ /*${Events::SetEvt} ........................................................*/ typedef struct { /* protected: */ @@ -43,7 +40,8 @@ typedef struct { /* public: */ uint8_t digit; } SetEvt; - +/*$enddecl${Events::SetEvt} ################################################*/ +/*$declare${Events::TimeEvt} ###############################################*/ /*${Events::TimeEvt} .......................................................*/ typedef struct { /* protected: */ @@ -52,12 +50,14 @@ typedef struct { /* public: */ uint32_t current_time; } TimeEvt; +/*$enddecl${Events::TimeEvt} ###############################################*/ - +/*$declare${Components::APP_alarmClock} ####################################*/ extern QActive * const APP_alarmClock; - +/*$enddecl${Components::APP_alarmClock} ####################################*/ +/*$declare${Components::AlarmClock_ctor} ###################################*/ /*${Components::AlarmClock_ctor} ...........................................*/ void AlarmClock_ctor(void); +/*$enddecl${Components::AlarmClock_ctor} ###################################*/ ; - -#endif /* clock_h */ +#endif /* clock_h */ \ No newline at end of file diff --git a/examples/win32/comp_qm/comp.qm b/examples/workstation/comp/comp.qm similarity index 97% rename from examples/win32/comp_qm/comp.qm rename to examples/workstation/comp/comp.qm index 0579d58e..a11b4db0 100644 --- a/examples/win32/comp_qm/comp.qm +++ b/examples/workstation/comp/comp.qm @@ -1,8 +1,8 @@ - + Dining Philosopher Problem example -NOTE: Requries QP5. +NOTE: Requries QP6. @@ -219,6 +219,7 @@ QHSM_DISPATCH(&me->alarm.super, &pe.super); Opaque pointer to the single instance of the AlarmClock AO + = &l_alarmClock.super; AlarmClock * const me = &l_alarmClock; @@ -247,7 +248,7 @@ $declare(Components::Alarm::ctor) #include "alarm.h" #include "clock.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* Alarm component --------------------*/ $define(Components::Alarm) @@ -284,21 +285,22 @@ $declare(Components::AlarmClock_ctor); #include <stdio.h> -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* Active object class -----------------------------------------------------*/ -$declare(Components::AlarmClock) +$declare${Components::AlarmClock} /* Local objects -----------------------------------------------------------*/ static AlarmClock l_alarmClock; /* the single instance of the AO */ /* Global-scope objects ----------------------------------------------------*/ -QMActive * const APP_alarmClock = &l_alarmClock.super; /* "opaque" pointer */ +$define${Components::APP_alarmClock} -$define(Components::AlarmClock_ctor) +$define${Components::AlarmClock_ctor} /*..........................................................................*/ -$define(Components::AlarmClock) +$define${Components::AlarmClock} + diff --git a/examples/win32/comp_qm/main.c b/examples/workstation/comp/main.c similarity index 87% rename from examples/win32/comp_qm/main.c rename to examples/workstation/comp/main.c index 89c7ba21..b1648954 100644 --- a/examples/win32/comp_qm/main.c +++ b/examples/workstation/comp/main.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: "Orthogonal Component" example, Console based -* Last Updated for Version: 5.4.2 -* Date of the Last Update: 2015-06-03 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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. state-machine.com. +* 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,8 +28,8 @@ * along with this program. If not, see . * * Contact information: -* Web : https://state-machine.com -* Email: info@state-machine.com +* https://www.state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ #include "qpc.h" #include "alarm.h" @@ -43,7 +43,6 @@ int main(int argc, char *argv[]) { static QEvt const *l_alarmClockQSto[10]; /* queue storage for AlarmClock */ static QF_MPOOL_EL(TimeEvt) l_smlPoolSto[10]; /* storage for small pool */ - printf("Orthogonal Component pattern\nQP version: %s\n" "Press 'o' to turn the Alarm ON\n" "Press 'f' to turn the Alarm OFF\n" diff --git a/examples/workstation/defer/Makefile b/examples/workstation/defer/Makefile new file mode 100644 index 00000000..7f635efb --- /dev/null +++ b/examples/workstation/defer/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := defer + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + defer.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/defer/bsp.c b/examples/workstation/defer/bsp.c similarity index 73% rename from examples/win32/defer/bsp.c rename to examples/workstation/defer/bsp.c index d47736d8..75359ecb 100644 --- a/examples/win32/defer/bsp.c +++ b/examples/workstation/defer/bsp.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: Console-based BSP, MinGW -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 +* Product: Console-based BSP +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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,18 +28,16 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ #include "qpc.h" #include "bsp.h" -#include -#include #include -#include +#include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ void BSP_init(int argc, char *argv[]) { @@ -48,22 +46,28 @@ void BSP_init(int argc, char *argv[]) { } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ + QF_consoleSetup(); } /*..........................................................................*/ void QF_onCleanup(void) { printf("\nBye! Bye!\n"); + QF_consoleCleanup(); } /*..........................................................................*/ void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - BSP_onKeyboardInput(_getch()); + int key; + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ + + key = QF_consoleWaitForKey(); + if (key != 0) { /* any key pressed? */ + BSP_onKeyboardInput(key); } } /*..........................................................................*/ void Q_onAssert(char const * const file, int line) { fprintf(stderr, "Assertion failed in %s, line %d", file, line); - QF_stop(); + QF_onCleanup(); + exit(-1); } diff --git a/examples/win32-qv/reminder2/bsp.h b/examples/workstation/defer/bsp.h similarity index 100% rename from examples/win32-qv/reminder2/bsp.h rename to examples/workstation/defer/bsp.h diff --git a/examples/win32/defer/defer.c b/examples/workstation/defer/defer.c similarity index 97% rename from examples/win32/defer/defer.c rename to examples/workstation/defer/defer.c index 8958988c..5d7ba48c 100644 --- a/examples/win32/defer/defer.c +++ b/examples/workstation/defer/defer.c @@ -1,11 +1,11 @@ /***************************************************************************** * Product: Deferred Event state pattern example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-14 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -36,7 +36,7 @@ #include /* this example uses printf() to report status */ -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ enum TServerSignals { diff --git a/examples/workstation/dpp-comp/Makefile b/examples/workstation/dpp-comp/Makefile new file mode 100644 index 00000000..9bbaa531 --- /dev/null +++ b/examples/workstation/dpp-comp/Makefile @@ -0,0 +1,291 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := dpp + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + cont \ + comp + +# list of all include directories needed by this project +INCLUDES := -I. \ + -Icont + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/dpp-comp/bsp.c b/examples/workstation/dpp-comp/bsp.c similarity index 50% rename from examples/win32/dpp-comp/bsp.c rename to examples/workstation/dpp-comp/bsp.c index 8e24d527..74081238 100644 --- a/examples/win32/dpp-comp/bsp.c +++ b/examples/workstation/dpp-comp/bsp.c @@ -1,13 +1,13 @@ - /***************************************************************************** -* Product: DPP example, Windows (console) -* Last updated for version 6.0.1 -* Last updated on 2017-10-29 +/***************************************************************************** +* Product: DPP example (console) +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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,14 +28,13 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ #include "qpc.h" #include "dpp.h" #include "bsp.h" -#include #include #include @@ -48,40 +47,9 @@ static uint32_t l_rnd; /* random seed */ enum { PHILO_STAT = QS_USER }; - static uint8_t l_running; static uint8_t const l_clock_tick = 0U; #endif -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - printf("\nBye! Bye!\n"); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - int ch = _getch(); - if (ch == '\33') { /* see if the ESC key pressed */ - BSP_terminate(0); - } - else if (ch == 'p') { - QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - } - else if (ch == 's') { - QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - } - } -} -/*..........................................................................*/ -void Q_onAssert(char const * const module, int_t loc) { - QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ - fprintf(stderr, "Assertion failed in %s, line %d", module, loc); - exit(-1); -} /*..........................................................................*/ void BSP_init(int argc, char *argv[]) { (void)argc; @@ -96,16 +64,17 @@ void BSP_init(int argc, char *argv[]) { BSP_randomSeed(1234U); - Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : "")); + Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : (void *)0)); QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ QS_USR_DICTIONARY(PHILO_STAT); + + /* setup the QS filters... */ + QS_FILTER_ON(QS_ALL_RECORDS); + QS_FILTER_OFF(QS_QF_TICK); } /*..........................................................................*/ void BSP_terminate(int16_t result) { (void)result; -#ifdef Q_SPY - l_running = (uint8_t)0; /* stop the QS output thread */ -#endif QF_stop(); /* stop the main "ticker thread" */ } /*..........................................................................*/ @@ -134,113 +103,73 @@ void BSP_randomSeed(uint32_t seed) { l_rnd = seed; } -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -#include "qspy.h" -#include - -#define WIN32_LEAN_AND_MEAN -#include /* Win32 API for multithreading */ - -static uint8_t l_running; - +/****************************************************************************/ /*..........................................................................*/ -static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */ - (void)par; +void QF_onStartup(void) { + QF_consoleSetup(); + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* desired tick rate/ticker-prio */ +} +/*..........................................................................*/ +void QF_onCleanup(void) { + printf("\nBye! Bye!\n"); + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); - l_running = (uint8_t)1; - while (l_running) { - uint16_t nBytes = 256; - uint8_t const *block; - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - if (block != (uint8_t *)0) { - QSPY_parse(block, nBytes); + QS_RX_INPUT(); /* handle the QS-RX input */ + QS_OUTPUT(); /* handle the QS output */ + + switch (QF_consoleGetKey()) { + case '\33': { /* see if the ESC key pressed */ + BSP_terminate(0); + break; } - Sleep(10U); /* wait for a clock tick */ - } - return 0; /* return success */ -} -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* 4K buffer for Quantum Spy */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - - /* here 'arg' is ignored, but this command-line parameter can be used - * to setup the QSP_config(), to set up the QS filters, or for any - * other purpose. - */ - (void)arg; - - QSPY_config(QP_VERSION, // version - QS_OBJ_PTR_SIZE, // objPtrSize - QS_FUN_PTR_SIZE, // funPtrSize - QS_TIME_SIZE, // tstampSize - Q_SIGNAL_SIZE, // sigSize, - QF_EVENT_SIZ_SIZE, // evtSize - QF_EQUEUE_CTR_SIZE, // queueCtrSize - QF_MPOOL_CTR_SIZE, // poolCtrSize - QF_MPOOL_SIZ_SIZE, // poolBlkSize - QF_TIMEEVT_CTR_SIZE,// tevtCtrSize - (void *)0, // matFile, - (void *)0, // mscFile - (QSPY_CustParseFun)0); // no customized parser function - - /* 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(QS_QF_ACTIVE_POST_FIFO); - QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO); - QS_FILTER_ON(QS_QF_PUBLISH); - - QS_FILTER_ON(PHILO_STAT); - - return CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL) - != (HANDLE)0; /* return the status of creating the idle thread */ -} -/*..........................................................................*/ -void QS_onCleanup(void) { - l_running = (uint8_t)0; - QSPY_stop(); -} -/*..........................................................................*/ -void QS_onFlush(void) { - for (;;) { - uint16_t nBytes = 1024; - uint8_t const *block; - - QF_CRIT_ENTRY(dummy); - block = QS_getBlock(&nBytes); - QF_CRIT_EXIT(dummy); - - if (block != (uint8_t const *)0) { - QSPY_parse(block, nBytes); - nBytes = 1024; + case 'p': { + QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); + break; } - else { + case 's': { + QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); + break; + } + default: { break; } } } + +/*--------------------------------------------------------------------------*/ +#ifdef Q_SPY /* define QS callbacks */ + /*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -void QSPY_onPrintLn(void) { - fputs(QSPY_line, stdout); - fputc('\n', stdout); +/*! callback function to execute user commands */ +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + /* unused parameters */ + (void)param1; + (void)param2; + (void)param3; } + #endif /* Q_SPY */ /*--------------------------------------------------------------------------*/ + +/*..........................................................................*/ +void Q_onAssert(char const * const module, int_t loc) { + QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ + fprintf(stderr, "Assertion failed in %s:%d", module, loc); + QF_onCleanup(); + exit(-1); +} + diff --git a/examples/win32-qv/dpp/bsp.h b/examples/workstation/dpp-comp/bsp.h similarity index 100% rename from examples/win32-qv/dpp/bsp.h rename to examples/workstation/dpp-comp/bsp.h diff --git a/examples/win32/dpp-comp/comp/comp.qmp b/examples/workstation/dpp-comp/comp/comp.qmp similarity index 99% rename from examples/win32/dpp-comp/comp/comp.qmp rename to examples/workstation/dpp-comp/comp/comp.qmp index 075ef107..6cdaab54 100644 --- a/examples/win32/dpp-comp/comp/comp.qmp +++ b/examples/workstation/dpp-comp/comp/comp.qmp @@ -80,7 +80,7 @@ QACTIVE_POST_LIFO(AO_Table, &pe->super); #include "dpp.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* helper macros to provide a randomized think time for Philos */ #define THINK_TIME \ diff --git a/examples/win32/dpp-comp/comp/philo.c b/examples/workstation/dpp-comp/comp/philo.c similarity index 94% rename from examples/win32/dpp-comp/comp/philo.c rename to examples/workstation/dpp-comp/comp/philo.c index 0337c7ee..3a674978 100644 --- a/examples/win32/dpp-comp/comp/philo.c +++ b/examples/workstation/dpp-comp/comp/philo.c @@ -1,9 +1,9 @@ /*$file${Comp::.::philo.c} #################################################*/ /* * Model: dpp.qm -* File: C:/qp_lab/qpc/examples/win32/dpp-comp/comp/philo.c +* File: ${Comp::.::philo.c} * -* This code has been generated by QM tool (https://state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -20,7 +20,7 @@ #include "dpp.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /* helper macros to provide a randomized think time for Philos */ #define THINK_TIME \ @@ -29,11 +29,12 @@ Q_DEFINE_THIS_FILE (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) /* Philo definition --------------------------------------------------------*/ -/*$define${Comp::Philo} ####################################################*/ /* Check for the minimum required QP version */ -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 6.0.1 or higher required +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 6.3.0 or higher required #endif + +/*$define${Comp::Philo} ####################################################*/ /*${Comp::Philo} ...........................................................*/ /*${Comp::Philo::ctor} .....................................................*/ void Philo_ctor(Philo * const me) { diff --git a/examples/win32/dpp-comp/cont/cont.qmp b/examples/workstation/dpp-comp/cont/cont.qmp similarity index 100% rename from examples/win32/dpp-comp/cont/cont.qmp rename to examples/workstation/dpp-comp/cont/cont.qmp diff --git a/examples/win32/dpp-comp/cont/dpp.h b/examples/workstation/dpp-comp/cont/dpp.h similarity index 96% rename from examples/win32/dpp-comp/cont/dpp.h rename to examples/workstation/dpp-comp/cont/dpp.h index 12ada0aa..006bed1e 100644 --- a/examples/win32/dpp-comp/cont/dpp.h +++ b/examples/workstation/dpp-comp/cont/dpp.h @@ -1,9 +1,9 @@ /*$file${Cont::.::dpp.h} ###################################################*/ /* * Model: dpp.qm -* File: C:/qp_lab/qpc/examples/win32/dpp-comp/cont/dpp.h +* File: ${Cont::.::dpp.h} * -* This code has been generated by QM tool (https://state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/win32/dpp-comp/cont/table.c b/examples/workstation/dpp-comp/cont/table.c similarity index 97% rename from examples/win32/dpp-comp/cont/table.c rename to examples/workstation/dpp-comp/cont/table.c index fb791662..1b874d9e 100644 --- a/examples/win32/dpp-comp/cont/table.c +++ b/examples/workstation/dpp-comp/cont/table.c @@ -1,9 +1,9 @@ /*$file${Cont::.::table.c} #################################################*/ /* * Model: dpp.qm -* File: C:/qp_lab/qpc/examples/win32/dpp-comp/cont/table.c +* File: ${Cont::.::table.c} * -* This code has been generated by QM tool (https://state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -54,11 +54,12 @@ static Table l_table; /* the single instance of the Table active object */ QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ //............................................................................ -/*$define${Cont::CompTimeEvt} ##############################################*/ /* Check for the minimum required QP version */ -#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 6.0.1 or higher required +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 6.3.0 or higher required #endif + +/*$define${Cont::CompTimeEvt} ##############################################*/ /*${Cont::CompTimeEvt} .....................................................*/ /*${Cont::CompTimeEvt::ctor} ...............................................*/ void CompTimeEvt_ctor( diff --git a/examples/win32/dpp-comp/dpp.qm b/examples/workstation/dpp-comp/dpp.qm similarity index 95% rename from examples/win32/dpp-comp/dpp.qm rename to examples/workstation/dpp-comp/dpp.qm index 28f871aa..768cf4ec 100644 --- a/examples/win32/dpp-comp/dpp.qm +++ b/examples/workstation/dpp-comp/dpp.qm @@ -1,5 +1,5 @@ - + Dining Philosopher Problem example with the "Orthogonal Component" state pattern (see https://state-machine.com/doc/Pattern_Orthogonal.pdf) The model demonstrates the following features: diff --git a/examples/win32/dpp-comp/main.c b/examples/workstation/dpp-comp/main.c similarity index 97% rename from examples/win32/dpp-comp/main.c rename to examples/workstation/dpp-comp/main.c index 952c95d7..159cc47f 100644 --- a/examples/win32/dpp-comp/main.c +++ b/examples/workstation/dpp-comp/main.c @@ -49,10 +49,6 @@ int main(int argc, char *argv[]) { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(argc, argv); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/workstation/dpp-comp/qspyview/dpp.tcl b/examples/workstation/dpp-comp/qspyview/dpp.tcl new file mode 100644 index 00000000..97d6a517 --- /dev/null +++ b/examples/workstation/dpp-comp/qspyview/dpp.tcl @@ -0,0 +1,384 @@ +#----------------------------------------------------------------------------- +# Product: QSpyView -- Customization example for DPP application +# Last updated for version 6.2.0 +# Last updated on 2018-03-14 +# +# 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://www.state-machine.com +# mailto:info@state-machine.com +#----------------------------------------------------------------------------- + +# command handlers =========================================================== +proc onMyCommand {} { + # do something here, for example: + # - inject an event to the Target + # - send a command to the Target + # - peek memory + # - poke memory + # - exectute system tick in the Target + # - open a dialog box... + # - etc. + + # as an example, the following code sends a command to the Target + variable ::qspy::QS_RX + ::qspy::sendPkt [binary format cciii $qspy::QS_RX(COMMAND) 1 12345 0 0] +} + +proc onPause {} { + global theButtonId theBtnState + if {[string equal $theBtnState BTN_UP]} { ;# is DWN? + set theBtnState BTN_DWN + ::qspy::sendCurrObj SM_AO l_table + ::qspy::sendEvent 255 PAUSE_SIG + #::qspy::sendEvent 6 6 0 + } else { + set theBtnState BTN_UP + ::qspy::sendCurrObj SM_AO l_table + ::qspy::sendEvent 255 SERVE_SIG + #::qspy::sendEvent 6 7 0 + } + .canv.c itemconfigure $theButtonId -image ::img::$theBtnState +} + +# additinal menu options ===================================================== +.mbar.cust add command -label "MyCommand" -command onMyCommand + + +# specific canvas for DPP ==================================================== +set scriptFolder [file dirname [file normalize [info script]]] + +image create photo ::img::e -file $scriptFolder/img/eating.gif +image create photo ::img::h -file $scriptFolder/img/hungry.gif +image create photo ::img::t -file $scriptFolder/img/thinking.gif +image create photo ::img::BTN_UP -file $scriptFolder/img/BTN_UP.gif +image create photo ::img::BTN_DWN -file $scriptFolder/img/BTN_DWN.gif + +wm geometry .canv =400x260 +.canv.c configure -width 400 +.canv.c configure -height 260 + +set thePhiloId [.canv.c create image 190 57 -image ::img::t] +.canv.c create image 273 100 -image ::img::t +.canv.c create image 237 185 -image ::img::t +.canv.c create image 146 184 -image ::img::t +.canv.c create image 107 100 -image ::img::t + + +set theButtonId [.canv.c create image 200 120 -image ::img::BTN_UP] +set theBtnState BTN_UP +.canv.c bind $theButtonId onPause + +# QS record handlers ========================================================= + +# user record handlers [70..0x7C] -------------------------------------------- +proc ::qspy::rec70 {} { ;# QS_USER + variable thePkt + variable theFmt + binary scan $thePkt xx$theFmt(tstamp)xcxa* \ + ts philoNum stat + + dispTxt [format "%010u Philo %1d is %s" $ts $philoNum $stat] + + global thePhiloId + set img [string index $stat 0] + .canv.c itemconfigure [expr $thePhiloId + $philoNum] -image ::img::$img +} +#............................................................................. +proc ::qspy::rec71 {} { ;# QS_USER + 1 + variable thePkt + variable theFmt + binary scan $thePkt xc$theFmt(tstamp)xc \ + cmdId ts par + dispTxt [format "%010u cmd=%d param=%d" $ts $cmdId $par] +} + +proc ::qspy::rec72 {} { ;# QS_USER + 2 +} +proc ::qspy::rec73 {} { ;# QS_USER + 3 +} +proc ::qspy::rec74 {} { ;# QS_USER + 4 +} +proc ::qspy::rec75 {} { ;# QS_USER + 5 +} +proc ::qspy::rec76 {} { ;# QS_USER + 6 +} +proc ::qspy::rec77 {} { ;# QS_USER + 7 +} +proc ::qspy::rec78 {} { ;# QS_USER + 8 +} +proc ::qspy::rec79 {} { ;# QS_USER + 9 +} +proc ::qspy::rec80 {} { ;# QS_USER + 10 +} +proc ::qspy::rec81 {} { ;# QS_USER + 11 +} +proc ::qspy::rec82 {} { ;# QS_USER + 12 +} +proc ::qspy::rec83 {} { ;# QS_USER + 13 +} +proc ::qspy::rec84 {} { ;# QS_USER + 14 +} +proc ::qspy::rec85 {} { ;# QS_USER + 15 +} +proc ::qspy::rec86 {} { ;# QS_USER + 16 +} +proc ::qspy::rec87 {} { ;# QS_USER + 17 +} +proc ::qspy::rec88 {} { ;# QS_USER + 18 +} +proc ::qspy::rec89 {} { ;# QS_USER + 19 +} +proc ::qspy::rec90 {} { ;# QS_USER + 20 +} +proc ::qspy::rec91 {} { ;# QS_USER + 21 +} +proc ::qspy::rec92 {} { ;# QS_USER + 22 +} +proc ::qspy::rec93 {} { ;# QS_USER + 23 +} +proc ::qspy::rec94 {} { ;# QS_USER + 24 +} +proc ::qspy::rec95 {} { ;# QS_USER + 25 +} +proc ::qspy::rec96 {} { ;# QS_USER + 26 +} +proc ::qspy::rec97 {} { ;# QS_USER + 27 +} +proc ::qspy::rec98 {} { ;# QS_USER + 28 +} +proc ::qspy::rec99 {} { ;# QS_USER + 29 +} +proc ::qspy::rec100 {} { ;# QS_USER + 30 +} +proc ::qspy::rec101 {} { ;# QS_USER + 31 +} +proc ::qspy::rec102 {} { ;# QS_USER + 32 +} +proc ::qspy::rec103 {} { ;# QS_USER + 33 +} +proc ::qspy::rec104 {} { ;# QS_USER + 34 +} +proc ::qspy::rec105 {} { ;# QS_USER + 35 +} +proc ::qspy::rec106 {} { ;# QS_USER + 36 +} +proc ::qspy::rec107 {} { ;# QS_USER + 37 +} +proc ::qspy::rec108 {} { ;# QS_USER + 38 +} +proc ::qspy::rec109 {} { ;# QS_USER + 39 +} +proc ::qspy::rec110 {} { ;# QS_USER + 40 +} +proc ::qspy::rec111 {} { ;# QS_USER + 41 +} +proc ::qspy::rec112 {} { ;# QS_USER + 42 +} +proc ::qspy::rec113 {} { ;# QS_USER + 43 +} +proc ::qspy::rec114 {} { ;# QS_USER + 44 +} +proc ::qspy::rec115 {} { ;# QS_USER + 45 +} +proc ::qspy::rec116 {} { ;# QS_USER + 46 +} +proc ::qspy::rec117 {} { ;# QS_USER + 47 +} +proc ::qspy::rec118 {} { ;# QS_USER + 48 +} +proc ::qspy::rec119 {} { ;# QS_USER + 49 +} +proc ::qspy::rec120 {} { ;# QS_USER + 50 +} +proc ::qspy::rec121 {} { ;# QS_USER + 51 +} +proc ::qspy::rec122 {} { ;# QS_USER + 52 +} +proc ::qspy::rec123 {} { ;# QS_USER + 53 +} +proc ::qspy::rec124 {} { ;# QS_USER + 54 +} + + +# special record handlers ---------------------------------------------------- +proc ::qspy::recRESET {} { ;# target reset callback +} +proc ::qspy::recINFO {} { ;# target info callback +} + +# standard record handlers [1..54] ------------------------------------------- +proc ::qspy::rec0 {} { ;# QS_EMPTY +} + +# [1] QEP records... +proc ::qspy::rec1 {} { ;# QS_QEP_STATE_ENTRY +} +proc ::qspy::rec2 {} { ;# QS_QEP_STATE_EXIT +} +proc ::qspy::rec3 {} { ;# QS_QEP_STATE_INIT +} +proc ::qspy::rec4 {} { ;# QS_QEP_INIT_TRAN +} +proc ::qspy::rec5 {} { ;# QS_QEP_INTERN_TRAN +} +proc ::qspy::rec6 {} { ;# QS_QEP_TRAN +} +proc ::qspy::rec7 {} { ;# QS_QEP_IGNORED +} +proc ::qspy::rec8 {} { ;# QS_QEP_DISPATCH +} +proc ::qspy::rec9 {} { ;# QS_QEP_UNHANDLED +} + +# [10] QF records... +proc ::qspy::rec10 {} { ;# QS_QF_ACTIVE_ADD +} +proc ::qspy::rec11 {} { ;# QS_QF_ACTIVE_REMOVE +} +proc ::qspy::rec12 {} { ;# QS_QF_ACTIVE_SUBSCRIBE +} +proc ::qspy::rec13 {} { ;# QS_QF_ACTIVE_UNSUBSCRIBE +} +proc ::qspy::rec14 {} { ;# QS_QF_ACTIVE_POST_FIFO +} +proc ::qspy::rec15 {} { ;# QS_QF_ACTIVE_POST_LIFO +} +proc ::qspy::rec16 {} { ;# QS_QF_ACTIVE_GET +} +proc ::qspy::rec17 {} { ;# QS_QF_ACTIVE_GET_LAST +} +proc ::qspy::rec18 {} { ;# QS_QF_EQUEUE_INIT +} +proc ::qspy::rec19 {} { ;# QS_QF_EQUEUE_POST_FIFO +} +proc ::qspy::rec20 {} { ;# QS_QF_EQUEUE_POST_LIFO +} +proc ::qspy::rec21 {} { ;# QS_QF_EQUEUE_GET +} +proc ::qspy::rec22 {} { ;# QS_QF_EQUEUE_GET_LAST +} +proc ::qspy::rec23 {} { ;# QS_QF_MPOOL_INIT +} +proc ::qspy::rec24 {} { ;# QS_QF_MPOOL_GET +} +proc ::qspy::rec25 {} { ;# QS_QF_MPOOL_PUT +} +proc ::qspy::rec26 {} { ;# QS_QF_PUBLISH +} +proc ::qspy::rec27 {} { ;# QS_QF_RESERVED8 +} +proc ::qspy::rec28 {} { ;# QS_QF_NEW +} +proc ::qspy::rec29 {} { ;# QS_QF_GC_ATTEMPT +} +proc ::qspy::rec30 {} { ;# QS_QF_GC +} +proc ::qspy::rec31 {} { ;# QS_QF_TICK +} +proc ::qspy::rec32 {} { ;# QS_QF_TIMEEVT_ARM +} +proc ::qspy::rec33 {} { ;# QS_QF_TIMEEVT_AUTO_DISARM +} +proc ::qspy::rec34 {} { ;# QS_QF_TIMEEVT_DISARM_ATTEMPT +} +proc ::qspy::rec35 {} { ;# QS_QF_TIMEEVT_DISARM +} +proc ::qspy::rec36 {} { ;# QS_QF_TIMEEVT_REARM +} +proc ::qspy::rec37 {} { ;# QS_QF_TIMEEVT_POST +} +proc ::qspy::rec38 {} { ;# QS_QF_TIMEEVT_CTR +} +proc ::qspy::rec39 {} { ;# QS_QF_CRIT_ENTRY +} +proc ::qspy::rec40 {} { ;# QS_QF_CRIT_EXIT +} +proc ::qspy::rec41 {} { ;# QS_QF_ISR_ENTRY +} +proc ::qspy::rec42 {} { ;# QS_QF_ISR_EXIT +} +proc ::qspy::rec43 {} { ;# QS_QF_INT_DISABLE +} +proc ::qspy::rec44 {} { ;# QS_QF_INT_ENABLE +} +proc ::qspy::rec45 {} { ;# QS_QF_ACTIVE_POST_ATTEMPT +} +proc ::qspy::rec46 {} { ;# QS_QF_EQUEUE_POST_ATTEMPT +} +proc ::qspy::rec47 {} { ;# QS_QF_MPOOL_GET_ATTEMPT +} +proc ::qspy::rec48 {} { ;# QS_QF_RESERVED1 +} +proc ::qspy::rec49 {} { ;# QS_QF_RESERVED0 +} + +# [50] QK/QV records +proc ::qspy::rec50 {} { ;# QS_QK_MUTEX_LOCK +} +proc ::qspy::rec51 {} { ;# QS_QK_MUTEX_UNLOCK +} +proc ::qspy::rec52 {} { ;# QS_QVK_SCHEDULE +} +proc ::qspy::rec53 {} { ;# QS_QVK_IDLE +} +proc ::qspy::rec54 {} { ;# QS_QK_RESUME +} + +# [55] Additional QEP records +proc ::qspy::rec55 {} { ;# QS_QEP_TRAN_HIST +} +proc ::qspy::rec56 {} { ;# QS_QEP_TRAN_EP +} +proc ::qspy::rec57 {} { ;# QS_QEP_TRAN_XP +} +proc ::qspy::rec58 {} { ;# QS_QEP_RESERVED1 +} +proc ::qspy::rec59 {} { ;# QS_QEP_RESERVED0 +} + +# Miscellaneous QS records +proc ::qspy::rec60 {} { ;# QS_SIG_DICT +} +proc ::qspy::rec61 {} { ;# QS_OBJ_DICT +} +proc ::qspy::rec62 {} { ;# QS_FUN_DICT +} +proc ::qspy::rec63 {} { ;# QS_USR_DICT +} + +# proc ::qspy::64 ;# QS_TARGET_INFO not used, see proc recINFO + +proc ::qspy::rec65 {} { ;# QS_RESERVED0 +} +proc ::qspy::rec66 {} { ;# QS_RX_STATUS +} +proc ::qspy::rec67 {} { ;# QS_TEST_STATUS +} +proc ::qspy::rec68 {} { ;# QS_PEEK_DATA +} +proc ::qspy::rec69 {} { ;# QS_ASSERT_FAIL +} diff --git a/examples/workstation/dpp-comp/qspyview/img/BTN_DWN.gif b/examples/workstation/dpp-comp/qspyview/img/BTN_DWN.gif new file mode 100644 index 0000000000000000000000000000000000000000..36d8c790736950bcfe9d753d25d9fd197be63048 GIT binary patch literal 2071 zcmV+y2C@6 zXoG5Gg>_Q&<;K>&o|uV$+QOa7xTU$Qc*eMh9@O3%ET&cLLF za%hNfX^C=e(7v68d3K9?dD6h1eQRZkb!}^2S$Jt>fpKYMTU35-WsGrck$ZB?ww;M| zYJhQWb7f(RdUSehVv28Sc4u7H$)SXNdCt0;%e%)z@C(n(Yu_5 zb#B_vp6T7PvZRo$p__4NUY?I&U{_Jy&auV3w%5t4dTnQaa9fdmYvS3a@1vmu-E3(!qul8$g~xBSPa^ixxg= zY}0GK)z3zn&MNc;do2ndcKEv%(t8Xnz-R&lTLv)1-Lw@^MDN{8X|nPsKKK!j|57anXq6cT?)8O0>n{K;3j}F7c#3+ zGc`y-CoO{1AWVV>i3EiVb)#jb4VEnd+^Fz_MNgF}xTjR95+U=53jj!5dD7wm4Oy4hjr5k9!0t5dtAn#IeN|0N}TTcKpGRL0e!$B>#PH4TEYq|?2&7kCHTn%3snG6M+{E*Fi#DtHgf_NWK1ds1sr%eK(v`s zORc7U9svdzM1ohx7cw~Ef(r|@5T{xspc{t-9I#si2($8euN8SXV1*U<&RatN5>t4K zzyb;Y+(n!>Sdf5JA56f(8+tBGs{?sJ%<{wzXqssf7y}@K1t};nj|(7MpjQAT{{ct4 z3`3j8(MTWd0G~4?F+dvoLL*dzh$&?O2?1cy1j1ubu*Aa9vK(>J4wSt#3{|8NKp8yE zLxp=R8E|#hA4u@W7(+ihYuOR=ZH3tmd|AO1EdZc}7A?5Y#m8}5aKZyk#KG(aU8nJN z*nz(bxC0O{>;)Mp$e=|OE;#9)3A3*blVkrRO736i_ zO*sV>v~PVD)x&SQ^%V%<1pqmaaDxIbfUm$1s55~Ho`D19eSmqC6MzESSAq9Auzdn( zfF7ivl^;Yw0T^7s4vZkc82rEjQ20t5KESNzZD0dl5C8?($G|MKj{edGiY@h)RpxhW#xIzjD;0`g=5C#y?fhQ?|20Cm(9XcpL z1WbbtEpXid_`rcNAn}Z6^g;u?P=y1i00T96!WA^=Bps3~21YPK3}Wyi9n7Hxa{#~= zupj|BaKL_POkowsFc}q`;0hh!-ws~TF-nq)gGP{n5fIP`Pf(%%4O{>K7S6B*2~0o^ za+tsbws3$G_(272pn*pg@Phsg!3DKcfcOMxf*8oagHeb=3Q#}kfRei<^tj=UvV!yh0(1R{t+5D<_8B2b|VG{gWArg8!u5CH{JzyKOL z(g7#v@LwGBUkzgLI|TR;0Wtun2%ta%B9xPup|BDP;2DxDKym>Wbke_ufXyLLl%IR# z;~o*9fGC6k2RhJ!5Qsq1cb0UaR0ydKT96(mRk8-)+kp!(y2oGgQ40V?00N*eQW}U< zq$FKv7k&{BUvw0gEG^wFIp|HDIu)P~2q^GUAQYeo0VpYSNI^AV)X`cdEP97PyyHA^=6CS#?K8qmWAs^6v#vXu((!5QZq|R0KK==3M=HMRyqX9ZuK< z4KkQPjtwS+EG2;qCQE_`kU+A4^&U8bFj>yZz=9F&stE8J%zF5sAuWJH7(@^V06UO% BVI%+m literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp-comp/qspyview/img/BTN_UP.gif b/examples/workstation/dpp-comp/qspyview/img/BTN_UP.gif new file mode 100644 index 0000000000000000000000000000000000000000..3246ff9827129f635ad0fc3e4de0b62a6438d946 GIT binary patch literal 1987 zcmV;!2R!&kNk%w1VJiSF0OkMygK=u(+R2J?Y;0p)n2UIFYGl~TwBy>h)xw~Pd3NaG z%H7kwg=}V*iG_o7af5DYq?LNw!k&b3Wx}?qjE05Jy`s*$oz=aax2vaORZH2>%87bb zZDwTM(yg?rlXh@vb75U(URuSyj(TZZj)HW`wwY5&J#%eqt)g~)baI`Kf{AuFQ2TFJAJrkRV`$*0@Qs(NN&ZD3KTo0F=Zi)&j{x~7T4vz4ivfXu_W*1nj) ztBJa%g{7N?yR??OtB!kcTFLNz@?G@BB;u#lFogNdp$iI0q}1--FCPfj#0xd6KolLIFou!oN}#RE!D z0~sN)n5hFbH9{^fI1dlf4-x_#i-v-ak2>ZcHW?-v0}AllVnYYIbUE5>k|tnxqc|hOj2seV5Kuv2ri>a_Fd6I-%^d)e zC4(S2anevli!%mDAi%Y-|LuLIMMMGQtX=@Cp{Tim9+H^#Xwi z5t;=5@<`|*fyB%PPbRup0U+KA8BCbSfI~FdjSotc91=o+?OQ4sCNydCl8#z`8h$&+i1tdt4$!dvyl+cA9S!98R1G$7HB?qV|wFCrXkkNsbLwf0_1!11S zMwk{PS%INP9C6{In*8NJj*2L;1`AJ#aDbj2bou2OoO=3csJxbNL>V5$a6) z`@#zsTrlqoh5i~v5n4ELf&(tpsNs|ad|+2ocDUh22erbBfW7qAJMRVgmJx;j7g;

      zEXxwhPXIsw2^;hwg2K^Gi-6S;M2<4hTrZ)5 z2_`sE!via5IM`uA)WQS-8~8!T9}K_yc(sv74h9%=Oc6#AUK6m!4&&g^kN`GPkb)CJ z=%9n)L~MY92zGQ}hndyZ3p?y3$PNVrd>o#^4zWBS0Pi&(mO=`#06;?j@y3hLLJMky znr8GRA7cQY@iNAAi!%_u!O^{p#T|>;0`h%1rXF|do?N-7gG=f7zE*io9KiY zNI-%N#32r8NP`*57zcmIaR@fh2o|?TuI+KocOJX}48YhI8~`Ez2Xp~K9!7wIA;({CqAqSuQ1Qxc5g)MBsigg^DJDyZY-u*xT&b+}i9gqMpy5oa1pg|9Y z`3WF=5}QC60Sz+9Jq?{xJm>sDI@`HP|2bg=FmS*J=ZOP($}4O#nYB z7rFkZ&=n~3qX{6ELTi8n064UlG_WR5@~1tF2GpG80;8MU^ihSb6NEKz!8Jh{&s(UY z9qzECMJ?HvgnkfCw*=%n-eJLYIF%hZxI#O`8896Nj4LA`p#VV}&;S^0(xY6tWdgj~ V&II&@rP>3iJO1f{O>{I606W4fO_=}y literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp-comp/qspyview/img/eating.gif b/examples/workstation/dpp-comp/qspyview/img/eating.gif new file mode 100644 index 0000000000000000000000000000000000000000..632b9d23acd8604b0219c7ebe2836c3c1f2fa825 GIT binary patch literal 3169 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 Fe*y4k@DKn1 literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp-comp/qspyview/img/hungry.gif b/examples/workstation/dpp-comp/qspyview/img/hungry.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc144db97a2ee0413f63de2148988e112139134e GIT binary patch literal 2428 zcmW-e`&&{61Axzg0~`?Xh={1DfK2gH;WaF3fb&+?(5yK#!_Cx|+i+8}+xHzVq6s>x zEiKKk+;VEArlmdE4x(kHWtTN;)$kHxpWBCRty*sE+1?-C_YZiJQW8aRxpH6)U;_ZB zBVY<A*0orR8LO{jTH3kN^1NBTIMCqsO*u z*RGd+o_Oli*8>9sJsteBXFKtr`)}Ov?r~H5wF|-B z=e{c`H9WRG{maG~=m`01HXtTC#_4nd|H6F@{oC+={Ld4B3&_n8u2B4-I~DV`ed;2^&n2BZ>%ZGoU>Hi@)Ip> zg9(X}YC0(e&ep^o_Qyr-6G*m{a5Nn6XlJ9iUvV{$fD^DENhTww(`o=VXUB$>k!3C+mUAHfHQ$a*(QDkFsRzQ?{M`=U4uErG+Vx5!e7XAG( zf+ptm0mXIJ=Pj;M<;v+qfm;1ft3L`J4vwo@2S)*EO!BNUhy84ieGj=F(Z z`DnCwN+mhOV0NAEz~V_SWvuml#h~pPy#^O8#k=d~`D$u>Jr)n$_0)QiUb=pU`G~br zolAV`!i~(eVyS``DK5q{U95l~!B< z?oeJ(<2(x8Elwid-erN{LIs*1=8k|2gVJi&O%w(u(4(ODEU<5~>FSXJnh+!IHkeQ_ z9pRwlE#(JcmMnFlF4m1TuE|9>(x9VS`bYT&GF*aZSN9<1;)S$e9fGYYLE$Z_SblS3 zQ-}(r2tbS;JW-qs@>!0p?>|J0kc+%jI0WPCAIzOz7mAqiA7o-E)rKxKwtc5OPXg96 z^1t=yee$fs|D$KkAQQ+iULofQ&02&B4?j)wY;4A5AYYpE5B05B2_Qa-Bncs?+-hbt zY>%RPI>?<`q^vdr^@@<_e>r!IrZBr@0Kcy7dJZbo^tVky186_})}RyqRA5TNpq-)8 z*6H4vbvUL-sU>)dl^WL;PoWM^L#-$~V#s706S)~|z)FrhEjIW$5amW*x2SZuGBDynMQ#p%pafabMH2(+!e@yVakVvHz2y#B}}WQ zh>(i00$j7iHw-+a4h2}~FrLY1p5OPR*fB_TQOM^wiV^uc2wZrZ{{vCWHY|@o6)2IK zXH3v)_BKmhLN8$`jok_0T|yUAs=T99Ip&KL%xlz=>A>)=uOtz1I|)Opt7vr2pjG1iYm+pL~QJCUkVV(&`yLsUjNvlSr@eJZh;S*sQwad#M@6}@> zL2_M)C}o;U6GAZ@Yt5L46p>V+46*bJy;8+214e9PAY9rqNN%f2mKmh9-2!RgS_d)0 zR_HALiVx9e0B9Yq8^Tu&y7|iqa$P!-Q*HrLUne3(7>=pf=D#(ripG|@9w}P0Ar2b z@OVd{(%HDEP^6-*uorMcCo0L`bOlWb@uW_P>=VY#a=)sRfxG3}=vc+>kIA>`7qwZ% zuTXF(2KwM`pL$&pw>DX%$^5-j8#&+VMpB?fUbz`zGD*U|K43|oQoR6JiFbV=JSVFP z$&*5{7>G~qT>CtYlWK@bdVoBfR&g@gh^Du+8(M;KlyDP?(T5T4UpodaGZDV`gnXzD z)I-^f#45bGGyv}>cOa`qBp>wSHC{?9&ReM|T6l-Jh*M&l6=up(42?@oa1WFCZqGM@ zl~&nyjbsp|PHL#xCSqv46km;46MC@!?&y*od4p<V>&l!$|*W#9S63Atbs)&js0pW_0|2(Erh{lQ0O^HdHLx(3;FQ2;Hv>qbf XpQlo&rO5Tpgr@ifb-xb}0apGEm|EE% literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp-comp/qspyview/img/thinking.gif b/examples/workstation/dpp-comp/qspyview/img/thinking.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec684ee5a378e80a351b0821edc6adc9fa1c4850 GIT binary patch literal 2378 zcmWlY=~ol?0ziK=lgUPa0Rkkf2?8bYeb(8LOfKd2C5cq>l;yATEw^lJ}}RIx&OeuH!eOld|9>Rx9{@X-xk;&2TffI*iuqX z>RO*%-gBz7~ecI;o+*|fDFJ1A*Q*tRx2OAu?7X~Z*S!C} z;**yq*jfRuWeAOlC zV`I0+C!QJ(HgDgysce_#_05GRdoEn<7M1SUw)2aR&7I=wJ%Z7(2UE|dzt*hz-`u;Z zigk}4KYB45xN5C3cgvT$rp}t$%In>ghMGkWpIFCC+K8AnXN~1)d8JLpZsWo7J^Dk1 zrF-7Ic|G~FE^l*6d6j;4_U--g@kdWy#Y74c(h7%8lqJQwEewkrJV7oE^*Xs9Gc?pa zynlCY_D!R1`@6Zfrw?Kc`tldo^mqSLHGNBBv)KRu;#tOf0wDVb|2P3Gn|c>nSyipA zsjb^xE%c7dN=fKGo2+f z9bMfS89ciThD4ebf837<=(}ccOtn)$Y&JXwLn3>rBS{qfa{WP#Fpd`jAmq!bX9xs4 z1j=REerbYLaq8pI zKLKEzTv3KU$X(3Y>;NPiwgP7sE1kGE?%Y%x$p38gzz$@%s`Y3qNE%rqSq=QxO-Ajm zLwP=--;T<#Hcixtrd@)e6R)LuemIq$4&@LV+SoR?Ib~=5O41HJcp-R$dcdKtRwc;B z`k&s_LpjNy@Z;TVuJ0|>;3ayNO+sW#_OK*ICtAAFH=L-9YA8Lho`oGO3w@;6_#m@( ze5G!Sckq~X2FvYzHj={2NNkxnE#j=&O4qN;C$&<>(MgNq+rE9m1@Uj@H=Q4_Q$&Rc zxJl5JHdpsNJ)a_`3OIgNc6!eDmc1A2TIF@!eFP9ndtaq9#azU^0oK?8E4K(29%_1FHG62#$OxSvj~1mf;jjAE`Ef zi>GhYK|X9X07kBba$f880@$x$V-O^&<+2266%As3T8k04!wtqxj=jVw+6RAZQNRI1 z?JP)zVhRQj5x|R60v}=Iw-8JQH~*g2v$%zZ?cJ?^RdJXg8*oC-rr;2eKvA$#t%%q9 z^%6|qnU%&R3{Qy>cQ0mtQ0d~UI<+^8b(~@ZaH^m@PH-WBF7VTaS+%!?$B*cF=T1@zvZXDKQ{|i?4LXo$r~= zk<&cI)!_@LJRk;7X|5GU5(U3TF0z_=&rL30xFGzZZCU|k{QM#}ad?}VJ7ZyNsPHK% z(QenrShBQZF=KMhaC_ZYnC04|t~&@2WY=%5kJk_w@(W9KQ1X zT@VLjK*5Q{pVd{?AxNQeAYR}9JZo-er%x+8zc1Z`|4FD*{dj4>t+!D z^HKEEF`P9&u_U-x4ID(Pph6lQ8JS=^AGotzc4Sc4CDtD3QKL!>y7Ms*iJ>D3} zr#NYbrgWXU>RqyU&(qpu7dNX`_67p00-dSS-ZrB|c`Q-8H)KI{FTM1lNs5vYv zfIL!a{lYj-;(RP6p@_NA|B64-MTMN*jEHC27;)VF;wR;dkGs~ANuol6CJsdE=vZOm5y+#S?m^j)0hozZ@_I)ljS?$S=(L-MYMfL|bU82v-R4#^Z!)4Nu!5kA zB16Rz(Js0O@xszBvq-%VDM26#4zr_ zxVoco2oW$)zBOUVU5K2~g-(3=KKJSKYh7%1AW#=LR(6*z5vdjP7lA!y zbN5#4%eN>iL7HGgma3d8S?+<#Y+Uszz#?*FOml_zB{1 zGRRX}(szwKK9{T63mgt|8H>|8#Uor_ZIRqJYc#49@hV2=fe$YJn!!(zgpweqvAFP( z9(HFd4zA)e7N>U#-!GLfdJUhbb~w?>GahG<4QbdB>(G4z{7!G9$B0ZV9oNA&x=Nw;6OV8BopPtc0wLP&KyEk86o}+#LMZ8<9eP|&enRD-wVEl$E^gq zq_8kWOUX!j6O?s!X}iMaYYkI^0Z#xJa)Lb!@zF1}qm?tb<&p zpvQoEM!Hw@8jdR))zizevMMVof11bM=i^4v!0)Mqes9Ar8J2nisf2|H5gTA!l~6S= zt!3(Rv70FAGD>E~hjY|(VCLM^Vz*q* zH9<&%=B2ce#iDKcM@wNfT@QZ@XVM-e0g|9RcPK%vayw~!5`ry+IS>e+JI=%zZxcaNh>7rr%5dZPj0$x z12(IvKd-%O2kng#U?Z&4;UDY;t);yk?Z<3y8g7eSRt>?wPS0skxIE37Ubmyp*B0m& pVqe^eUK~AZ?cAAr;_dL>k7aRD*UyK2i+eDL`IL?r`+9!i`~$2(4t4+l literal 0 HcmV?d00001 diff --git a/examples/win32/dpp-gui/README.txt b/examples/workstation/dpp-gui/README.txt similarity index 84% rename from examples/win32/dpp-gui/README.txt rename to examples/workstation/dpp-gui/README.txt index e1752535..9f41208a 100644 --- a/examples/win32/dpp-gui/README.txt +++ b/examples/workstation/dpp-gui/README.txt @@ -2,7 +2,7 @@ The Win32 GUI emulation of the Dining Philosopers Problem (DPP) example for the EFM32-SLSTK3401A board from Silicon Labs is now located in the directory: -examples\arm-cm\dpp_efm32-slstk3401a\win32\ +examples\arm-cm\dpp_efm32-slstk3401a\win32-gui\ This co-location of the Win32 emulation with the embedded code running diff --git a/examples/workstation/dpp/Makefile b/examples/workstation/dpp/Makefile new file mode 100644 index 00000000..8eb55e30 --- /dev/null +++ b/examples/workstation/dpp/Makefile @@ -0,0 +1,288 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := dpp + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/workstation/dpp/bsp.c b/examples/workstation/dpp/bsp.c new file mode 100644 index 00000000..74081238 --- /dev/null +++ b/examples/workstation/dpp/bsp.c @@ -0,0 +1,175 @@ +/***************************************************************************** +* Product: DPP example (console) +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 +* +* 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 "qpc.h" +#include "dpp.h" +#include "bsp.h" + +#include +#include + +Q_DEFINE_THIS_FILE + +/* local variables ---------------------------------------------------------*/ +static uint32_t l_rnd; /* random seed */ + +#ifdef Q_SPY + enum { + PHILO_STAT = QS_USER + }; + static uint8_t const l_clock_tick = 0U; +#endif + +/*..........................................................................*/ +void BSP_init(int argc, char *argv[]) { + (void)argc; + (void)argv; + + printf("Dining Philosophers Problem example" + "\nQP %s\n" + "Press 'p' to pause\n" + "Press 's' to serve\n" + "Press ESC to quit...\n", + QP_versionStr); + + BSP_randomSeed(1234U); + + Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : (void *)0)); + QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ + QS_USR_DICTIONARY(PHILO_STAT); + + /* setup the QS filters... */ + QS_FILTER_ON(QS_ALL_RECORDS); + QS_FILTER_OFF(QS_QF_TICK); +} +/*..........................................................................*/ +void BSP_terminate(int16_t result) { + (void)result; + QF_stop(); /* stop the main "ticker thread" */ +} +/*..........................................................................*/ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + printf("Philosopher %2d is %s\n", (int)n, stat); + + QS_BEGIN(PHILO_STAT, (void *)0) /* application-specific record begin */ + QS_U8(1, n); /* Philosopher number */ + QS_STR(stat); /* Philosopher status */ + QS_END() +} +/*..........................................................................*/ +void BSP_displayPaused(uint8_t paused) { + printf("Paused is %s\n", paused ? "ON" : "OFF"); +} +/*..........................................................................*/ +uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ + /* "Super-Duper" Linear Congruential Generator (LCG) + * LCG(2^32, 3*7*11*13*23, 0, seed) + */ + l_rnd = l_rnd * (3U*7U*11U*13U*23U); + return l_rnd >> 8; +} +/*..........................................................................*/ +void BSP_randomSeed(uint32_t seed) { + l_rnd = seed; +} + +/****************************************************************************/ +/*..........................................................................*/ +void QF_onStartup(void) { + QF_consoleSetup(); + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* desired tick rate/ticker-prio */ +} +/*..........................................................................*/ +void QF_onCleanup(void) { + printf("\nBye! Bye!\n"); + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ + + QS_RX_INPUT(); /* handle the QS-RX input */ + QS_OUTPUT(); /* handle the QS output */ + + switch (QF_consoleGetKey()) { + case '\33': { /* see if the ESC key pressed */ + BSP_terminate(0); + break; + } + case 'p': { + QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); + break; + } + case 's': { + QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); + break; + } + default: { + break; + } + } +} + +/*--------------------------------------------------------------------------*/ +#ifdef Q_SPY /* define QS callbacks */ + +/*..........................................................................*/ +/*! callback function to execute user commands */ +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + /* unused parameters */ + (void)param1; + (void)param2; + (void)param3; +} + +#endif /* Q_SPY */ +/*--------------------------------------------------------------------------*/ + +/*..........................................................................*/ +void Q_onAssert(char const * const module, int_t loc) { + QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */ + fprintf(stderr, "Assertion failed in %s:%d", module, loc); + QF_onCleanup(); + exit(-1); +} + diff --git a/examples/win32/dpp-comp/bsp.h b/examples/workstation/dpp/bsp.h similarity index 100% rename from examples/win32/dpp-comp/bsp.h rename to examples/workstation/dpp/bsp.h diff --git a/examples/win32/dpp/dpp.h b/examples/workstation/dpp/dpp.h similarity index 100% rename from examples/win32/dpp/dpp.h rename to examples/workstation/dpp/dpp.h diff --git a/examples/win32/dpp/dpp.qm b/examples/workstation/dpp/dpp.qm similarity index 100% rename from examples/win32/dpp/dpp.qm rename to examples/workstation/dpp/dpp.qm diff --git a/examples/win32-qv/dpp/dpp.sln b/examples/workstation/dpp/dpp.sln similarity index 100% rename from examples/win32-qv/dpp/dpp.sln rename to examples/workstation/dpp/dpp.sln diff --git a/examples/win32-qv/dpp/dpp.vcxproj b/examples/workstation/dpp/dpp.vcxproj similarity index 80% rename from examples/win32-qv/dpp/dpp.vcxproj rename to examples/workstation/dpp/dpp.vcxproj index 3889418e..b5895774 100644 --- a/examples/win32-qv/dpp/dpp.vcxproj +++ b/examples/workstation/dpp/dpp.vcxproj @@ -1,4 +1,4 @@ - + @@ -78,8 +78,8 @@ Default - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) + qp.lib;%(AdditionalDependencies) + ../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true Console MachineX86 @@ -93,7 +93,7 @@ MaxSpeed true .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;snprintf=_snprintf;WIN32;_CONSOLE;%(PreprocessorDefinitions) false @@ -106,8 +106,8 @@ 4127 - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) + qp.lib;%(AdditionalDependencies) + ../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true Console true @@ -134,8 +134,8 @@ 4127 - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) + qp.lib;wsock32.lib;%(AdditionalDependencies) + ../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true Console MachineX86 @@ -145,10 +145,6 @@ - - true - true - @@ -159,18 +155,6 @@ - - - true - - - true - true - - - true - - diff --git a/examples/workstation/dpp/dpp.vcxproj.filters b/examples/workstation/dpp/dpp.vcxproj.filters new file mode 100644 index 00000000..05c7af40 --- /dev/null +++ b/examples/workstation/dpp/dpp.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/win32-qv/dpp/main.c b/examples/workstation/dpp/main.c similarity index 93% rename from examples/win32-qv/dpp/main.c rename to examples/workstation/dpp/main.c index 515fc000..8de07c1a 100644 --- a/examples/win32-qv/dpp/main.c +++ b/examples/workstation/dpp/main.c @@ -52,15 +52,6 @@ int main(int argc, char *argv[]) { QF_init(); /* initialize the framework and the underlying RT kernel */ BSP_init(argc, argv); /* initialize the Board Support Package */ - /* object dictionaries... */ - QS_OBJ_DICTIONARY(smlPoolSto); - QS_OBJ_DICTIONARY(tableQueueSto); - QS_OBJ_DICTIONARY(philoQueueSto[0]); - QS_OBJ_DICTIONARY(philoQueueSto[1]); - QS_OBJ_DICTIONARY(philoQueueSto[2]); - QS_OBJ_DICTIONARY(philoQueueSto[3]); - QS_OBJ_DICTIONARY(philoQueueSto[4]); - /* initialize publish-subscribe... */ QF_psInit(subscrSto, Q_DIM(subscrSto)); diff --git a/examples/win32/dpp/philo.c b/examples/workstation/dpp/philo.c similarity index 100% rename from examples/win32/dpp/philo.c rename to examples/workstation/dpp/philo.c diff --git a/examples/workstation/dpp/qspyview/dpp.tcl b/examples/workstation/dpp/qspyview/dpp.tcl new file mode 100644 index 00000000..97d6a517 --- /dev/null +++ b/examples/workstation/dpp/qspyview/dpp.tcl @@ -0,0 +1,384 @@ +#----------------------------------------------------------------------------- +# Product: QSpyView -- Customization example for DPP application +# Last updated for version 6.2.0 +# Last updated on 2018-03-14 +# +# 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://www.state-machine.com +# mailto:info@state-machine.com +#----------------------------------------------------------------------------- + +# command handlers =========================================================== +proc onMyCommand {} { + # do something here, for example: + # - inject an event to the Target + # - send a command to the Target + # - peek memory + # - poke memory + # - exectute system tick in the Target + # - open a dialog box... + # - etc. + + # as an example, the following code sends a command to the Target + variable ::qspy::QS_RX + ::qspy::sendPkt [binary format cciii $qspy::QS_RX(COMMAND) 1 12345 0 0] +} + +proc onPause {} { + global theButtonId theBtnState + if {[string equal $theBtnState BTN_UP]} { ;# is DWN? + set theBtnState BTN_DWN + ::qspy::sendCurrObj SM_AO l_table + ::qspy::sendEvent 255 PAUSE_SIG + #::qspy::sendEvent 6 6 0 + } else { + set theBtnState BTN_UP + ::qspy::sendCurrObj SM_AO l_table + ::qspy::sendEvent 255 SERVE_SIG + #::qspy::sendEvent 6 7 0 + } + .canv.c itemconfigure $theButtonId -image ::img::$theBtnState +} + +# additinal menu options ===================================================== +.mbar.cust add command -label "MyCommand" -command onMyCommand + + +# specific canvas for DPP ==================================================== +set scriptFolder [file dirname [file normalize [info script]]] + +image create photo ::img::e -file $scriptFolder/img/eating.gif +image create photo ::img::h -file $scriptFolder/img/hungry.gif +image create photo ::img::t -file $scriptFolder/img/thinking.gif +image create photo ::img::BTN_UP -file $scriptFolder/img/BTN_UP.gif +image create photo ::img::BTN_DWN -file $scriptFolder/img/BTN_DWN.gif + +wm geometry .canv =400x260 +.canv.c configure -width 400 +.canv.c configure -height 260 + +set thePhiloId [.canv.c create image 190 57 -image ::img::t] +.canv.c create image 273 100 -image ::img::t +.canv.c create image 237 185 -image ::img::t +.canv.c create image 146 184 -image ::img::t +.canv.c create image 107 100 -image ::img::t + + +set theButtonId [.canv.c create image 200 120 -image ::img::BTN_UP] +set theBtnState BTN_UP +.canv.c bind $theButtonId onPause + +# QS record handlers ========================================================= + +# user record handlers [70..0x7C] -------------------------------------------- +proc ::qspy::rec70 {} { ;# QS_USER + variable thePkt + variable theFmt + binary scan $thePkt xx$theFmt(tstamp)xcxa* \ + ts philoNum stat + + dispTxt [format "%010u Philo %1d is %s" $ts $philoNum $stat] + + global thePhiloId + set img [string index $stat 0] + .canv.c itemconfigure [expr $thePhiloId + $philoNum] -image ::img::$img +} +#............................................................................. +proc ::qspy::rec71 {} { ;# QS_USER + 1 + variable thePkt + variable theFmt + binary scan $thePkt xc$theFmt(tstamp)xc \ + cmdId ts par + dispTxt [format "%010u cmd=%d param=%d" $ts $cmdId $par] +} + +proc ::qspy::rec72 {} { ;# QS_USER + 2 +} +proc ::qspy::rec73 {} { ;# QS_USER + 3 +} +proc ::qspy::rec74 {} { ;# QS_USER + 4 +} +proc ::qspy::rec75 {} { ;# QS_USER + 5 +} +proc ::qspy::rec76 {} { ;# QS_USER + 6 +} +proc ::qspy::rec77 {} { ;# QS_USER + 7 +} +proc ::qspy::rec78 {} { ;# QS_USER + 8 +} +proc ::qspy::rec79 {} { ;# QS_USER + 9 +} +proc ::qspy::rec80 {} { ;# QS_USER + 10 +} +proc ::qspy::rec81 {} { ;# QS_USER + 11 +} +proc ::qspy::rec82 {} { ;# QS_USER + 12 +} +proc ::qspy::rec83 {} { ;# QS_USER + 13 +} +proc ::qspy::rec84 {} { ;# QS_USER + 14 +} +proc ::qspy::rec85 {} { ;# QS_USER + 15 +} +proc ::qspy::rec86 {} { ;# QS_USER + 16 +} +proc ::qspy::rec87 {} { ;# QS_USER + 17 +} +proc ::qspy::rec88 {} { ;# QS_USER + 18 +} +proc ::qspy::rec89 {} { ;# QS_USER + 19 +} +proc ::qspy::rec90 {} { ;# QS_USER + 20 +} +proc ::qspy::rec91 {} { ;# QS_USER + 21 +} +proc ::qspy::rec92 {} { ;# QS_USER + 22 +} +proc ::qspy::rec93 {} { ;# QS_USER + 23 +} +proc ::qspy::rec94 {} { ;# QS_USER + 24 +} +proc ::qspy::rec95 {} { ;# QS_USER + 25 +} +proc ::qspy::rec96 {} { ;# QS_USER + 26 +} +proc ::qspy::rec97 {} { ;# QS_USER + 27 +} +proc ::qspy::rec98 {} { ;# QS_USER + 28 +} +proc ::qspy::rec99 {} { ;# QS_USER + 29 +} +proc ::qspy::rec100 {} { ;# QS_USER + 30 +} +proc ::qspy::rec101 {} { ;# QS_USER + 31 +} +proc ::qspy::rec102 {} { ;# QS_USER + 32 +} +proc ::qspy::rec103 {} { ;# QS_USER + 33 +} +proc ::qspy::rec104 {} { ;# QS_USER + 34 +} +proc ::qspy::rec105 {} { ;# QS_USER + 35 +} +proc ::qspy::rec106 {} { ;# QS_USER + 36 +} +proc ::qspy::rec107 {} { ;# QS_USER + 37 +} +proc ::qspy::rec108 {} { ;# QS_USER + 38 +} +proc ::qspy::rec109 {} { ;# QS_USER + 39 +} +proc ::qspy::rec110 {} { ;# QS_USER + 40 +} +proc ::qspy::rec111 {} { ;# QS_USER + 41 +} +proc ::qspy::rec112 {} { ;# QS_USER + 42 +} +proc ::qspy::rec113 {} { ;# QS_USER + 43 +} +proc ::qspy::rec114 {} { ;# QS_USER + 44 +} +proc ::qspy::rec115 {} { ;# QS_USER + 45 +} +proc ::qspy::rec116 {} { ;# QS_USER + 46 +} +proc ::qspy::rec117 {} { ;# QS_USER + 47 +} +proc ::qspy::rec118 {} { ;# QS_USER + 48 +} +proc ::qspy::rec119 {} { ;# QS_USER + 49 +} +proc ::qspy::rec120 {} { ;# QS_USER + 50 +} +proc ::qspy::rec121 {} { ;# QS_USER + 51 +} +proc ::qspy::rec122 {} { ;# QS_USER + 52 +} +proc ::qspy::rec123 {} { ;# QS_USER + 53 +} +proc ::qspy::rec124 {} { ;# QS_USER + 54 +} + + +# special record handlers ---------------------------------------------------- +proc ::qspy::recRESET {} { ;# target reset callback +} +proc ::qspy::recINFO {} { ;# target info callback +} + +# standard record handlers [1..54] ------------------------------------------- +proc ::qspy::rec0 {} { ;# QS_EMPTY +} + +# [1] QEP records... +proc ::qspy::rec1 {} { ;# QS_QEP_STATE_ENTRY +} +proc ::qspy::rec2 {} { ;# QS_QEP_STATE_EXIT +} +proc ::qspy::rec3 {} { ;# QS_QEP_STATE_INIT +} +proc ::qspy::rec4 {} { ;# QS_QEP_INIT_TRAN +} +proc ::qspy::rec5 {} { ;# QS_QEP_INTERN_TRAN +} +proc ::qspy::rec6 {} { ;# QS_QEP_TRAN +} +proc ::qspy::rec7 {} { ;# QS_QEP_IGNORED +} +proc ::qspy::rec8 {} { ;# QS_QEP_DISPATCH +} +proc ::qspy::rec9 {} { ;# QS_QEP_UNHANDLED +} + +# [10] QF records... +proc ::qspy::rec10 {} { ;# QS_QF_ACTIVE_ADD +} +proc ::qspy::rec11 {} { ;# QS_QF_ACTIVE_REMOVE +} +proc ::qspy::rec12 {} { ;# QS_QF_ACTIVE_SUBSCRIBE +} +proc ::qspy::rec13 {} { ;# QS_QF_ACTIVE_UNSUBSCRIBE +} +proc ::qspy::rec14 {} { ;# QS_QF_ACTIVE_POST_FIFO +} +proc ::qspy::rec15 {} { ;# QS_QF_ACTIVE_POST_LIFO +} +proc ::qspy::rec16 {} { ;# QS_QF_ACTIVE_GET +} +proc ::qspy::rec17 {} { ;# QS_QF_ACTIVE_GET_LAST +} +proc ::qspy::rec18 {} { ;# QS_QF_EQUEUE_INIT +} +proc ::qspy::rec19 {} { ;# QS_QF_EQUEUE_POST_FIFO +} +proc ::qspy::rec20 {} { ;# QS_QF_EQUEUE_POST_LIFO +} +proc ::qspy::rec21 {} { ;# QS_QF_EQUEUE_GET +} +proc ::qspy::rec22 {} { ;# QS_QF_EQUEUE_GET_LAST +} +proc ::qspy::rec23 {} { ;# QS_QF_MPOOL_INIT +} +proc ::qspy::rec24 {} { ;# QS_QF_MPOOL_GET +} +proc ::qspy::rec25 {} { ;# QS_QF_MPOOL_PUT +} +proc ::qspy::rec26 {} { ;# QS_QF_PUBLISH +} +proc ::qspy::rec27 {} { ;# QS_QF_RESERVED8 +} +proc ::qspy::rec28 {} { ;# QS_QF_NEW +} +proc ::qspy::rec29 {} { ;# QS_QF_GC_ATTEMPT +} +proc ::qspy::rec30 {} { ;# QS_QF_GC +} +proc ::qspy::rec31 {} { ;# QS_QF_TICK +} +proc ::qspy::rec32 {} { ;# QS_QF_TIMEEVT_ARM +} +proc ::qspy::rec33 {} { ;# QS_QF_TIMEEVT_AUTO_DISARM +} +proc ::qspy::rec34 {} { ;# QS_QF_TIMEEVT_DISARM_ATTEMPT +} +proc ::qspy::rec35 {} { ;# QS_QF_TIMEEVT_DISARM +} +proc ::qspy::rec36 {} { ;# QS_QF_TIMEEVT_REARM +} +proc ::qspy::rec37 {} { ;# QS_QF_TIMEEVT_POST +} +proc ::qspy::rec38 {} { ;# QS_QF_TIMEEVT_CTR +} +proc ::qspy::rec39 {} { ;# QS_QF_CRIT_ENTRY +} +proc ::qspy::rec40 {} { ;# QS_QF_CRIT_EXIT +} +proc ::qspy::rec41 {} { ;# QS_QF_ISR_ENTRY +} +proc ::qspy::rec42 {} { ;# QS_QF_ISR_EXIT +} +proc ::qspy::rec43 {} { ;# QS_QF_INT_DISABLE +} +proc ::qspy::rec44 {} { ;# QS_QF_INT_ENABLE +} +proc ::qspy::rec45 {} { ;# QS_QF_ACTIVE_POST_ATTEMPT +} +proc ::qspy::rec46 {} { ;# QS_QF_EQUEUE_POST_ATTEMPT +} +proc ::qspy::rec47 {} { ;# QS_QF_MPOOL_GET_ATTEMPT +} +proc ::qspy::rec48 {} { ;# QS_QF_RESERVED1 +} +proc ::qspy::rec49 {} { ;# QS_QF_RESERVED0 +} + +# [50] QK/QV records +proc ::qspy::rec50 {} { ;# QS_QK_MUTEX_LOCK +} +proc ::qspy::rec51 {} { ;# QS_QK_MUTEX_UNLOCK +} +proc ::qspy::rec52 {} { ;# QS_QVK_SCHEDULE +} +proc ::qspy::rec53 {} { ;# QS_QVK_IDLE +} +proc ::qspy::rec54 {} { ;# QS_QK_RESUME +} + +# [55] Additional QEP records +proc ::qspy::rec55 {} { ;# QS_QEP_TRAN_HIST +} +proc ::qspy::rec56 {} { ;# QS_QEP_TRAN_EP +} +proc ::qspy::rec57 {} { ;# QS_QEP_TRAN_XP +} +proc ::qspy::rec58 {} { ;# QS_QEP_RESERVED1 +} +proc ::qspy::rec59 {} { ;# QS_QEP_RESERVED0 +} + +# Miscellaneous QS records +proc ::qspy::rec60 {} { ;# QS_SIG_DICT +} +proc ::qspy::rec61 {} { ;# QS_OBJ_DICT +} +proc ::qspy::rec62 {} { ;# QS_FUN_DICT +} +proc ::qspy::rec63 {} { ;# QS_USR_DICT +} + +# proc ::qspy::64 ;# QS_TARGET_INFO not used, see proc recINFO + +proc ::qspy::rec65 {} { ;# QS_RESERVED0 +} +proc ::qspy::rec66 {} { ;# QS_RX_STATUS +} +proc ::qspy::rec67 {} { ;# QS_TEST_STATUS +} +proc ::qspy::rec68 {} { ;# QS_PEEK_DATA +} +proc ::qspy::rec69 {} { ;# QS_ASSERT_FAIL +} diff --git a/examples/workstation/dpp/qspyview/img/BTN_DWN.gif b/examples/workstation/dpp/qspyview/img/BTN_DWN.gif new file mode 100644 index 0000000000000000000000000000000000000000..36d8c790736950bcfe9d753d25d9fd197be63048 GIT binary patch literal 2071 zcmV+y2C@6 zXoG5Gg>_Q&<;K>&o|uV$+QOa7xTU$Qc*eMh9@O3%ET&cLLF za%hNfX^C=e(7v68d3K9?dD6h1eQRZkb!}^2S$Jt>fpKYMTU35-WsGrck$ZB?ww;M| zYJhQWb7f(RdUSehVv28Sc4u7H$)SXNdCt0;%e%)z@C(n(Yu_5 zb#B_vp6T7PvZRo$p__4NUY?I&U{_Jy&auV3w%5t4dTnQaa9fdmYvS3a@1vmu-E3(!qul8$g~xBSPa^ixxg= zY}0GK)z3zn&MNc;do2ndcKEv%(t8Xnz-R&lTLv)1-Lw@^MDN{8X|nPsKKK!j|57anXq6cT?)8O0>n{K;3j}F7c#3+ zGc`y-CoO{1AWVV>i3EiVb)#jb4VEnd+^Fz_MNgF}xTjR95+U=53jj!5dD7wm4Oy4hjr5k9!0t5dtAn#IeN|0N}TTcKpGRL0e!$B>#PH4TEYq|?2&7kCHTn%3snG6M+{E*Fi#DtHgf_NWK1ds1sr%eK(v`s zORc7U9svdzM1ohx7cw~Ef(r|@5T{xspc{t-9I#si2($8euN8SXV1*U<&RatN5>t4K zzyb;Y+(n!>Sdf5JA56f(8+tBGs{?sJ%<{wzXqssf7y}@K1t};nj|(7MpjQAT{{ct4 z3`3j8(MTWd0G~4?F+dvoLL*dzh$&?O2?1cy1j1ubu*Aa9vK(>J4wSt#3{|8NKp8yE zLxp=R8E|#hA4u@W7(+ihYuOR=ZH3tmd|AO1EdZc}7A?5Y#m8}5aKZyk#KG(aU8nJN z*nz(bxC0O{>;)Mp$e=|OE;#9)3A3*blVkrRO736i_ zO*sV>v~PVD)x&SQ^%V%<1pqmaaDxIbfUm$1s55~Ho`D19eSmqC6MzESSAq9Auzdn( zfF7ivl^;Yw0T^7s4vZkc82rEjQ20t5KESNzZD0dl5C8?($G|MKj{edGiY@h)RpxhW#xIzjD;0`g=5C#y?fhQ?|20Cm(9XcpL z1WbbtEpXid_`rcNAn}Z6^g;u?P=y1i00T96!WA^=Bps3~21YPK3}Wyi9n7Hxa{#~= zupj|BaKL_POkowsFc}q`;0hh!-ws~TF-nq)gGP{n5fIP`Pf(%%4O{>K7S6B*2~0o^ za+tsbws3$G_(272pn*pg@Phsg!3DKcfcOMxf*8oagHeb=3Q#}kfRei<^tj=UvV!yh0(1R{t+5D<_8B2b|VG{gWArg8!u5CH{JzyKOL z(g7#v@LwGBUkzgLI|TR;0Wtun2%ta%B9xPup|BDP;2DxDKym>Wbke_ufXyLLl%IR# z;~o*9fGC6k2RhJ!5Qsq1cb0UaR0ydKT96(mRk8-)+kp!(y2oGgQ40V?00N*eQW}U< zq$FKv7k&{BUvw0gEG^wFIp|HDIu)P~2q^GUAQYeo0VpYSNI^AV)X`cdEP97PyyHA^=6CS#?K8qmWAs^6v#vXu((!5QZq|R0KK==3M=HMRyqX9ZuK< z4KkQPjtwS+EG2;qCQE_`kU+A4^&U8bFj>yZz=9F&stE8J%zF5sAuWJH7(@^V06UO% BVI%+m literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp/qspyview/img/BTN_UP.gif b/examples/workstation/dpp/qspyview/img/BTN_UP.gif new file mode 100644 index 0000000000000000000000000000000000000000..3246ff9827129f635ad0fc3e4de0b62a6438d946 GIT binary patch literal 1987 zcmV;!2R!&kNk%w1VJiSF0OkMygK=u(+R2J?Y;0p)n2UIFYGl~TwBy>h)xw~Pd3NaG z%H7kwg=}V*iG_o7af5DYq?LNw!k&b3Wx}?qjE05Jy`s*$oz=aax2vaORZH2>%87bb zZDwTM(yg?rlXh@vb75U(URuSyj(TZZj)HW`wwY5&J#%eqt)g~)baI`Kf{AuFQ2TFJAJrkRV`$*0@Qs(NN&ZD3KTo0F=Zi)&j{x~7T4vz4ivfXu_W*1nj) ztBJa%g{7N?yR??OtB!kcTFLNz@?G@BB;u#lFogNdp$iI0q}1--FCPfj#0xd6KolLIFou!oN}#RE!D z0~sN)n5hFbH9{^fI1dlf4-x_#i-v-ak2>ZcHW?-v0}AllVnYYIbUE5>k|tnxqc|hOj2seV5Kuv2ri>a_Fd6I-%^d)e zC4(S2anevli!%mDAi%Y-|LuLIMMMGQtX=@Cp{Tim9+H^#Xwi z5t;=5@<`|*fyB%PPbRup0U+KA8BCbSfI~FdjSotc91=o+?OQ4sCNydCl8#z`8h$&+i1tdt4$!dvyl+cA9S!98R1G$7HB?qV|wFCrXkkNsbLwf0_1!11S zMwk{PS%INP9C6{In*8NJj*2L;1`AJ#aDbj2bou2OoO=3csJxbNL>V5$a6) z`@#zsTrlqoh5i~v5n4ELf&(tpsNs|ad|+2ocDUh22erbBfW7qAJMRVgmJx;j7g;

      zEXxwhPXIsw2^;hwg2K^Gi-6S;M2<4hTrZ)5 z2_`sE!via5IM`uA)WQS-8~8!T9}K_yc(sv74h9%=Oc6#AUK6m!4&&g^kN`GPkb)CJ z=%9n)L~MY92zGQ}hndyZ3p?y3$PNVrd>o#^4zWBS0Pi&(mO=`#06;?j@y3hLLJMky znr8GRA7cQY@iNAAi!%_u!O^{p#T|>;0`h%1rXF|do?N-7gG=f7zE*io9KiY zNI-%N#32r8NP`*57zcmIaR@fh2o|?TuI+KocOJX}48YhI8~`Ez2Xp~K9!7wIA;({CqAqSuQ1Qxc5g)MBsigg^DJDyZY-u*xT&b+}i9gqMpy5oa1pg|9Y z`3WF=5}QC60Sz+9Jq?{xJm>sDI@`HP|2bg=FmS*J=ZOP($}4O#nYB z7rFkZ&=n~3qX{6ELTi8n064UlG_WR5@~1tF2GpG80;8MU^ihSb6NEKz!8Jh{&s(UY z9qzECMJ?HvgnkfCw*=%n-eJLYIF%hZxI#O`8896Nj4LA`p#VV}&;S^0(xY6tWdgj~ V&II&@rP>3iJO1f{O>{I606W4fO_=}y literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp/qspyview/img/eating.gif b/examples/workstation/dpp/qspyview/img/eating.gif new file mode 100644 index 0000000000000000000000000000000000000000..632b9d23acd8604b0219c7ebe2836c3c1f2fa825 GIT binary patch literal 3169 zcmWmB|3k}p0|4;%=iBz#R{PS{`d*(^m$b^FBD$=a8j+AhVI|jm>9JgtsQc_oYpAnu zkKB1!U8hBuZy9&oXVWE#rzmp1E$8TPEV^`$FFnum%j+L_rOr;77MGU+=76UFj6dd# z-{*WP{Pg&u`|Y-p4<9~Mmk18;=4>t$e!RmfE!l8T#~T`YcJ?4|>=yUd&7ONdmVSER zyLOpiz{(#l8rNyd_ZgOMFP*b`Y2>CgDSvbbTp09XWz_!t2UjgmeckQ$=+UDenwp+< zF`W6su`$H>^YB##1-o|DUbyh%{d;%1PqFUY?(eavvgYt_T)$>E=6o1ge0A})SARY~ zab(x%fa~9X|NZoL$EAkCyr}H<_I8Wq*y~=m>!*Y@(yy;}oH?{Vy*2gNuWe{nn)n-C zczML;S)N2|>#1K_1Z7E^PwiXz_U+pTcGqF&tKV{eZ`iNSm^1I{k#(b^W40FTz{Eq= zbIotQ9`5Yuvzs@oQWMA0-dVGMI=mfl-rwKv7=FF^=B=XZb;6Gyx1Bs* zY;Bly^{cBb6)oqjtNXhDHQdj8H#&Un_{J0Ftp7Y*KlW;@vm>kb2qv1JWedENNUz$1zJgZDOCXnSXem1fj> z<+VTDlQreF@KVJ`ljYY5_KQo>Ckp)}dGgwJE%U(GFrrs9rnyk(FT6okvkmVrbb@9b z@+Cj`1K^+eR(q!(zW=0`^Oo>a-(yQHqo*ae*n#iP517tvpk;kSf3G5u`lt%sKaU+= zd>Qt*gl+Pb*La4bMfSFZ{c8uVbDq6vJMVjN?f@EX9eS4ZTZl%Ya533QJ}QD;TMSK5 z%;9;?tLjds)1C|-xavysW?`P;5C!9e z#0I$z+5zq&>G{P+)pk|RjtyQc6)fn>AioevZdTC~&1#Z~M@!Hp4W#Lc*B8-iQ{0W; z7N>aZ>@-~_A~Q`=%>97M&JU5DH1KdjN3q>+5KKfQDc1`H?O{~w>2hUNV5sREEqx{x zmFiRUK|-hdg}$kxhXG4|06kaX7L1)?u5pyG1| zCB|<9R@SQkm_bm<0jb?4G}JHN`voo!C3PUEMk2;!f+!4&+E&+zcq#w_7_tLYc^Y9N z$KB^V@xlvy>b9fvf>YeTVZCePIzbSpp8Fogw#@Sd(UNjDYs6?F}UsS@Wagz zh~d5C0asU5Ps3p^n(ZKs52$2Ta?{}D3)Q*|%q`d`ISu4QFY2~YnJC8M(t2))wm9-A zIC?Db-Th19qFKm7L)?huSac6?O(dL*py^HbFZ1Q~u1;JqLZos8E-x{5KG9=m6}vYg zzPM2#MNoFx)GE4}dv4Mwq3njYM4w7^uVaND1$D^qw6;Zrgn}c2>*7Q)2UL)cuz<8x zUD;~1Vck>LlYhKij8IU7uhu)LJX2ldBF_~|g>mztOXJicPa=gyo0b?L!a}9gd(>%z zeYQD=6VNff>N4i(DS=#@zubjpI@?}|0X0r7TQ$pk;Uc0p4k(cG!`aYFFxRch=~S?$dj%CEZK#@1);}Un#Ih4pJNhIzAORmix-x1_}k)nQyd>->S_vg~X zZ}w)CK{U4X-?D54{X(2Q(TC7{|F7Bj9eW}#pBs0Emj|)9$zIk1+(QzrdsP4l6kXlH zbE9#iteyGtJjw`{Dqr4J)7T_hq~5(5^ZUZ>fMRk|JO!&up1DtPY8E||HoA`E8hZH` z2Elp=3iw`+L=zb6`IOB|>+SFgr(ULWXrmX01Xiik`g9(1wgu2MT$J6kCU3N4PFOUB zAR`1#W)=Rdl3c}4Hh9nJXd&wN%H06px6^HpO|3TGqA z$lz}Zl&pU#4+E0~M|m8T4e>XsX;WTfQ>{hgf@9MLkLF9OPP>p5=W}qDDG;2D(}d}I zgWZ&S;2?wgy2?VIuyAlir3EUZ)gi3xVx9S?=a`Ow7l)Rz9>`_%As^sxn3gcFQ7j}$ zRHT5QY|7@Mn2d*II~G=&p_;GWYRqB$6E!aSjn~MPNfPQ{%Do)P+Bhhk%wu0WilEOe zGZ3YW8&d`yIG1bi4t2C$>pMi}l0+1}0m@Eq_YNbOv|$C*K_t38cj)IVxxmi%g#B=} z#v?SMQ*Tl8TMb>}aw+_|e+sN2FixgIWhkS5yutH1>qpMLlH>n2Qlf2hOJZ=$(nTCK z%qh6NH|Wenc;Wc5=byDF;vr`0G`G6IDhJ9Vt)WIbRe?p!5`!Un%_>3|V%2^y*`yP3jrq$KrHP88ZvOewl#QuqInu zdnGCAha~qvqaB`RBKal`Kg}9)CD{Rogo-duwvC~vz*QI1rcZcxF1AhDl49xFRVhg-4B0$xwVuh2OnGa zDfJm3P63A~P^AqYez*0h$>*d4ojnZVEDC}AOBW|#THxi5$mB08t9qaVQ}H<@?C%D1 z6o{W>eQb0ZQRgvJ8qk|MfskljGN2F@970~Iyb_2t|FzAah9f8A3!Gq9BS`7tdJI)E zl^`gE=V9agv4jkv3a2&)h3r8*2`oX0ixn`DQMTt!ab%BdG94CkVHXNrJz7!F<1dKH zigzLnP6Q#J&+5T>vtTn?r1gBd>s)Qa)XZu@hjY}<>Fw* Fe*y4k@DKn1 literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp/qspyview/img/hungry.gif b/examples/workstation/dpp/qspyview/img/hungry.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc144db97a2ee0413f63de2148988e112139134e GIT binary patch literal 2428 zcmW-e`&&{61Axzg0~`?Xh={1DfK2gH;WaF3fb&+?(5yK#!_Cx|+i+8}+xHzVq6s>x zEiKKk+;VEArlmdE4x(kHWtTN;)$kHxpWBCRty*sE+1?-C_YZiJQW8aRxpH6)U;_ZB zBVY<A*0orR8LO{jTH3kN^1NBTIMCqsO*u z*RGd+o_Oli*8>9sJsteBXFKtr`)}Ov?r~H5wF|-B z=e{c`H9WRG{maG~=m`01HXtTC#_4nd|H6F@{oC+={Ld4B3&_n8u2B4-I~DV`ed;2^&n2BZ>%ZGoU>Hi@)Ip> zg9(X}YC0(e&ep^o_Qyr-6G*m{a5Nn6XlJ9iUvV{$fD^DENhTww(`o=VXUB$>k!3C+mUAHfHQ$a*(QDkFsRzQ?{M`=U4uErG+Vx5!e7XAG( zf+ptm0mXIJ=Pj;M<;v+qfm;1ft3L`J4vwo@2S)*EO!BNUhy84ieGj=F(Z z`DnCwN+mhOV0NAEz~V_SWvuml#h~pPy#^O8#k=d~`D$u>Jr)n$_0)QiUb=pU`G~br zolAV`!i~(eVyS``DK5q{U95l~!B< z?oeJ(<2(x8Elwid-erN{LIs*1=8k|2gVJi&O%w(u(4(ODEU<5~>FSXJnh+!IHkeQ_ z9pRwlE#(JcmMnFlF4m1TuE|9>(x9VS`bYT&GF*aZSN9<1;)S$e9fGYYLE$Z_SblS3 zQ-}(r2tbS;JW-qs@>!0p?>|J0kc+%jI0WPCAIzOz7mAqiA7o-E)rKxKwtc5OPXg96 z^1t=yee$fs|D$KkAQQ+iULofQ&02&B4?j)wY;4A5AYYpE5B05B2_Qa-Bncs?+-hbt zY>%RPI>?<`q^vdr^@@<_e>r!IrZBr@0Kcy7dJZbo^tVky186_})}RyqRA5TNpq-)8 z*6H4vbvUL-sU>)dl^WL;PoWM^L#-$~V#s706S)~|z)FrhEjIW$5amW*x2SZuGBDynMQ#p%pafabMH2(+!e@yVakVvHz2y#B}}WQ zh>(i00$j7iHw-+a4h2}~FrLY1p5OPR*fB_TQOM^wiV^uc2wZrZ{{vCWHY|@o6)2IK zXH3v)_BKmhLN8$`jok_0T|yUAs=T99Ip&KL%xlz=>A>)=uOtz1I|)Opt7vr2pjG1iYm+pL~QJCUkVV(&`yLsUjNvlSr@eJZh;S*sQwad#M@6}@> zL2_M)C}o;U6GAZ@Yt5L46p>V+46*bJy;8+214e9PAY9rqNN%f2mKmh9-2!RgS_d)0 zR_HALiVx9e0B9Yq8^Tu&y7|iqa$P!-Q*HrLUne3(7>=pf=D#(ripG|@9w}P0Ar2b z@OVd{(%HDEP^6-*uorMcCo0L`bOlWb@uW_P>=VY#a=)sRfxG3}=vc+>kIA>`7qwZ% zuTXF(2KwM`pL$&pw>DX%$^5-j8#&+VMpB?fUbz`zGD*U|K43|oQoR6JiFbV=JSVFP z$&*5{7>G~qT>CtYlWK@bdVoBfR&g@gh^Du+8(M;KlyDP?(T5T4UpodaGZDV`gnXzD z)I-^f#45bGGyv}>cOa`qBp>wSHC{?9&ReM|T6l-Jh*M&l6=up(42?@oa1WFCZqGM@ zl~&nyjbsp|PHL#xCSqv46km;46MC@!?&y*od4p<V>&l!$|*W#9S63Atbs)&js0pW_0|2(Erh{lQ0O^HdHLx(3;FQ2;Hv>qbf XpQlo&rO5Tpgr@ifb-xb}0apGEm|EE% literal 0 HcmV?d00001 diff --git a/examples/workstation/dpp/qspyview/img/thinking.gif b/examples/workstation/dpp/qspyview/img/thinking.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec684ee5a378e80a351b0821edc6adc9fa1c4850 GIT binary patch literal 2378 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 literal 0 HcmV?d00001 diff --git a/examples/win32/dpp/table.c b/examples/workstation/dpp/table.c similarity index 100% rename from examples/win32/dpp/table.c rename to examples/workstation/dpp/table.c diff --git a/examples/win32/game-gui/README.txt b/examples/workstation/game-gui/README.txt similarity index 86% rename from examples/win32/game-gui/README.txt rename to examples/workstation/game-gui/README.txt index 0017b08e..1192feda 100644 --- a/examples/win32/game-gui/README.txt +++ b/examples/workstation/game-gui/README.txt @@ -1,7 +1,7 @@ The Win32 GUI emulation of the "Fly 'n' Shoot" game example for the EFM32-SLSTK3401A board from Silicon Labs is now located in the directory: -examples\arm-cm\game_efm32-slstk3401a\win32\ +examples\arm-cm\game_efm32-slstk3401a\win32-gui\ **** NOTE: The EFM32-SLSTK3401A board replaces the EK-LM3S811 board, which diff --git a/examples/workstation/history_qhsm/Makefile b/examples/workstation/history_qhsm/Makefile new file mode 100644 index 00000000..88b2f492 --- /dev/null +++ b/examples/workstation/history_qhsm/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := history_qhsm + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + main.c \ + history.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/history_qhsm/history.c b/examples/workstation/history_qhsm/history.c similarity index 77% rename from examples/win32/history_qhsm/history.c rename to examples/workstation/history_qhsm/history.c index 9e403c7c..49268c7c 100644 --- a/examples/win32/history_qhsm/history.c +++ b/examples/workstation/history_qhsm/history.c @@ -1,8 +1,9 @@ -/***************************************************************************** +/*$file${.::history.c} #####################################################*/ +/* * Model: history.qm -* File: ./history.c +* File: ${.::history.c} * -* This code has been generated by QM tool (see state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -13,8 +14,8 @@ * 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. -*****************************************************************************/ -/*${.::history.c} ..........................................................*/ +*/ +/*$endhead${.::history.c} ##################################################*/ #include "qpc.h" #include "history.h" @@ -24,11 +25,7 @@ Q_DEFINE_THIS_FILE - -#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) -#error qpc version 5.8.0 or higher required -#endif - +/*$declare${SMs::ToastOven} ################################################*/ /*${SMs::ToastOven} ........................................................*/ typedef struct { /* protected: */ @@ -47,22 +44,30 @@ static QState ToastOven_baking(ToastOven * const me, QEvt const * const e); static QState ToastOven_off(ToastOven * const me, QEvt const * const e); static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e); static QState ToastOven_final(ToastOven * const me, QEvt const * const e); - +/*$enddecl${SMs::ToastOven} ################################################*/ static ToastOven l_oven; /* the only instance of the ToastOven class */ /* global-scope definitions -----------------------------------------*/ QHsm * const the_oven = (QHsm *)&l_oven; /* the opaque pointer */ +/* Check for the minimum required QP version */ +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 6.3.0 or higher required +#endif + +/*$define${SMs::ToastOven_ctor} ############################################*/ /*${SMs::ToastOven_ctor} ...................................................*/ void ToastOven_ctor(void) { ToastOven *me = &l_oven; QHsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial)); } +/*$enddef${SMs::ToastOven_ctor} ############################################*/ +/*$define${SMs::ToastOven} #################################################*/ /*${SMs::ToastOven} ........................................................*/ /*${SMs::ToastOven::SM} ....................................................*/ static QState ToastOven_initial(ToastOven * const me, QEvt const * const e) { - /* ${SMs::ToastOven::SM::initial} */ + /*${SMs::ToastOven::SM::initial} */ (void)e; /* avoid compiler warning */ /* state history attributes */ me->his_doorClosed = Q_STATE_CAST(&ToastOven_off); @@ -72,45 +77,45 @@ static QState ToastOven_initial(ToastOven * const me, QEvt const * const e) { static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::doorClosed} */ + /*${SMs::ToastOven::SM::doorClosed} */ case Q_ENTRY_SIG: { printf("door-Closed;"); status_ = Q_HANDLED(); break; } - /* ${SMs::ToastOven::SM::doorClosed} */ + /*${SMs::ToastOven::SM::doorClosed} */ case Q_EXIT_SIG: { /* save deep history */ me->his_doorClosed = QHsm_state(me); status_ = Q_HANDLED(); break; } - /* ${SMs::ToastOven::SM::doorClosed::initial} */ + /*${SMs::ToastOven::SM::doorClosed::initial} */ case Q_INIT_SIG: { status_ = Q_TRAN(&ToastOven_off); break; } - /* ${SMs::ToastOven::SM::doorClosed::TERMINATE} */ + /*${SMs::ToastOven::SM::doorClosed::TERMINATE} */ case TERMINATE_SIG: { status_ = Q_TRAN(&ToastOven_final); break; } - /* ${SMs::ToastOven::SM::doorClosed::OPEN} */ + /*${SMs::ToastOven::SM::doorClosed::OPEN} */ case OPEN_SIG: { status_ = Q_TRAN(&ToastOven_doorOpen); break; } - /* ${SMs::ToastOven::SM::doorClosed::TOAST} */ + /*${SMs::ToastOven::SM::doorClosed::TOAST} */ case TOAST_SIG: { status_ = Q_TRAN(&ToastOven_toasting); break; } - /* ${SMs::ToastOven::SM::doorClosed::BAKE} */ + /*${SMs::ToastOven::SM::doorClosed::BAKE} */ case BAKE_SIG: { status_ = Q_TRAN(&ToastOven_baking); break; } - /* ${SMs::ToastOven::SM::doorClosed::OFF} */ + /*${SMs::ToastOven::SM::doorClosed::OFF} */ case OFF_SIG: { status_ = Q_TRAN(&ToastOven_off); break; @@ -126,19 +131,19 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) { static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::doorClosed::heating} */ + /*${SMs::ToastOven::SM::doorClosed::heating} */ case Q_ENTRY_SIG: { printf("heater-On;"); status_ = Q_HANDLED(); break; } - /* ${SMs::ToastOven::SM::doorClosed::heating} */ + /*${SMs::ToastOven::SM::doorClosed::heating} */ case Q_EXIT_SIG: { printf("heater-Off;"); status_ = Q_HANDLED(); break; } - /* ${SMs::ToastOven::SM::doorClosed::heating::initial} */ + /*${SMs::ToastOven::SM::doorClosed::heating::initial} */ case Q_INIT_SIG: { status_ = Q_TRAN(&ToastOven_toasting); break; @@ -154,7 +159,7 @@ static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) { static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::doorClosed::heating::toasting} */ + /*${SMs::ToastOven::SM::doorClosed::heating::toasting} */ case Q_ENTRY_SIG: { printf("toasting;"); status_ = Q_HANDLED(); @@ -171,7 +176,7 @@ static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) { static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::doorClosed::heating::baking} */ + /*${SMs::ToastOven::SM::doorClosed::heating::baking} */ case Q_ENTRY_SIG: { printf("baking;"); status_ = Q_HANDLED(); @@ -188,7 +193,7 @@ static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) { static QState ToastOven_off(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::doorClosed::off} */ + /*${SMs::ToastOven::SM::doorClosed::off} */ case Q_ENTRY_SIG: { printf("toaster-Off;"); status_ = Q_HANDLED(); @@ -205,24 +210,24 @@ static QState ToastOven_off(ToastOven * const me, QEvt const * const e) { static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::doorOpen} */ + /*${SMs::ToastOven::SM::doorOpen} */ case Q_ENTRY_SIG: { printf("door-Open,lamp-On;"); status_ = Q_HANDLED(); break; } - /* ${SMs::ToastOven::SM::doorOpen} */ + /*${SMs::ToastOven::SM::doorOpen} */ case Q_EXIT_SIG: { printf("lamp-Off;"); status_ = Q_HANDLED(); break; } - /* ${SMs::ToastOven::SM::doorOpen::CLOSE} */ + /*${SMs::ToastOven::SM::doorOpen::CLOSE} */ case CLOSE_SIG: { status_ = Q_TRAN_HIST(me->his_doorClosed); break; } - /* ${SMs::ToastOven::SM::doorOpen::TERMINATE} */ + /*${SMs::ToastOven::SM::doorOpen::TERMINATE} */ case TERMINATE_SIG: { status_ = Q_TRAN(&ToastOven_final); break; @@ -238,9 +243,10 @@ static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { static QState ToastOven_final(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /* ${SMs::ToastOven::SM::final} */ + /*${SMs::ToastOven::SM::final} */ case Q_ENTRY_SIG: { printf("\nBye! Bye!\n"); + QF_onCleanup(); exit(0); status_ = Q_HANDLED(); break; @@ -252,4 +258,4 @@ static QState ToastOven_final(ToastOven * const me, QEvt const * const e) { } return status_; } - +/*$enddef${SMs::ToastOven} #################################################*/ diff --git a/examples/win32/history_qhsm/history.h b/examples/workstation/history_qhsm/history.h similarity index 66% rename from examples/win32/history_qhsm/history.h rename to examples/workstation/history_qhsm/history.h index 9da7e3b7..08c1d7b2 100644 --- a/examples/win32/history_qhsm/history.h +++ b/examples/workstation/history_qhsm/history.h @@ -1,8 +1,9 @@ -/***************************************************************************** +/*$file${.::history.h} #####################################################*/ +/* * Model: history.qm -* File: ./history.h +* File: ${.::history.h} * -* This code has been generated by QM tool (see state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -13,8 +14,8 @@ * 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. -*****************************************************************************/ -/*${.::history.h} ..........................................................*/ +*/ +/*$endhead${.::history.h} ##################################################*/ #ifndef history_h #define history_h @@ -29,8 +30,9 @@ enum ToastOvenSignals { extern QHsm * const the_oven; /* opaque pointer to the oven HSM */ +/*$declare${SMs::ToastOven_ctor} ###########################################*/ /*${SMs::ToastOven_ctor} ...................................................*/ void ToastOven_ctor(void); +/*$enddecl${SMs::ToastOven_ctor} ###########################################*/ - -#endif /* history_h */ +#endif /* history_h */ \ No newline at end of file diff --git a/examples/win32/history_qhsm/history.qm b/examples/workstation/history_qhsm/history.qm similarity index 98% rename from examples/win32/history_qhsm/history.qm rename to examples/workstation/history_qhsm/history.qm index 7038a1d8..090ea579 100644 --- a/examples/win32/history_qhsm/history.qm +++ b/examples/workstation/history_qhsm/history.qm @@ -1,5 +1,5 @@ - + QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. @@ -102,6 +102,7 @@ printf("\nBye! Bye!\n"); +QF_onCleanup(); exit(0); diff --git a/examples/win32/history_qhsm/main.c b/examples/workstation/history_qhsm/main.c similarity index 72% rename from examples/win32/history_qhsm/main.c rename to examples/workstation/history_qhsm/main.c index da57c94b..9beeb2f8 100644 --- a/examples/win32/history_qhsm/main.c +++ b/examples/workstation/history_qhsm/main.c @@ -1,13 +1,13 @@ /***************************************************************************** * Product: History Example, Win32 -* Last updated for version 5.8.0 -* Last updated on 2016-11-19 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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,19 +28,20 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ -#include "qep_port.h" -#include "qassert.h" +#include "qpc.h" #include "history.h" -#include #include #include /*..........................................................................*/ int main() { + QF_init(); + QF_onStartup(); + printf("History state pattern\nQP version: %s\n" "Press 'o' to OPEN the door\n" "Press 'c' to CLOSE the door\n" @@ -50,7 +51,7 @@ int main() { "Press ESC to quit...\n", QP_versionStr); - /* instantiate the ToastOven HSM and trigger the initial transition */ + /* instantiate the ToastOven HSM and trigger the initial transition */ ToastOven_ctor(); QHSM_INIT(the_oven, (QEvt *)0); @@ -59,8 +60,8 @@ int main() { uint8_t c; printf("\n"); - c = (uint8_t)_getch(); /* read one character from the console */ - printf("%c: ", c); + c = (uint8_t)QF_consoleWaitForKey(); + printf("%c: ", (c >= ' ') ? c : 'X'); switch (c) { case 'o': e.sig = OPEN_SIG; break; @@ -73,10 +74,25 @@ int main() { /* dispatch the event into the state machine */ QHSM_DISPATCH(the_oven, &e); } + + QF_onCleanup(); return 0; } + +/*..........................................................................*/ +void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { +} + /*..........................................................................*/ void Q_onAssert(char const * const file, int line) { fprintf(stderr, "Assertion failed in %s, line %d", file, line); - _exit(-1); + exit(-1); } diff --git a/examples/workstation/history_qmsm/Makefile b/examples/workstation/history_qmsm/Makefile new file mode 100644 index 00000000..36736b56 --- /dev/null +++ b/examples/workstation/history_qmsm/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := history_qmsm + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + main.c \ + history.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/history_qmsm/history.c b/examples/workstation/history_qmsm/history.c similarity index 99% rename from examples/win32/history_qmsm/history.c rename to examples/workstation/history_qmsm/history.c index 6c3f9374..e2f3ca32 100644 --- a/examples/win32/history_qmsm/history.c +++ b/examples/workstation/history_qmsm/history.c @@ -3,7 +3,7 @@ * Model: history.qm * File: ${.::history.c} * -* This code has been generated by QM 4.2.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (https://www.state-machine.com/qm). * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * * This code is covered by the following QP license: @@ -114,11 +114,12 @@ static ToastOven l_oven; /* the only instance of the ToastOven class */ /* global-scope definitions -----------------------------------------*/ QMsm * const the_oven = (QMsm *)&l_oven; /* the opaque pointer */ -/*$define${SMs::ToastOven_ctor} ############################################*/ /* Check for the minimum required QP version */ -#if ((QP_VERSION < 630) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) #error qpc version 6.3.0 or higher required #endif + +/*$define${SMs::ToastOven_ctor} ############################################*/ /*${SMs::ToastOven_ctor} ...................................................*/ void ToastOven_ctor(void) { ToastOven *me = &l_oven; @@ -421,6 +422,7 @@ static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { /*${SMs::ToastOven::SM::final} */ static QState ToastOven_final_e(ToastOven * const me) { printf("\nBye! Bye!\n"); + QF_onCleanup(); exit(0); (void)me; /* avoid compiler warning in case 'me' is not used */ return QM_ENTRY(&ToastOven_final_s); diff --git a/examples/win32/history_qmsm/history.h b/examples/workstation/history_qmsm/history.h similarity index 95% rename from examples/win32/history_qmsm/history.h rename to examples/workstation/history_qmsm/history.h index 8fd8a5b5..6785d390 100644 --- a/examples/win32/history_qmsm/history.h +++ b/examples/workstation/history_qmsm/history.h @@ -3,7 +3,7 @@ * Model: history.qm * File: ${.::history.h} * -* This code has been generated by QM 4.2.0 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (https://www.state-machine.com/qm). * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * * This code is covered by the following QP license: diff --git a/examples/win32/history_qmsm/history.qm b/examples/workstation/history_qmsm/history.qm similarity index 98% rename from examples/win32/history_qmsm/history.qm rename to examples/workstation/history_qmsm/history.qm index 2c69b5b5..0bdb314d 100644 --- a/examples/win32/history_qmsm/history.qm +++ b/examples/workstation/history_qmsm/history.qm @@ -1,5 +1,5 @@ - + QMsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing the QMsm class implementation. @@ -103,6 +103,7 @@ printf("\nBye! Bye!\n"); +QF_onCleanup(); exit(0); diff --git a/examples/win32/history_qmsm/main.c b/examples/workstation/history_qmsm/main.c similarity index 71% rename from examples/win32/history_qmsm/main.c rename to examples/workstation/history_qmsm/main.c index e02c263b..0791f437 100644 --- a/examples/win32/history_qmsm/main.c +++ b/examples/workstation/history_qmsm/main.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: History with QM example, Win32 -* Last updated for version 5.8.0 -* Last updated on 2016-11-19 +* Product: History Example, Win32 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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,19 +28,20 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com *****************************************************************************/ -#include "qep_port.h" -#include "qassert.h" +#include "qpc.h" #include "history.h" -#include #include #include /*..........................................................................*/ int main() { + QF_init(); + QF_onStartup(); + printf("History state pattern\nQP version: %s\n" "Press 'o' to OPEN the door\n" "Press 'c' to CLOSE the door\n" @@ -50,7 +51,7 @@ int main() { "Press ESC to quit...\n", QP_versionStr); - /* instantiate the ToastOven HSM and trigger the initial transition */ + /* instantiate the ToastOven HSM and trigger the initial transition */ ToastOven_ctor(); QHSM_INIT(the_oven, (QEvt *)0); @@ -59,8 +60,8 @@ int main() { uint8_t c; printf("\n"); - c = (uint8_t)_getch(); /* read one character from the console */ - printf("%c: ", c); + c = (uint8_t)QF_consoleWaitForKey(); + printf("%c: ", (c >= ' ') ? c : 'X'); switch (c) { case 'o': e.sig = OPEN_SIG; break; @@ -73,10 +74,26 @@ int main() { /* dispatch the event into the state machine */ QHSM_DISPATCH(the_oven, &e); } + + QF_onCleanup(); return 0; } + +/*..........................................................................*/ +void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +/*..........................................................................*/ +void QF_onClockTick(void) { +} + /*..........................................................................*/ void Q_onAssert(char const * const file, int line) { fprintf(stderr, "Assertion failed in %s, line %d", file, line); - _exit(-1); + QF_onCleanup(); + exit(-1); } diff --git a/examples/workstation/qhsmtst/Makefile b/examples/workstation/qhsmtst/Makefile new file mode 100644 index 00000000..98d0efe6 --- /dev/null +++ b/examples/workstation/qhsmtst/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := qhsmtst + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + main.c \ + qhsmtst.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/qhsmtst/log.txt b/examples/workstation/qhsmtst/log.txt similarity index 95% rename from examples/win32/qhsmtst/log.txt rename to examples/workstation/qhsmtst/log.txt index 8ae564ab..dba9b470 100644 --- a/examples/win32/qhsmtst/log.txt +++ b/examples/workstation/qhsmtst/log.txt @@ -1,4 +1,4 @@ -QHsmTst example, QP 6.2.0 +QHsmTst example, QP 6.3.6 top-INIT;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY; A:s21-A;s211-EXIT;s21-EXIT;s21-ENTRY;s21-INIT;s211-ENTRY; B:s21-B;s211-EXIT;s211-ENTRY; diff --git a/examples/win32/qhsmtst/main.c b/examples/workstation/qhsmtst/main.c similarity index 76% rename from examples/win32/qhsmtst/main.c rename to examples/workstation/qhsmtst/main.c index 9ea1b446..b2bc3cde 100644 --- a/examples/win32/qhsmtst/main.c +++ b/examples/workstation/qhsmtst/main.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: QHsmTst Example, Win32 -* Last updated for version 6.3.0 -* Last updated on 2018-05-07 +* Product: QHsmTst Example +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 @@ -34,10 +34,8 @@ #include "qpc.h" #include "qhsmtst.h" -#include #include #include -#include Q_DEFINE_THIS_FILE @@ -47,7 +45,16 @@ static void dispatch(QSignal sig); /*..........................................................................*/ int main(int argc, char *argv[]) { - QHsmTst_ctor(); /* instantiate the QHsmTst object */ + +#ifdef Q_SPY + uint8_t qsBuf[128]; + QS_initBuf(qsBuf, sizeof(qsBuf)); +#endif + + QF_init(); + QF_onStartup(); + + QHsmTst_ctor(); /* instantiate the QHsmTst object */ if (argc > 1) { /* file name provided? */ l_outFile = fopen(argv[1], "w"); @@ -66,9 +73,9 @@ int main(int argc, char *argv[]) { QEvt e; int c; - printf("\n>"); - c = _getche(); /* get a character from the console with echo */ - printf(": "); + printf("\n"); + c = (uint8_t)QF_consoleWaitForKey(); + printf("%c: ", (c >= ' ') ? c : 'X'); if ('a' <= c && c <= 'i') { /* in range? */ e.sig = (QSignal)(c - 'a' + A_SIG); @@ -123,22 +130,24 @@ int main(int argc, char *argv[]) { fclose(l_outFile); } + QF_onCleanup(); return 0; } /*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - _exit(-1); +void Q_onAssert(char const * const module, int loc) { + fprintf(stderr, "Assertion failed in %s:%d\n", module, loc); + QF_onCleanup(); + exit(-1); } /*..........................................................................*/ void BSP_display(char const *msg) { fprintf(l_outFile, msg); - fflush(l_outFile); } /*..........................................................................*/ void BSP_exit(void) { - printf("Bye, Bye!"); - _exit(0); + printf("Bye, Bye!\n"); + QF_onCleanup(); + exit(0); } /*..........................................................................*/ static void dispatch(QSignal sig) { @@ -150,27 +159,38 @@ static void dispatch(QSignal sig) { } /*--------------------------------------------------------------------------*/ -#ifdef Q_SPY -#include "qs_port.h" - -/*..........................................................................*/ void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); } /*..........................................................................*/ void QF_onClockTick(void) { } -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QS_onCleanup(void) { -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -void QS_onFlush(void) { -} -#endif + +/*--------------------------------------------------------------------------*/ +#ifdef Q_SPY /* define QS callbacks */ + +/*! callback function to execute user commands */ +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + /* unused parameters */ + (void)param1; + (void)param2; + (void)param3; +} + +#endif /* Q_SPY */ +/*--------------------------------------------------------------------------*/ diff --git a/examples/win32/qhsmtst/qhsmtst.c b/examples/workstation/qhsmtst/qhsmtst.c similarity index 98% rename from examples/win32/qhsmtst/qhsmtst.c rename to examples/workstation/qhsmtst/qhsmtst.c index a5456d91..e2506014 100644 --- a/examples/win32/qhsmtst/qhsmtst.c +++ b/examples/workstation/qhsmtst/qhsmtst.c @@ -3,7 +3,7 @@ * Model: qhsmtst.qm * File: ${.::qhsmtst.c} * -* This code has been generated by QM 4.2.1 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 @@ -44,11 +44,12 @@ static QHsmTst l_hsmtst; /* the only instance of the QHsmTst class */ /* global-scope definitions ---------------------------------------*/ QHsm * const the_hsm = (QHsm *)&l_hsmtst; /* the opaque pointer */ -/*$define${HSMs::QHsmTst_ctor} #############################################*/ /* Check for the minimum required QP version */ -#if ((QP_VERSION < 630) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) #error qpc version 6.3.0 or higher required #endif + +/*$define${HSMs::QHsmTst_ctor} #############################################*/ /*${HSMs::QHsmTst_ctor} ....................................................*/ void QHsmTst_ctor(void) { QHsmTst *me = &l_hsmtst; diff --git a/examples/win32/qhsmtst/qhsmtst.h b/examples/workstation/qhsmtst/qhsmtst.h similarity index 95% rename from examples/win32/qhsmtst/qhsmtst.h rename to examples/workstation/qhsmtst/qhsmtst.h index ef3e083b..04588175 100644 --- a/examples/win32/qhsmtst/qhsmtst.h +++ b/examples/workstation/qhsmtst/qhsmtst.h @@ -3,7 +3,7 @@ * Model: qhsmtst.qm * File: ${.::qhsmtst.h} * -* This code has been generated by QM 4.2.1 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (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 diff --git a/examples/win32/qhsmtst/qhsmtst.qm b/examples/workstation/qhsmtst/qhsmtst.qm similarity index 99% rename from examples/win32/qhsmtst/qhsmtst.qm rename to examples/workstation/qhsmtst/qhsmtst.qm index b5a2fd7a..f24c2202 100644 --- a/examples/win32/qhsmtst/qhsmtst.qm +++ b/examples/workstation/qhsmtst/qhsmtst.qm @@ -1,5 +1,5 @@ - + QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. diff --git a/examples/win32/qhsmtst/qhsmtst.sln b/examples/workstation/qhsmtst/qhsmtst.sln similarity index 100% rename from examples/win32/qhsmtst/qhsmtst.sln rename to examples/workstation/qhsmtst/qhsmtst.sln diff --git a/examples/win32/qhsmtst/qhsmtst.vcxproj b/examples/workstation/qhsmtst/qhsmtst.vcxproj similarity index 79% rename from examples/win32/qhsmtst/qhsmtst.vcxproj rename to examples/workstation/qhsmtst/qhsmtst.vcxproj index 97c21ca1..f89e15ca 100644 --- a/examples/win32/qhsmtst/qhsmtst.vcxproj +++ b/examples/workstation/qhsmtst/qhsmtst.vcxproj @@ -64,7 +64,7 @@ Disabled - .;../../../include;../../../ports/win32;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false @@ -78,8 +78,8 @@ Default - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) + qp.lib;%(AdditionalDependencies) + ../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true Console MachineX86 @@ -92,7 +92,7 @@ MaxSpeed true - .;../../../include;../../../ports/win32;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) NDEBUG;snprintf=_snprintf;WIN32;_CONSOLE;%(PreprocessorDefinitions) false @@ -106,8 +106,8 @@ 4127 - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) + qp.lib;%(AdditionalDependencies) + ../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true Console true @@ -121,7 +121,7 @@ Disabled - .;../../../include;../../../ports/win32;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) Q_SPY;snprintf=_snprintf;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false @@ -134,8 +134,8 @@ 4127 - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) + qp.lib;wsock32.lib;%(AdditionalDependencies) + ../../../ports/win32-qv/$(Configuration);%(AdditionalLibraryDirectories) true Console MachineX86 @@ -145,10 +145,6 @@ - - true - true - @@ -156,18 +152,6 @@ - - - true - - - true - true - - - true - - diff --git a/examples/workstation/qhsmtst/qhsmtst.vcxproj.filters b/examples/workstation/qhsmtst/qhsmtst.vcxproj.filters new file mode 100644 index 00000000..be3b4d06 --- /dev/null +++ b/examples/workstation/qhsmtst/qhsmtst.vcxproj.filters @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/examples/workstation/qmsmtst/Makefile b/examples/workstation/qmsmtst/Makefile new file mode 100644 index 00000000..5b388c3f --- /dev/null +++ b/examples/workstation/qmsmtst/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := qmsmtst + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + main.c \ + qmsmtst.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/qmsmtst/log.txt b/examples/workstation/qmsmtst/log.txt similarity index 95% rename from examples/win32/qmsmtst/log.txt rename to examples/workstation/qmsmtst/log.txt index bd11169e..34df9e2c 100644 --- a/examples/win32/qmsmtst/log.txt +++ b/examples/workstation/qmsmtst/log.txt @@ -1,4 +1,4 @@ -QMsmTst example, QP 6.3.0 +QMsmTst example, QP 6.3.6 top-INIT;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY; A:s21-A;s211-EXIT;s21-EXIT;s21-ENTRY;s21-INIT;s211-ENTRY; B:s21-B;s211-EXIT;s211-ENTRY; diff --git a/examples/win32/qmsmtst/main.c b/examples/workstation/qmsmtst/main.c similarity index 76% rename from examples/win32/qmsmtst/main.c rename to examples/workstation/qmsmtst/main.c index fa87582d..adf1099d 100644 --- a/examples/win32/qmsmtst/main.c +++ b/examples/workstation/qmsmtst/main.c @@ -1,13 +1,13 @@ /***************************************************************************** -* Product: QMsmTst Example, Win32 -* Last updated for version 6.3.0 -* Last updated on 2018-05-07 +* Product: QMsmTst Example, Workstation-console +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 @@ -34,10 +34,8 @@ #include "qpc.h" #include "qmsmtst.h" -#include #include #include -#include Q_DEFINE_THIS_FILE @@ -47,7 +45,15 @@ static void dispatch(QSignal sig); /*..........................................................................*/ int main(int argc, char *argv[]) { - QMsmTst_ctor(); /* instantiate the QMsmTst object */ +#ifdef Q_SPY + uint8_t qsBuf[128]; + QS_initBuf(qsBuf, sizeof(qsBuf)); +#endif + + QF_init(); + QF_onStartup(); + + QMsmTst_ctor(); /* instantiate the QMsmTst object */ if (argc > 1) { /* file name provided? */ l_outFile = fopen(argv[1], "w"); @@ -66,9 +72,9 @@ int main(int argc, char *argv[]) { QEvt e; int c; - printf("\n>"); - c = _getche(); /* get a character from the console with echo */ - printf(": "); + printf("\n"); + c = (uint8_t)QF_consoleWaitForKey(); + printf("%c: ", (c >= ' ') ? c : 'X'); if ('a' <= c && c <= 'i') { /* in range? */ e.sig = (QSignal)(c - 'a' + A_SIG); @@ -123,12 +129,14 @@ int main(int argc, char *argv[]) { fclose(l_outFile); } + QF_onCleanup(); return 0; } /*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - _exit(-1); +void Q_onAssert(char const * const module, int loc) { + fprintf(stderr, "Assertion failed in %s:%d\n", module, loc); + QF_onCleanup(); + exit(-1); } /*..........................................................................*/ void BSP_display(char const *msg) { @@ -137,8 +145,9 @@ void BSP_display(char const *msg) { } /*..........................................................................*/ void BSP_exit(void) { - printf("Bye, Bye!"); - _exit(0); + printf("Bye, Bye!\n"); + QF_onCleanup(); + exit(0); } /*..........................................................................*/ static void dispatch(QSignal sig) { @@ -150,27 +159,38 @@ static void dispatch(QSignal sig) { } /*--------------------------------------------------------------------------*/ -#ifdef Q_SPY -#include "qs_port.h" - -/*..........................................................................*/ void QF_onStartup(void) { + QF_consoleSetup(); +} +/*..........................................................................*/ +void QF_onCleanup(void) { + QF_consoleCleanup(); } /*..........................................................................*/ void QF_onClockTick(void) { } -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QS_onCleanup(void) { -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (QSTimeCtr)clock(); -} -/*..........................................................................*/ -void QS_onFlush(void) { -} -#endif + +/*--------------------------------------------------------------------------*/ +#ifdef Q_SPY /* define QS callbacks */ + +/*! callback function to execute user commands */ +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + /* unused parameters */ + (void)param1; + (void)param2; + (void)param3; +} + +#endif /* Q_SPY */ +/*--------------------------------------------------------------------------*/ diff --git a/examples/win32/qmsmtst/qmsmtst.c b/examples/workstation/qmsmtst/qmsmtst.c similarity index 99% rename from examples/win32/qmsmtst/qmsmtst.c rename to examples/workstation/qmsmtst/qmsmtst.c index 5a745509..8b9b129e 100644 --- a/examples/win32/qmsmtst/qmsmtst.c +++ b/examples/workstation/qmsmtst/qmsmtst.c @@ -3,7 +3,7 @@ * Model: qmsmtst.qm * File: ${.::qmsmtst.c} * -* This code has been generated by QM 4.2.1 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (https://www.state-machine.com/qm). * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * * This code is covered by the following QP license: @@ -104,11 +104,12 @@ static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */ /* global-scope definitions ---------------------------------------*/ QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */ -/*$define${SMs::QMsmTst_ctor} ##############################################*/ /* Check for the minimum required QP version */ -#if ((QP_VERSION < 630) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8))) +#if (QP_VERSION < 630U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) #error qpc version 6.3.0 or higher required #endif + +/*$define${SMs::QMsmTst_ctor} ##############################################*/ /*${SMs::QMsmTst_ctor} .....................................................*/ void QMsmTst_ctor(void) { QMsmTst *me = &l_msmtst; diff --git a/examples/win32/qmsmtst/qmsmtst.h b/examples/workstation/qmsmtst/qmsmtst.h similarity index 95% rename from examples/win32/qmsmtst/qmsmtst.h rename to examples/workstation/qmsmtst/qmsmtst.h index 5ab4af8d..508bbc1b 100644 --- a/examples/win32/qmsmtst/qmsmtst.h +++ b/examples/workstation/qmsmtst/qmsmtst.h @@ -3,7 +3,7 @@ * Model: qmsmtst.qm * File: ${.::qmsmtst.h} * -* This code has been generated by QM 4.2.1 (https://www.state-machine.com/qm). +* This code has been generated by QM 4.3.1 (https://www.state-machine.com/qm). * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * * This code is covered by the following QP license: diff --git a/examples/win32/qmsmtst/qmsmtst.qm b/examples/workstation/qmsmtst/qmsmtst.qm similarity index 99% rename from examples/win32/qmsmtst/qmsmtst.qm rename to examples/workstation/qmsmtst/qmsmtst.qm index 665fd0f3..138e9869 100644 --- a/examples/win32/qmsmtst/qmsmtst.qm +++ b/examples/workstation/qmsmtst/qmsmtst.qm @@ -1,5 +1,5 @@ - + QMsmTst is a QMsm state machine test based on the contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. diff --git a/examples/workstation/reminder/Makefile b/examples/workstation/reminder/Makefile new file mode 100644 index 00000000..30d7adbd --- /dev/null +++ b/examples/workstation/reminder/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := reminder + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + reminder.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32-qv/reminder2/bsp.c b/examples/workstation/reminder/bsp.c similarity index 81% rename from examples/win32-qv/reminder2/bsp.c rename to examples/workstation/reminder/bsp.c index d47736d8..c00372c9 100644 --- a/examples/win32-qv/reminder2/bsp.c +++ b/examples/workstation/reminder/bsp.c @@ -34,12 +34,10 @@ #include "qpc.h" #include "bsp.h" -#include #include #include -#include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ void BSP_init(int argc, char *argv[]) { @@ -48,22 +46,29 @@ void BSP_init(int argc, char *argv[]) { } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ + QF_consoleSetup(); } /*..........................................................................*/ void QF_onCleanup(void) { printf("\nBye! Bye!\n"); + QF_consoleCleanup(); } /*..........................................................................*/ void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - BSP_onKeyboardInput(_getch()); + int ch; + + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ + + ch = QF_consoleGetKey(); + if (ch != 0) { /* any key pressed? */ + BSP_onKeyboardInput(ch); } } /*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - QF_stop(); +void Q_onAssert(char const * const module, int loc) { + fprintf(stderr, "Assertion failed in %s:%d", module, loc); + QF_onCleanup(); + exit(-1); } diff --git a/examples/win32/comp/bsp.h b/examples/workstation/reminder/bsp.h similarity index 100% rename from examples/win32/comp/bsp.h rename to examples/workstation/reminder/bsp.h diff --git a/examples/win32/reminder/reminder.c b/examples/workstation/reminder/reminder.c similarity index 99% rename from examples/win32/reminder/reminder.c rename to examples/workstation/reminder/reminder.c index c41fa3ff..cc2cac55 100644 --- a/examples/win32/reminder/reminder.c +++ b/examples/workstation/reminder/reminder.c @@ -36,7 +36,7 @@ #include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ enum SensorSignals { diff --git a/examples/workstation/reminder2/Makefile b/examples/workstation/reminder2/Makefile new file mode 100644 index 00000000..15fbd82f --- /dev/null +++ b/examples/workstation/reminder2/Makefile @@ -0,0 +1,286 @@ +############################################################################## +# Product: Makefile for QP/C for Windows and POSIX *HOSTS* +# Last updated for version 6.3.6 +# Last updated on 2018-10-14 +# +# 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 +############################################################################## +# +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# make clean # cleanup the build +# make CONF=spy clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := reminder2 + +#----------------------------------------------------------------------------- +# project directories: +# + +# list of all source directories used by this project +VPATH := . \ + +# list of all include directories needed by this project +INCLUDES := -I. \ + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + bsp.c \ + reminder2.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API +DEFINES := -DQP_API_VERSION=9999 + +ifeq (,$(CONF)) + CONF := dbg +endif + +#----------------------------------------------------------------------------- +# add QP/C framework (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + +# NOTE: +# For Windows hosts, you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/win32-qv +#QP_PORT_DIR := $(QPC)/ports/win32 +LIB_DIRS += -L$(QP_PORT_DIR)/$(CONF) +LIBS += -lqp -lwsock32 + +else + +# NOTE: +# For POSIX hosts (Linux, MacOS), you can choose: +# - the single-threaded QP/C port (win32-qv) or +# - the multithreaded QP/C port (win32). +# +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix + +C_SRCS += \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qf_port.c + +QS_SRCS := \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qs_port.c + +LIBS += -lpthread + +endif + +#============================================================================ +# Typically you should not need to change anything below this line + +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QPC)/src -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# http://sourceforge.net/projects/qpc/files/QTools/ +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build configurations... + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := build_rel + +CFLAGS = -c -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := build_spy + +C_SRCS += $(QS_SRCS) +VPATH += $(QPC)/src/qs + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := build + +CFLAGS = -c -g -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections \ + -O -Wall -W $(INCLUDES) $(DEFINES) + +endif # ..................................................................... + +LINKFLAGS := + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_EXE) + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(TARGET_EXE) + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/examples/win32/comp/bsp.c b/examples/workstation/reminder2/bsp.c similarity index 81% rename from examples/win32/comp/bsp.c rename to examples/workstation/reminder2/bsp.c index d47736d8..c00372c9 100644 --- a/examples/win32/comp/bsp.c +++ b/examples/workstation/reminder2/bsp.c @@ -34,12 +34,10 @@ #include "qpc.h" #include "bsp.h" -#include #include #include -#include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ void BSP_init(int argc, char *argv[]) { @@ -48,22 +46,29 @@ void BSP_init(int argc, char *argv[]) { } /*..........................................................................*/ void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */ + QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ + QF_consoleSetup(); } /*..........................................................................*/ void QF_onCleanup(void) { printf("\nBye! Bye!\n"); + QF_consoleCleanup(); } /*..........................................................................*/ void QF_onClockTick(void) { - QF_TICK(&l_clock_tick); /* perform the QF clock tick processing */ - if (_kbhit()) { /* any key pressed? */ - BSP_onKeyboardInput(_getch()); + int ch; + + QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ + + ch = QF_consoleGetKey(); + if (ch != 0) { /* any key pressed? */ + BSP_onKeyboardInput(ch); } } /*..........................................................................*/ -void Q_onAssert(char const * const file, int line) { - fprintf(stderr, "Assertion failed in %s, line %d", file, line); - QF_stop(); +void Q_onAssert(char const * const module, int loc) { + fprintf(stderr, "Assertion failed in %s:%d", module, loc); + QF_onCleanup(); + exit(-1); } diff --git a/examples/win32/defer/bsp.h b/examples/workstation/reminder2/bsp.h similarity index 100% rename from examples/win32/defer/bsp.h rename to examples/workstation/reminder2/bsp.h diff --git a/examples/win32/reminder2/reminder2.c b/examples/workstation/reminder2/reminder2.c similarity index 98% rename from examples/win32/reminder2/reminder2.c rename to examples/workstation/reminder2/reminder2.c index 05cbe243..d0375e37 100644 --- a/examples/win32/reminder2/reminder2.c +++ b/examples/workstation/reminder2/reminder2.c @@ -28,15 +28,16 @@ * along with this program. If not, see . * * Contact information: -* Web : https://state-machine.com -* Email: info@state-machine.com +* https://state-machine.com +* mailto:info@state-machine.com *****************************************************************************/ #include "qpc.h" #include "bsp.h" +#include #include -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE /*..........................................................................*/ enum ReminderSignals { diff --git a/include/qep.h b/include/qep.h index e8284b96..989760ba 100644 --- a/include/qep.h +++ b/include/qep.h @@ -4,12 +4,12 @@ * @ingroup qep * @cond ****************************************************************************** -* Last updated for version 6.3.4 -* Last updated on 2018-08-08 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -45,16 +45,16 @@ * major version number, Y is a 1-digit minor version number, and Z is * a 1-digit release number. */ -#define QP_VERSION 634U +#define QP_VERSION 636U /*! The current QP version number string of the form X.Y.Z, where X is * a 1-digit major version number, Y is a 1-digit minor version number, * and Z is a 1-digit release number. */ -#define QP_VERSION_STR "6.3.4" +#define QP_VERSION_STR "6.3.6" -/*! Tamperproof current QP release (6.3.4) and date (2018-08-09) */ -#define QP_RELEASE 0x943AB9F5U +/*! Tamperproof current QP release (6.3.6) and date (2018-10-20) */ +#define QP_RELEASE 0x941A87C3U /****************************************************************************/ diff --git a/include/qs.h b/include/qs.h index cf372e9e..68ea3acc 100644 --- a/include/qs.h +++ b/include/qs.h @@ -4,12 +4,12 @@ * @ingroup qs qpspy * @cond ****************************************************************************** -* Last updated for version 6.3.1 -* Last updated on 2018-05-24 +* Last updated for version 6.3.6 +* Last updated on 2018-10-14 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -158,7 +158,7 @@ enum QSpyRecords { QS_TARGET_INFO, /*!< reports the Target information */ QS_TARGET_DONE, /*!< reports completion of a user callback */ QS_RX_STATUS, /*!< reports QS data receive status */ - QS_MSC_RESERVED1, + QS_QUERY_DATA, /*!< reports the data from "current object" query */ QS_PEEK_DATA, /*!< reports the data from the PEEK query */ QS_ASSERT_FAIL, /*!< assertion failed in the code */ @@ -189,7 +189,8 @@ enum QSpyUserRecords { QS_USER0 = QS_USER, /*!< offset for User Group 0 */ QS_USER1 = QS_USER0 + 10, /*!< offset for User Group 1 */ QS_USER2 = QS_USER1 + 10, /*!< offset for User Group 2 */ - QS_USER3 = QS_USER2 + 10 /*!< offset for User Group 3 */ + QS_USER3 = QS_USER2 + 10, /*!< offset for User Group 3 */ + QS_USER4 = QS_USER3 + 10 /*!< offset for User Group 4 */ }; #ifndef QS_TIME_SIZE @@ -731,6 +732,9 @@ QSTimeCtr QS_onGetTime(void); /*! Internal QS macro to output an unformatted uint32_t data element */ #define QS_U32_(data_) (QS_u32_((uint32_t)(data_))) +/*! Internal QS macro to output a zero-terminated ASCII string element */ +#define QS_STR_(msg_) (QS_str_((msg_))) + #if (Q_SIGNAL_SIZE == 1) /*! Internal macro to output an unformatted event signal data element */ @@ -780,11 +784,8 @@ QSTimeCtr QS_onGetTime(void); #define QS_FUN_(fun_) (QS_u32_((uint32_t)(fun_))) #endif - -/*! Internal QS macro to output a zero-terminated ASCII string element */ -#define QS_STR_(msg_) (QS_str_((msg_))) - -/* Macros for use in the client code .......................................*/ +/****************************************************************************/ +/* Macros for use in the client code */ /*! Enumerates data formats recognized by QS */ /** @@ -1069,6 +1070,7 @@ enum { /*! get the current QS version number string of the form "X.Y.Z" */ #define QS_getVersion() (QP_versionStr) + /****************************************************************************/ /* QS private data (the transmit channel) */ typedef uint_fast16_t QSCtr; /*!< QS ring buffer counter and offset type */ @@ -1130,7 +1132,7 @@ enum QSpyRxRecords { QS_RX_AO_FILTER, /*!< set local AO filter in the Target */ QS_RX_CURR_OBJ, /*!< set the "current-object" in the Target */ QS_RX_TEST_CONTINUE, /*!< continue a test after QS_TEST_PAUSE() */ - QS_RX_RESERVED1, /*!< reserved for future use */ + QS_RX_QUERY_CURR, /*!< query the "current object" in the Target */ QS_RX_EVENT /*!< inject an event to the Target */ }; @@ -1140,7 +1142,9 @@ void QS_rxInitBuf(uint8_t sto[], uint16_t stoSize); /*! Parse all bytes present in the QS RX data buffer */ void QS_rxParse(void); -/*! Private QS-RX data to keep track of the lock-free buffer */ +/*! Private QS-RX data to keep track of the current objects and +* the lock-free RX buffer +*/ typedef struct { void *currObj[MAX_OBJ]; /*!< current objects */ uint8_t *buf; /*!< pointer to the start of the ring buffer */ @@ -1181,6 +1185,18 @@ void QS_onReset(void); void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3); +/*! macro to handle the QS output from the application +* NOTE: if this macro is used, the application must define QS_output(). +*/ +#define QS_OUTPUT() (QS_output()) + +/*! macro to handle the QS-RX input to the application +* NOTE: if this macro is used, the application must define QS_rx_input(). +*/ +#define QS_RX_INPUT() (QS_rx_input()) + +/****************************************************************************/ +/* Facilities for use in QUTest only */ #ifdef Q_UTEST /*! callback to setup a unit test inside the Target */ void QS_onTestSetup(void); @@ -1191,12 +1207,19 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, /*! callback to run the test loop */ void QS_onTestLoop(void); - /*! callback to "massage" the test event, if neccessary */ + /*! callback to "massage" the test event before dispatching/posting it */ void QS_onTestEvt(QEvt *e); + /*! callback to examine an event that is about to be posted */ + void QS_onTestPost(void const *sender, QActive *recipient, + QEvt const *e, bool status); + /*! QS internal function to process posted events during test */ void QS_processTestEvts_(void); + /*! internal function to process armed time events during test */ + void QS_tickX_(uint_fast8_t const tickRate, void const * const sender); + /*! QS internal function to get the Test-Probe for a given API */ uint32_t QS_getTestProbe_(void (* const api)(void)); @@ -1219,20 +1242,32 @@ void QS_onCommand(uint8_t cmdId, uint32_t param1, QS_onTestLoop(); \ } while (0) -#ifdef QP_IMPL - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) + enum QUTestUserRecords { + QUTEST_ON_POST = 124 + }; - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QS_rxPriv_.readySet, (uint_fast8_t)(me_)->prio) -#endif /* QP_IMPL */ + /************************************************************************/ + /*! QActiveDummy Object class */ + /** + * @description + * QActiveDummy is a test double for the role of collaborating active + * objects in QUTest unit testing. + */ + typedef struct { + QActive super; /* inherit QActive */ + } QActiveDummy; + + /*! Constructor of the QActiveDummy Active Object class */ + void QActiveDummy_ctor(QActiveDummy * const me); + +#else /* Q_UTEST not defined */ -#else /* dummy definitions when not building for QUTEST */ #define QS_TEST_PROBE_DEF(fun_) #define QS_TEST_PROBE(code_) #define QS_TEST_PROBE_ID(id_, code_) #define QS_TEST_PAUSE() ((void)0) + #endif /* Q_UTEST */ #endif /* qs_h */ diff --git a/include/qs_dummy.h b/include/qs_dummy.h index 8a8f1093..90e8112e 100644 --- a/include/qs_dummy.h +++ b/include/qs_dummy.h @@ -5,14 +5,14 @@ * @ingroup qs qpspy * @cond ****************************************************************************** -* Last updated for version 5.9.0 -* Last updated on 2017-05-16 +* Last updated for version 6.3.6 +* Last updated on 2018-10-14 * -* 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) 2005-2017 Quantum Leaps, LLC. All rights reserved. +* Copyright (C) 2002-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 @@ -33,7 +33,7 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com ****************************************************************************** * @endcond @@ -93,32 +93,37 @@ #define QS_TEST_PROBE_ID(id_, code_) #define QS_TEST_PAUSE() ((void)0) +#define QS_OUTPUT() ((void)0) +#define QS_RX_INPUT() ((void)0) + /****************************************************************************/ /* internal QS macros used only in the QP components */ -#define QS_CRIT_STAT_ -#define QS_BEGIN_(rec_, refObj_, obj_) if (0) { -#define QS_END_() } -#define QS_BEGIN_NOCRIT_(rec_, refObj_, obj_) if (0) { -#define QS_END_NOCRIT_() } -#define QS_U8_(data_) ((void)0) -#define QS_2U8_(data1_, data2_) ((void)0) -#define QS_U16_(data_) ((void)0) -#define QS_U32_(data_) ((void)0) -#define QS_U64_(data_) ((void)0) -#define QS_TIME_() ((void)0) -#define QS_SIG_(sig_) ((void)0) -#define QS_EVS_(size_) ((void)0) -#define QS_OBJ_(obj_) ((void)0) -#define QS_FUN_(fun_) ((void)0) -#define QS_EQC_(ctr_) ((void)0) -#define QS_MPC_(ctr_) ((void)0) -#define QS_MPS_(size_) ((void)0) -#define QS_TEC_(ctr_) ((void)0) +#ifdef QP_IMPL + #define QS_CRIT_STAT_ + #define QS_BEGIN_(rec_, refObj_, obj_) if (0) { + #define QS_END_() } + #define QS_BEGIN_NOCRIT_(rec_, refObj_, obj_) if (0) { + #define QS_END_NOCRIT_() } + #define QS_U8_(data_) ((void)0) + #define QS_2U8_(data1_, data2_) ((void)0) + #define QS_U16_(data_) ((void)0) + #define QS_U32_(data_) ((void)0) + #define QS_U64_(data_) ((void)0) + #define QS_TIME_() ((void)0) + #define QS_SIG_(sig_) ((void)0) + #define QS_EVS_(size_) ((void)0) + #define QS_OBJ_(obj_) ((void)0) + #define QS_FUN_(fun_) ((void)0) + #define QS_EQC_(ctr_) ((void)0) + #define QS_MPC_(ctr_) ((void)0) + #define QS_MPS_(size_) ((void)0) + #define QS_TEC_(ctr_) ((void)0) -#define QF_QS_CRIT_ENTRY() ((void)0) -#define QF_QS_CRIT_EXIT() ((void)0) -#define QF_QS_ISR_ENTRY(isrnest_, prio_) ((void)0) -#define QF_QS_ISR_EXIT(isrnest_, prio_) ((void)0) -#define QF_QS_ACTION(act_) ((void)0) + #define QF_QS_CRIT_ENTRY() ((void)0) + #define QF_QS_CRIT_EXIT() ((void)0) + #define QF_QS_ISR_ENTRY(isrnest_, prio_) ((void)0) + #define QF_QS_ISR_EXIT(isrnest_, prio_) ((void)0) + #define QF_QS_ACTION(act_) ((void)0) +#endif /* QP_IMPL */ #endif /* qs_dummy_h */ diff --git a/ports/arm-cm/qutest/qf_port.h b/ports/arm-cm/qutest/qf_port.h index c136d3b4..208e77c2 100644 --- a/ports/arm-cm/qutest/qf_port.h +++ b/ports/arm-cm/qutest/qf_port.h @@ -3,12 +3,12 @@ * @brief QF/C port to Cortex-M, QUTEST unit test harness, generic C99 compiler * @cond ****************************************************************************** -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-12 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-04 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -78,6 +78,12 @@ extern uint8_t volatile QF_intNest; #define QF_SCHED_LOCK_(dummy) ((void)0) #define QF_SCHED_UNLOCK_() ((void)0) + /* native event queue operations */ + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_rxPriv_.readySet, (uint_fast8_t)(me_)->prio) + /* native QF event pool operations */ #define QF_EPOOL_TYPE_ QMPool #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ @@ -87,13 +93,8 @@ extern uint8_t volatile QF_intNest; #define QF_EPOOL_GET_(p_, e_, m_) ((e_) = (QEvt *)QMPool_get(&(p_), (m_))) #define QF_EPOOL_PUT_(p_, e_) (QMPool_put(&(p_), e_)) + #include "qf_pkg.h" /* internal QF interface */ + #endif /* QP_IMPL */ -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -* -*/ - #endif /* qf_port_h */ diff --git a/ports/posix-qutest/qf_port.h b/ports/posix-qutest/qf_port.h index a3f8de24..030f6a25 100644 --- a/ports/posix-qutest/qf_port.h +++ b/ports/posix-qutest/qf_port.h @@ -3,12 +3,12 @@ * @brief QF/C "port" for QUTEST unit test harness, generic C99 compiler * @cond ****************************************************************************** -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-12 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-04 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -78,6 +78,12 @@ extern uint8_t volatile QF_intNest; #define QF_SCHED_LOCK_(dummy) ((void)0) #define QF_SCHED_UNLOCK_() ((void)0) + /* native event queue operations */ + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_rxPriv_.readySet, (uint_fast8_t)(me_)->prio) + /* native QF event pool operations */ #define QF_EPOOL_TYPE_ QMPool #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ @@ -87,12 +93,8 @@ extern uint8_t volatile QF_intNest; #define QF_EPOOL_GET_(p_, e_, m_) ((e_) = (QEvt *)QMPool_get(&(p_), (m_))) #define QF_EPOOL_PUT_(p_, e_) (QMPool_put(&(p_), e_)) + #include "qf_pkg.h" /* internal QF interface */ + #endif /* QP_IMPL */ -/***************************************************************************** -* NOTE1: -* This QF "port" provides dummy declaration for the QF stub that provides -* empty definitions of the QF facilities. -*/ - #endif /* qf_port_h */ diff --git a/ports/posix-qutest/qutest_port.c b/ports/posix-qutest/qutest_port.c index 49e3650d..5c9cabd1 100644 --- a/ports/posix-qutest/qutest_port.c +++ b/ports/posix-qutest/qutest_port.c @@ -1,17 +1,17 @@ /** * @file -* @brief QS/C QUTEST port for POSIX -* @ingroup qf +* @brief QS/C QUTEST to POSIX +* @ingroup ports * @cond ****************************************************************************** -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-16 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-20 * -* 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 @@ -48,7 +48,6 @@ Q_DEFINE_THIS_MODULE("qutest_port") -#include /* for printf() and _snprintf_s() */ #include #include #include @@ -59,7 +58,9 @@ Q_DEFINE_THIS_MODULE("qutest_port") #include #include #include +#include #include +#include #define QS_TX_SIZE (4*1024) #define QS_RX_SIZE 1024 @@ -86,6 +87,7 @@ uint8_t QS_onStartup(void const *arg) { struct hostent *host; struct sigaction sig_act; + int flags; QS_initBuf(qsBuf, sizeof(qsBuf)); QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); @@ -110,8 +112,9 @@ uint8_t QS_onStartup(void const *arg) { l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ if (l_sock == INVALID_SOCKET){ - printf(" ERROR cannot create client socket,errno=%d\n", - errno); + fprintf(stderr, + " ERROR cannot create client socket,errno=%d\n", + errno); goto error; } @@ -133,8 +136,9 @@ uint8_t QS_onStartup(void const *arg) { /* remote hostName:port (QSPY server socket) */ host = gethostbyname(hostName); if (host == NULL) { - printf(" ERROR cannot resolve host Name=%s,errno=%d\n", - hostName, errno); + fprintf(stderr, + " ERROR cannot resolve host Name=%s,errno=%d\n", + hostName, errno); goto error; } @@ -147,9 +151,27 @@ uint8_t QS_onStartup(void const *arg) { if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) == -1) { - printf(" ERROR cannot connect to QSPY at " - "Host=%s:%d,errno=%d\n", - hostName, port_remote, errno); + fprintf(stderr, + " ERROR cannot connect to QSPY at " + "Host=%s:%d,errno=%d\n", + hostName, port_remote, errno); + goto error; + } + + /* Set the socket to non-blocking mode */ + flags = fcntl(l_sock, F_GETFL, 0); + if (flags == -1) { + fprintf(stderr, + " ERROR Socket configuration failed errno=%d\n", + errno); + QS_EXIT(); + goto error; + } + if (fcntl(l_sock, F_SETFL, flags | O_NONBLOCK) != 0) { + fprintf(stderr, + " ERROR Socket configuration failed errno=%d\n", + errno); + QS_EXIT(); goto error; } @@ -200,7 +222,8 @@ void QS_onTestLoop() { nrec = select(l_sock + 1, &readSet, (fd_set *)0, (fd_set *)0, &timeout); if (nrec < 0) { - printf(" ERROR socket select,errno=%d\n", errno); + fprintf(stderr, " ERROR socket select,errno=%d\n", + errno); QS_onCleanup(); exit(-2); } @@ -252,7 +275,7 @@ void QS_onFlush(void) { static void sigIntHandler(int dummy) { (void)dummy; /* unused parameter */ QS_onCleanup(); - printf("\n disconnecting from QSPY\n"); + //printf("\n disconnecting from QSPY\n"); exit(-1); } diff --git a/ports/posix-qv/qf_port.c b/ports/posix-qv/qf_port.c index ee4e1442..f7d75734 100644 --- a/ports/posix-qv/qf_port.c +++ b/ports/posix-qv/qf_port.c @@ -1,15 +1,15 @@ /** * @file -* @brief QF/C port to POSIX API with cooperative QV scheduler (posix-qv) +* @brief QF/C port to POSIX API (single-threaded, like QV kernel) * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 6.3.2 -* Last updated on 2018-06-18 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -49,6 +49,14 @@ #include /* for PTHREAD_STACK_MIN */ #include /* for mlockall() */ +#include +#include +#include /* for memcpy() and memset() */ +#include +#include +#include +#include +#include Q_DEFINE_THIS_MODULE("qf_port") @@ -59,16 +67,19 @@ pthread_cond_t QV_condVar_; /* Cond.var. to signal events */ /* Local objects ===========================================================*/ static bool l_isRunning; +static struct termios l_tsav; /* structure with saved terminal attributes */ static struct timespec l_tick; static int_t l_tickPrio; enum { NANOSLEEP_NSEC_PER_SEC = 1000000000 }; /* see NOTE05 */ static void *ticker_thread(void *arg); +static void sigIntHandler(int dummy); /* QF functions ============================================================*/ void QF_init(void) { extern uint_fast8_t QF_maxPool_; extern QTimeEvt QF_timeEvtHead_[QF_MAX_TICK_RATE]; + struct sigaction sig_act; /* lock memory so we're never swapped out to disk */ /*mlockall(MCL_CURRENT | MCL_FUTURE); uncomment when supported */ @@ -76,6 +87,9 @@ void QF_init(void) { /* init the global mutex with the default non-recursive initializer */ pthread_mutex_init(&QF_pThreadMutex_, NULL); + /* init the global condition variable with the default initializer */ + pthread_cond_init(&QV_condVar_, NULL); + /* clear the internal QF variables, so that the framework can (re)start * correctly even if the startup code is not called to clear the * uninitialized data (as is required by the C Standard). @@ -87,9 +101,13 @@ void QF_init(void) { l_tick.tv_sec = 0; l_tick.tv_nsec = NANOSLEEP_NSEC_PER_SEC/100L; /* default clock tick */ l_tickPrio = sched_get_priority_min(SCHED_FIFO); /* default tick prio */ -} -/****************************************************************************/ + /* install the SIGINT (Ctrl-C) signal handler */ + sig_act.sa_handler = &sigIntHandler; + sigaction(SIGINT, &sig_act, NULL); +} + +/****************************************************************************/ int_t QF_run(void) { struct sched_param sparam; @@ -214,7 +232,37 @@ void QF_stop(void) { QPSet_insert(&QV_readySet_, p); pthread_cond_signal(&QV_condVar_); } + /*..........................................................................*/ +void QF_consoleSetup(void) { + struct termios tio; /* modified terminal attributes */ + + tcgetattr(0, &l_tsav); /* save the current terminal attributes */ + tcgetattr(0, &tio); /* obtain the current terminal attributes */ + tio.c_lflag &= ~(ICANON | ECHO); /* disable the canonical mode & echo */ + tcsetattr(0, TCSANOW, &tio); /* set the new attributes */ +} +/*..........................................................................*/ +void QF_consoleCleanup(void) { + tcsetattr(0, TCSANOW, &l_tsav); /* restore the saved attributes */ +} +/*..........................................................................*/ +int QF_consoleGetKey(void) { + int byteswaiting; + ioctl(0, FIONREAD, &byteswaiting); + if (byteswaiting > 0) { + char ch; + read(0, &ch, 1); + return (int)ch; + } + return 0; /* no input at this time */ +} +/*..........................................................................*/ +int QF_consoleWaitForKey(void) { + return getchar(); +} + +/****************************************************************************/ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, @@ -243,12 +291,17 @@ void QActive_stop(QActive * const me) { static void *ticker_thread(void *arg) { /* for pthread_create() */ (void)arg; /* unused parameter */ while (l_isRunning) { /* the clock tick loop... */ - QF_onClockTick(); /* clock tick callback (must call QF_TICK_X()) */ - nanosleep(&l_tick, NULL); /* sleep for the number of ticks, NOTE05 */ + QF_onClockTick(); /* clock tick callback (must call QF_TICK_X()) */ } return (void *)0; /* return success */ } +/*..........................................................................*/ +static void sigIntHandler(int dummy) { + (void)dummy; /* unused parameter */ + QF_onCleanup(); + exit(-1); +} /***************************************************************************** * NOTE01: diff --git a/ports/posix-qv/qf_port.h b/ports/posix-qv/qf_port.h index c0ccd886..662e90fa 100644 --- a/ports/posix-qv/qf_port.h +++ b/ports/posix-qv/qf_port.h @@ -1,16 +1,16 @@ /** * @file -* @brief QF/C port to POSIX API with cooperative QV scheduler (posix-qv) +* @brief QF/C port to POSIX API (single-threaded, like the QV kernel) * @cond ****************************************************************************** -* Last updated for version 6.3.2 -* Last updated on 2018-06-16 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * -* 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 @@ -41,8 +41,8 @@ /* POSIX event queue and thread types */ #define QF_EQUEUE_TYPE QEQueue -/*#define QF_OS_OBJECT_TYPE // not provided */ -/*#define QF_THREAD_TYPE // not provided */ +/*#define QF_OS_OBJECT_TYPE // not used */ +/*#define QF_THREAD_TYPE // not used */ /* The maximum number of active objects in the application */ #define QF_MAX_ACTIVE 64 @@ -82,7 +82,14 @@ void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); /* clock tick callback (NOTE not called when "ticker thread" is not running) */ void QF_onClockTick(void); /* clock tick callback (provided in the app) */ -extern pthread_mutex_t QF_pThreadMutex_; /* mutex for QF critical section */ +/* abstractions for console access... */ +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +/* mutex for QF critical section */ +extern pthread_mutex_t QF_pThreadMutex_; /****************************************************************************/ /* interface used only inside QF implementation, but not in applications */ diff --git a/ports/posix-qv/qs_port.c b/ports/posix-qv/qs_port.c new file mode 100644 index 00000000..5df821cd --- /dev/null +++ b/ports/posix-qv/qs_port.c @@ -0,0 +1,240 @@ +/** +* @file +* @brief QS/C port to POSIX +* @ingroup ports +* @cond +****************************************************************************** +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 +* +* 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 +****************************************************************************** +* @endcond +*/ +#ifndef Q_SPY + #error "Q_SPY must be defined to compile qs_port.c" +#endif /* Q_SPY */ + +#define QP_IMPL /* this is QP implementation */ +#include "qf_port.h" /* QF port */ +#include "qassert.h" /* QP embedded systems-friendly assertions */ +#include "qs_port.h" /* include QS port */ + +Q_DEFINE_THIS_MODULE("qs_port") + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for printf() */ + +#define QS_TX_SIZE (4*1024) +#define QS_RX_SIZE 1024 +#define QS_IMEOUT_MS 100 +#define INVALID_SOCKET -1 + +/* local variables .........................................................*/ +static int l_sock = INVALID_SOCKET; + +/*..........................................................................*/ +uint8_t QS_onStartup(void const *arg) { + static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ + static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + char hostName[64]; + char const *src; + char *dst; + + uint16_t port_local = 51234; /* default local port */ + uint16_t port_remote = 6601; /* default QSPY server port */ + int sockopt_bool; + struct sockaddr_in sa_local; + struct sockaddr_in sa_remote; + struct hostent *host; + int flags; + + QS_initBuf(qsBuf, sizeof(qsBuf)); + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + src = (arg != (void const *)0) + ? (char const *)arg + : "localhost"; + dst = hostName; + while ((*src != '\0') + && (*src != ':') + && (dst < &hostName[sizeof(hostName)])) + { + *dst++ = *src++; + } + *dst = '\0'; + if (*src == ':') { + port_remote = (uint16_t)strtoul(src + 1, NULL, 10); + } + + //printf(" Connecting to QSPY on Host=%s:%d...\n", + // hostName, port_remote); + + l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ + if (l_sock == INVALID_SOCKET){ + printf(" ERROR cannot create client socket,errno=%d\n", + errno); + goto error; + } + + /* configure the socket */ + sockopt_bool = 1; + setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, + &sockopt_bool, sizeof(sockopt_bool)); + + sockopt_bool = 0; + setsockopt(l_sock, SOL_SOCKET, SO_LINGER, + &sockopt_bool, sizeof(sockopt_bool)); + + /* local address:port */ + memset(&sa_local, 0, sizeof(sa_local)); + sa_local.sin_family = AF_INET; + sa_local.sin_port = htons(port_local); + host = gethostbyname(""); /* local host */ + + /* remote hostName:port (QSPY server socket) */ + host = gethostbyname(hostName); + if (host == NULL) { + printf(" ERROR cannot resolve host Name=%s,errno=%d\n", + hostName, errno); + goto error; + } + + memset(&sa_remote, 0, sizeof(sa_remote)); + sa_remote.sin_family = AF_INET; + memcpy(&sa_remote.sin_addr, host->h_addr, host->h_length); + sa_remote.sin_port = htons(port_remote); + + /* try to connect to the QSPY server */ + if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) + == -1) + { + printf(" ERROR cannot connect to QSPY at " + "Host=%s:%d,errno=%d\n", + hostName, port_remote, errno); + goto error; + } + + /* Set the socket to non-blocking mode */ + flags = fcntl(l_sock, F_GETFL, 0); + if (flags == -1) { + printf(" ERROR Socket configuration failed errno=%d\n", + errno); + QS_EXIT(); + goto error; + } + if (fcntl(l_sock, F_SETFL, flags | O_NONBLOCK) != 0) { + printf(" ERROR Socket configuration failed errno=%d\n", + errno); + QS_EXIT(); + goto error; + } + + //printf(" Connected to QSPY at Host=%s:%d\n", + // hostName, port_remote); + QS_onFlush(); + + return (uint8_t)1; /* success */ + +error: + return (uint8_t)0; /* failure */ +} +/*..........................................................................*/ +void QS_onCleanup(void) { + if (l_sock != INVALID_SOCKET) { + close(l_sock); + l_sock = INVALID_SOCKET; + } + //printf(" Disconnected from QSPY\n"); +} +/*..........................................................................*/ +void QS_onReset(void) { + QS_onCleanup(); + exit(0); +} +/*..........................................................................*/ +void QS_onFlush(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + nBytes = QS_TX_SIZE; + } + } +} +/*..........................................................................*/ +QSTimeCtr QS_onGetTime(void) { + /* NOTE: + * clock() is the most portable facility, but might not provide the desired + * granularity. Other, less-portable alternatives are clock_gettime(), + * rdtsc(), or gettimeofday(). + */ + return (QSTimeCtr)clock(); +} + +/*..........................................................................*/ +void QS_output(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + } + } +} +/*..........................................................................*/ +void QS_rx_input(void) { + uint8_t buf[QS_RX_SIZE]; + int status = recv(l_sock, (char *)buf, (int)sizeof(buf), 0); + if (status != -1) { /* any data received? */ + uint8_t *pb; + int i = (int)QS_rxGetNfree(); + if (i > status) { + i = status; + } + status -= i; + /* reorder the received bytes into QS-RX buffer */ + for (pb = &buf[0]; i > 0; --i, ++pb) { + QS_RX_PUT(*pb); + } + QS_rxParse(); /* parse all n-bytes of data */ + } +} + diff --git a/ports/posix-qv/qs_port.h b/ports/posix-qv/qs_port.h index 99ac67bb..f43a5a80 100644 --- a/ports/posix-qv/qs_port.h +++ b/ports/posix-qv/qs_port.h @@ -4,14 +4,14 @@ * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 6.2.0 -* Last updated on 2018-04-05 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 @@ -50,6 +50,9 @@ #define QS_FUN_PTR_SIZE 4 #endif +void QS_output(void); /* handle the QS output */ +void QS_rx_input(void); /* handle the QS-RX input */ + /***************************************************************************** * NOTE: QS might be used with or without other QP components, in which * case the separate definitions of the macros QF_CRIT_STAT_TYPE, @@ -57,8 +60,8 @@ * to be used with the other QP component, by simply including "qf_port.h" * *before* "qs.h". */ -#include "qf_port.h" /* use QS with QF */ -#include "qs.h" /* QS platform-independent public interface */ +#include "qf_port.h" /* use QS with QF */ +#include "qs.h" /* QS platform-independent public interface */ #endif /* qs_port_h */ diff --git a/ports/posix/README.url b/ports/posix/README.url deleted file mode 100644 index 60a0455b..00000000 --- a/ports/posix/README.url +++ /dev/null @@ -1,3 +0,0 @@ -[InternetShortcut] -URL=https://state-machine.com/qpc/posix.html -IconFile=https://state-machine.com/qp.ico diff --git a/ports/posix/qf_port.c b/ports/posix/qf_port.c index 391e840b..b3791d3a 100644 --- a/ports/posix/qf_port.c +++ b/ports/posix/qf_port.c @@ -1,15 +1,15 @@ /** * @file -* @brief QF/C port to POSIX/P-threads, GNU-C compiler +* @brief QF/C port to POSIX API (multi-threaded) * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 6.3.2 -* Last updated on 2018-06-16 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -49,6 +49,14 @@ #include /* for PTHREAD_STACK_MIN */ #include /* for mlockall() */ +#include +#include +#include /* for memcpy() and memset() */ +#include +#include +#include +#include +#include Q_DEFINE_THIS_MODULE("qf_port") @@ -57,15 +65,19 @@ pthread_mutex_t QF_pThreadMutex_; /* Local objects ===========================================================*/ static pthread_mutex_t l_startupMutex; -static bool l_isRunning; +static bool l_isRunning; /* flag indicating when QF is running */ +static struct termios l_tsav; /* structure with saved terminal attributes */ static struct timespec l_tick; static int_t l_tickPrio; enum { NANOSLEEP_NSEC_PER_SEC = 1000000000 }; /* see NOTE05 */ +static void sigIntHandler(int dummy); + /* QF functions ============================================================*/ void QF_init(void) { extern uint_fast8_t QF_maxPool_; extern QTimeEvt QF_timeEvtHead_[QF_MAX_TICK_RATE]; + struct sigaction sig_act; /* lock memory so we're never swapped out to disk */ /*mlockall(MCL_CURRENT | MCL_FUTURE); uncomment when supported */ @@ -92,9 +104,13 @@ void QF_init(void) { l_tick.tv_sec = 0; l_tick.tv_nsec = NANOSLEEP_NSEC_PER_SEC/100L; /* default clock tick */ l_tickPrio = sched_get_priority_min(SCHED_FIFO); /* default tick prio */ -} -/****************************************************************************/ + /* install the SIGINT (Ctrl-C) signal handler */ + sig_act.sa_handler = &sigIntHandler; + sigaction(SIGINT, &sig_act, NULL); +} + +/****************************************************************************/ int_t QF_run(void) { struct sched_param sparam; @@ -136,7 +152,37 @@ void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { void QF_stop(void) { l_isRunning = false; /* stop the loop in QF_run() */ } + /*..........................................................................*/ +void QF_consoleSetup(void) { + struct termios tio; /* modified terminal attributes */ + + tcgetattr(0, &l_tsav); /* save the current terminal attributes */ + tcgetattr(0, &tio); /* obtain the current terminal attributes */ + tio.c_lflag &= ~(ICANON | ECHO); /* disable the canonical mode & echo */ + tcsetattr(0, TCSANOW, &tio); /* set the new attributes */ +} +/*..........................................................................*/ +void QF_consoleCleanup(void) { + tcsetattr(0, TCSANOW, &l_tsav); /* restore the saved attributes */ +} +/*..........................................................................*/ +int QF_consoleGetKey(void) { + int byteswaiting; + ioctl(0, FIONREAD, &byteswaiting); + if (byteswaiting > 0) { + char ch; + read(0, &ch, 1); + return (int)ch; + } + return 0; /* no input at this time */ +} +/*..........................................................................*/ +int QF_consoleWaitForKey(void) { + return getchar(); +} + +/****************************************************************************/ static void *thread_routine(void *arg) { /* the expected POSIX signature */ QActive *act = (QActive *)arg; @@ -154,7 +200,8 @@ static void *thread_routine(void *arg) { /* the expected POSIX signature */ pthread_cond_destroy(&act->osObject); /* cleanup the condition variable */ return (void *)0; /* return success */ } -/*..........................................................................*/ + +/****************************************************************************/ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, @@ -168,7 +215,7 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, Q_REQUIRE_ID(600, stkSto == (void *)0); QEQueue_init(&me->eQueue, qSto, qLen); - pthread_cond_init(&me->osObject, 0); + pthread_cond_init(&me->osObject, NULL); me->prio = (uint8_t)prio; QF_add_(me); /* make QF aware of this active object */ @@ -189,6 +236,7 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + /* stack size not provided? */ if (stkSize == 0U) { /* set the allowed minimum */ stkSize = (uint_fast16_t)PTHREAD_STACK_MIN; @@ -203,16 +251,25 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, pthread_attr_setschedpolicy(&attr, SCHED_OTHER); param.sched_priority = 0; pthread_attr_setschedparam(&attr, ¶m); - Q_ALLEGE(pthread_create(&thread, &attr, &thread_routine, me)== 0); + Q_ALLEGE_ID(601, + pthread_create(&thread, &attr, &thread_routine, me) == 0); } pthread_attr_destroy(&attr); me->thread = (uint8_t)1; } /*..........................................................................*/ void QActive_stop(QActive * const me) { + QActive_unsubscribeAll(me); me->thread = (uint8_t)0; /* stop the QActive thread loop */ } +/****************************************************************************/ +static void sigIntHandler(int dummy) { + (void)dummy; /* unused parameter */ + QF_onCleanup(); + exit(-1); +} + /***************************************************************************** * NOTE01: * In Linux, the scheduler policy closest to real-time is the SCHED_FIFO diff --git a/ports/posix/qf_port.h b/ports/posix/qf_port.h index e8ea5b1c..3bc8264c 100644 --- a/ports/posix/qf_port.h +++ b/ports/posix/qf_port.h @@ -1,16 +1,16 @@ /** * @file -* @brief QF/C port to POSIX threads (pthreads) +* @brief QF/C port to POSIX API (multi-threaded) * @cond ****************************************************************************** -* Last Updated for Version: 6.3.2 -* Date of the Last Update: 2018-06-16 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * -* 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 @@ -72,9 +72,18 @@ #include "qmpool.h" /* POSIX needs memory-pool */ #include "qf.h" /* QF platform-independent public interface */ +/* set clock tick rate and p-thread priority */ void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); + +/* clock tick callback (NOTE not called when "ticker thread" is not running) */ void QF_onClockTick(void); /* clock tick callback (provided in the app) */ +/* abstractions for console access... */ +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + extern pthread_mutex_t QF_pThreadMutex_; /* mutex for QF critical section */ /****************************************************************************/ diff --git a/ports/posix/qs_port.c b/ports/posix/qs_port.c new file mode 100644 index 00000000..5df821cd --- /dev/null +++ b/ports/posix/qs_port.c @@ -0,0 +1,240 @@ +/** +* @file +* @brief QS/C port to POSIX +* @ingroup ports +* @cond +****************************************************************************** +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 +* +* 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 +****************************************************************************** +* @endcond +*/ +#ifndef Q_SPY + #error "Q_SPY must be defined to compile qs_port.c" +#endif /* Q_SPY */ + +#define QP_IMPL /* this is QP implementation */ +#include "qf_port.h" /* QF port */ +#include "qassert.h" /* QP embedded systems-friendly assertions */ +#include "qs_port.h" /* include QS port */ + +Q_DEFINE_THIS_MODULE("qs_port") + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for printf() */ + +#define QS_TX_SIZE (4*1024) +#define QS_RX_SIZE 1024 +#define QS_IMEOUT_MS 100 +#define INVALID_SOCKET -1 + +/* local variables .........................................................*/ +static int l_sock = INVALID_SOCKET; + +/*..........................................................................*/ +uint8_t QS_onStartup(void const *arg) { + static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ + static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + char hostName[64]; + char const *src; + char *dst; + + uint16_t port_local = 51234; /* default local port */ + uint16_t port_remote = 6601; /* default QSPY server port */ + int sockopt_bool; + struct sockaddr_in sa_local; + struct sockaddr_in sa_remote; + struct hostent *host; + int flags; + + QS_initBuf(qsBuf, sizeof(qsBuf)); + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + src = (arg != (void const *)0) + ? (char const *)arg + : "localhost"; + dst = hostName; + while ((*src != '\0') + && (*src != ':') + && (dst < &hostName[sizeof(hostName)])) + { + *dst++ = *src++; + } + *dst = '\0'; + if (*src == ':') { + port_remote = (uint16_t)strtoul(src + 1, NULL, 10); + } + + //printf(" Connecting to QSPY on Host=%s:%d...\n", + // hostName, port_remote); + + l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ + if (l_sock == INVALID_SOCKET){ + printf(" ERROR cannot create client socket,errno=%d\n", + errno); + goto error; + } + + /* configure the socket */ + sockopt_bool = 1; + setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, + &sockopt_bool, sizeof(sockopt_bool)); + + sockopt_bool = 0; + setsockopt(l_sock, SOL_SOCKET, SO_LINGER, + &sockopt_bool, sizeof(sockopt_bool)); + + /* local address:port */ + memset(&sa_local, 0, sizeof(sa_local)); + sa_local.sin_family = AF_INET; + sa_local.sin_port = htons(port_local); + host = gethostbyname(""); /* local host */ + + /* remote hostName:port (QSPY server socket) */ + host = gethostbyname(hostName); + if (host == NULL) { + printf(" ERROR cannot resolve host Name=%s,errno=%d\n", + hostName, errno); + goto error; + } + + memset(&sa_remote, 0, sizeof(sa_remote)); + sa_remote.sin_family = AF_INET; + memcpy(&sa_remote.sin_addr, host->h_addr, host->h_length); + sa_remote.sin_port = htons(port_remote); + + /* try to connect to the QSPY server */ + if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) + == -1) + { + printf(" ERROR cannot connect to QSPY at " + "Host=%s:%d,errno=%d\n", + hostName, port_remote, errno); + goto error; + } + + /* Set the socket to non-blocking mode */ + flags = fcntl(l_sock, F_GETFL, 0); + if (flags == -1) { + printf(" ERROR Socket configuration failed errno=%d\n", + errno); + QS_EXIT(); + goto error; + } + if (fcntl(l_sock, F_SETFL, flags | O_NONBLOCK) != 0) { + printf(" ERROR Socket configuration failed errno=%d\n", + errno); + QS_EXIT(); + goto error; + } + + //printf(" Connected to QSPY at Host=%s:%d\n", + // hostName, port_remote); + QS_onFlush(); + + return (uint8_t)1; /* success */ + +error: + return (uint8_t)0; /* failure */ +} +/*..........................................................................*/ +void QS_onCleanup(void) { + if (l_sock != INVALID_SOCKET) { + close(l_sock); + l_sock = INVALID_SOCKET; + } + //printf(" Disconnected from QSPY\n"); +} +/*..........................................................................*/ +void QS_onReset(void) { + QS_onCleanup(); + exit(0); +} +/*..........................................................................*/ +void QS_onFlush(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + nBytes = QS_TX_SIZE; + } + } +} +/*..........................................................................*/ +QSTimeCtr QS_onGetTime(void) { + /* NOTE: + * clock() is the most portable facility, but might not provide the desired + * granularity. Other, less-portable alternatives are clock_gettime(), + * rdtsc(), or gettimeofday(). + */ + return (QSTimeCtr)clock(); +} + +/*..........................................................................*/ +void QS_output(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + } + } +} +/*..........................................................................*/ +void QS_rx_input(void) { + uint8_t buf[QS_RX_SIZE]; + int status = recv(l_sock, (char *)buf, (int)sizeof(buf), 0); + if (status != -1) { /* any data received? */ + uint8_t *pb; + int i = (int)QS_rxGetNfree(); + if (i > status) { + i = status; + } + status -= i; + /* reorder the received bytes into QS-RX buffer */ + for (pb = &buf[0]; i > 0; --i, ++pb) { + QS_RX_PUT(*pb); + } + QS_rxParse(); /* parse all n-bytes of data */ + } +} + diff --git a/ports/posix/qs_port.h b/ports/posix/qs_port.h index b7ebc072..f43a5a80 100644 --- a/ports/posix/qs_port.h +++ b/ports/posix/qs_port.h @@ -4,14 +4,14 @@ * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 @@ -32,7 +32,7 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com ****************************************************************************** * @endcond @@ -40,16 +40,19 @@ #ifndef qs_port_h #define qs_port_h -#define QS_TIME_SIZE 4 +#define QS_TIME_SIZE 4 #if defined(__LP64__) || defined(_LP64) /* 64-bit architecture? */ - #define QS_OBJ_PTR_SIZE 8 - #define QS_FUN_PTR_SIZE 8 + #define QS_OBJ_PTR_SIZE 8 + #define QS_FUN_PTR_SIZE 8 #else /* 32-bit architecture */ - #define QS_OBJ_PTR_SIZE 4 - #define QS_FUN_PTR_SIZE 4 + #define QS_OBJ_PTR_SIZE 4 + #define QS_FUN_PTR_SIZE 4 #endif +void QS_output(void); /* handle the QS output */ +void QS_rx_input(void); /* handle the QS-RX input */ + /***************************************************************************** * NOTE: QS might be used with or without other QP components, in which * case the separate definitions of the macros QF_CRIT_STAT_TYPE, @@ -57,7 +60,8 @@ * to be used with the other QP component, by simply including "qf_port.h" * *before* "qs.h". */ -#include "qf_port.h" /* use QS with QF */ -#include "qs.h" /* QS platform-independent public interface */ +#include "qf_port.h" /* use QS with QF */ +#include "qs.h" /* QS platform-independent public interface */ #endif /* qs_port_h */ + diff --git a/ports/win32-qutest/Makefile b/ports/win32-qutest/Makefile index 9dc4aa67..66090ca6 100644 --- a/ports/win32-qutest/Makefile +++ b/ports/win32-qutest/Makefile @@ -1,11 +1,11 @@ ############################################################################## # Product: Makefile for QUTEST, QP/C, Win32, MinGW toolset -# Last Updated for Version: 6.2.0 -# Date of the Last Update: 2018-03-12 +# Last Updated for Version: 6.3.6 +# Date of the Last Update: 2018-10-20 # -# 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. # @@ -88,6 +88,7 @@ C_SRCS := \ qf_qact.c \ qf_qeq.c \ qf_qmact.c \ + qf_time.c \ qs.c \ qs_64bit.c \ qs_rx.c \ diff --git a/ports/win32-qutest/qf_port.h b/ports/win32-qutest/qf_port.h index 8de05c7f..ec6a91f8 100644 --- a/ports/win32-qutest/qf_port.h +++ b/ports/win32-qutest/qf_port.h @@ -4,8 +4,8 @@ * @ingroup qutest * @cond ****************************************************************************** -* Last Updated for Version: 6.3.4 -* Date of the Last Update: 2018-09-04 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-04 * * Q u a n t u m L e a P s * ------------------------ @@ -123,6 +123,12 @@ extern uint8_t volatile QF_intNest; #define QF_SCHED_LOCK_(dummy) ((void)0) #define QF_SCHED_UNLOCK_() ((void)0) + /* native event queue operations */ + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_rxPriv_.readySet, (uint_fast8_t)(me_)->prio) + /* native QF event pool operations */ #define QF_EPOOL_TYPE_ QMPool #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ @@ -132,12 +138,8 @@ extern uint8_t volatile QF_intNest; #define QF_EPOOL_GET_(p_, e_, m_) ((e_) = (QEvt *)QMPool_get(&(p_), (m_))) #define QF_EPOOL_PUT_(p_, e_) (QMPool_put(&(p_), e_)) + #include "qf_pkg.h" /* internal QF interface */ + #endif /* QP_IMPL */ -/***************************************************************************** -* NOTE1: -* This QF "port" provides dummy declaration for the QF stub that provides -* empty definitions of the QF facilities. -*/ - #endif /* qf_port_h */ diff --git a/ports/win32-qutest/qp.vcxproj b/ports/win32-qutest/qp.vcxproj index 745d7579..e22935f0 100644 --- a/ports/win32-qutest/qp.vcxproj +++ b/ports/win32-qutest/qp.vcxproj @@ -80,6 +80,7 @@ + diff --git a/ports/win32-qutest/qp.vcxproj.filters b/ports/win32-qutest/qp.vcxproj.filters index 02bff094..10239a3b 100644 --- a/ports/win32-qutest/qp.vcxproj.filters +++ b/ports/win32-qutest/qp.vcxproj.filters @@ -60,6 +60,9 @@ QP_spy + + QP + diff --git a/ports/win32-qutest/qutest_port.c b/ports/win32-qutest/qutest_port.c index 068a5229..a07666b5 100644 --- a/ports/win32-qutest/qutest_port.c +++ b/ports/win32-qutest/qutest_port.c @@ -4,14 +4,14 @@ * @ingroup qf * @cond ****************************************************************************** -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-16 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-03 * -* 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 @@ -46,9 +46,9 @@ #include "qassert.h" /* QP embedded systems-friendly assertions */ #include "qs_port.h" /* include QS port */ -Q_DEFINE_THIS_MODULE("qutest_port") +//Q_DEFINE_THIS_MODULE("qutest_port") -#include /* for printf() and _snprintf_s() */ +#include #include #include #include @@ -83,7 +83,8 @@ uint8_t QS_onStartup(void const *arg) { /* initialize Windows sockets */ if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { - printf(" ERROR Windows Sockets cannot be initialized\n"); + fprintf(stderr, + " ERROR Windows Sockets cannot be initialized\n"); goto error; } @@ -104,8 +105,9 @@ uint8_t QS_onStartup(void const *arg) { l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ if (l_sock == INVALID_SOCKET){ - printf(" ERROR cannot create client socket,WSAErr=%d\n", - WSAGetLastError()); + fprintf(stderr, + " ERROR cannot create client socket,WSAErr=%d\n", + WSAGetLastError()); goto error; } @@ -131,16 +133,18 @@ uint8_t QS_onStartup(void const *arg) { sa_local.sin_addr.s_addr = inet_addr( inet_ntoa(*(struct in_addr *)*host->h_addr_list)); //if (bind(l_sock, &sa_local, sizeof(sa_local)) == -1) { - // printf(" WARNINIG Cannot bind to the local port, WSAErr=%d\n", - // WSAGetLastError()); + // fprintf(stderr, + // " WARNINIG Cannot bind to the local port, WSAErr=%d\n", + // WSAGetLastError()); // /* no error */ //} /* remote hostName:port (QSPY server socket) */ host = gethostbyname(hostName); if (host == NULL) { - printf(" ERROR cannot resolve host Name=%s,WSAErr=%d\n", - hostName, WSAGetLastError()); + fprintf(stderr, + " ERROR cannot resolve host Name=%s,WSAErr=%d\n", + hostName, WSAGetLastError()); goto error; } @@ -153,16 +157,18 @@ uint8_t QS_onStartup(void const *arg) { if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) == SOCKET_ERROR) { - printf(" ERROR socket configuration failed,WSAErr=%d\n", - WSAGetLastError()); + fprintf(stderr, + " ERROR socket configuration failed,WSAErr=%d\n", + WSAGetLastError()); QS_EXIT(); goto error; } /* Set the socket to non-blocking mode. */ if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { - printf(" ERROR Socket configuration failed WASErr=%d\n", - WSAGetLastError()); + fprintf(stderr, + " ERROR Socket configuration failed WASErr=%d\n", + WSAGetLastError()); QS_EXIT(); goto error; } @@ -210,7 +216,9 @@ void QS_onTestLoop() { /* selective, timed blocking on the TCP/IP socket... */ status = select(0, &readSet, (fd_set *)0, (fd_set *)0, &timeout); if (status == SOCKET_ERROR) { - printf(" ERROR socket select,WSAErr=%d", WSAGetLastError()); + fprintf(stderr, + " ERROR socket select,WSAErr=%d", + WSAGetLastError()); QS_onCleanup(); exit(-2); } diff --git a/ports/win32-qv/Makefile b/ports/win32-qv/Makefile index bab51697..ef325a97 100644 --- a/ports/win32-qv/Makefile +++ b/ports/win32-qv/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C port to Win32 API, MinGW toolset -# Last Updated for Version: 5.9.1 -# Date of the Last Update: 2017-05-25 +# Product: Makefile for QP/C port to Win32-QV, MinGW toolset +# Last updated for version 6.3.6 +# Last updated on 2018-10-13 # -# 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) 2005-2017 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2002-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 ############################################################################## # examples of invoking this Makefile: @@ -101,7 +101,8 @@ C_QS_SRCS := \ qs.c \ qs_rx.c \ qs_fp.c \ - qs_64bit.c + qs_64bit.c \ + qs_port.c # C++ source files CPP_SRCS := diff --git a/ports/win32-qv/qf_port.c b/ports/win32-qv/qf_port.c index f8e1b273..841b8d81 100644 --- a/ports/win32-qv/qf_port.c +++ b/ports/win32-qv/qf_port.c @@ -1,15 +1,15 @@ /** * @file -* @brief QF/C port to Win32 with cooperative QV kernel (win32-qv) +* @brief QF/C port to Win32 API (single-threaded, like the QV kernel) * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 6.2.0 -* Last updated on 2018-04-05 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -48,6 +48,7 @@ #endif /* Q_SPY */ #include /* limits of dynamic range for integers */ +#include /* console input/output */ Q_DEFINE_THIS_MODULE("qf_port") @@ -58,6 +59,7 @@ HANDLE QV_win32Event_; /* Win32 event to signal events */ /* Local objects ===========================================================*/ static CRITICAL_SECTION l_win32CritSect; static DWORD l_tickMsec = 10U; /* clock tick in msec (argument for Sleep()) */ +static int_t l_tickPrio = 50; /* default priority of the "ticker" thread */ static bool l_isRunning; /* flag indicating when QF is running */ static DWORD WINAPI ticker_thread(LPVOID arg); @@ -93,27 +95,25 @@ void QF_stop(void) { } /****************************************************************************/ int_t QF_run(void) { - HANDLE ticker; - QF_onStartup(); /* application-specific startup callback */ l_isRunning = true; /* QF is running */ if (l_tickMsec != (uint32_t)0) { /* system clock tick configured? */ /* create the ticker thread... */ - ticker = CreateThread(NULL, 1024, &ticker_thread, (void *)0, 0, NULL); + HANDLE ticker = CreateThread(NULL, 1024, &ticker_thread, + (void *)0, 0, NULL); Q_ASSERT_ID(310, ticker != (HANDLE)0); /* thread must be created */ } /* the combined event-loop and background-loop of the QV kernel */ QF_INT_DISABLE(); while (l_isRunning) { - QEvt const *e; - QActive *a; - uint_fast8_t p; - /* find the maximum priority AO ready to run */ if (QPSet_notEmpty(&QV_readySet_)) { + uint_fast8_t p; + QActive *a; + QEvt const *e; QPSet_findMax(&QV_readySet_, p); a = QF_active_[p]; @@ -163,13 +163,32 @@ int_t QF_run(void) { return (int_t)0; /* return success */ } /****************************************************************************/ -void QF_setTickRate(uint32_t ticksPerSec) { +void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { if (ticksPerSec != (uint32_t)0) { l_tickMsec = 1000UL / ticksPerSec; } else { l_tickMsec = (uint32_t)0; /* means NO system clock tick */ } + l_tickPrio = tickPrio; +} + +/*..........................................................................*/ +void QF_consoleSetup(void) { +} +/*..........................................................................*/ +void QF_consoleCleanup(void) { +} +/*..........................................................................*/ +int QF_consoleGetKey(void) { + if (_kbhit()) { /* any key pressed? */ + return _getch(); + } + return 0; +} +/*..........................................................................*/ +int QF_consoleWaitForKey(void) { + return _getch(); } /* QActive functions =======================================================*/ @@ -179,38 +198,47 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *ie) { Q_REQUIRE_ID(600, ((uint_fast8_t)0 < prio) /* priority must be in range */ - && (prio <= (uint_fast8_t)QF_MAX_ACTIVE) - && (stkSto == (void *)0)); /* statck storage must NOT... - * ... be provided */ + && (prio <= (uint_fast8_t)QF_MAX_ACTIVE) + && (stkSto == (void *)0)); /* statck storage must NOT... + * ... be provided */ QEQueue_init(&me->eQueue, qSto, qLen); me->prio = prio; /* set QF priority of this AO before adding it to QF */ - QF_add_(me); /* make QF aware of this active object */ + QF_add_(me); /* make QF aware of this AO */ QHSM_INIT(&me->super, ie); /* take the top-most initial tran. */ - QS_FLUSH(); /* flush the QS trace buffer to the host */ + QS_FLUSH(); /* flush the QS trace buffer to the host */ - (void)stkSize; /* avoid the "unused parameter" compiler warning */ + (void)stkSize; /* unused parameter */ } /****************************************************************************/ void QActive_stop(QActive * const me) { QActive_unsubscribeAll(me); QF_remove_(me); - free((void *)me->eQueue.ring); /* free the fudged queue storage */ } + /****************************************************************************/ static DWORD WINAPI ticker_thread(LPVOID arg) { /* for CreateThread() */ - (void)arg; /* avoid compiler warning about unused parameter */ + int threadPrio = THREAD_PRIORITY_NORMAL; - /* set the ticker thread priority below normal to prevent - * flooding other threads with time events when the machine - * is very busy. - */ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + // set the ticker thread priority according to selection made in + // QF_setTickRate() + // + if (l_tickPrio < 33) { + threadPrio = THREAD_PRIORITY_BELOW_NORMAL; + } + else if (l_tickPrio > 66) { + threadPrio = THREAD_PRIORITY_ABOVE_NORMAL; + } + + SetThreadPriority(GetCurrentThread(), threadPrio); while (l_isRunning) { Sleep(l_tickMsec); /* wait for the tick interval */ QF_onClockTick(); /* clock tick callback (must call QF_TICK_X()) */ } + + (void)arg; /* unused parameter */ + return (DWORD)0; /* return success */ } diff --git a/ports/win32-qv/qf_port.h b/ports/win32-qv/qf_port.h index 19acb973..f969c9a5 100644 --- a/ports/win32-qv/qf_port.h +++ b/ports/win32-qv/qf_port.h @@ -1,11 +1,11 @@ /** * @file -* @brief QF/C port to Win32 with cooperative QV kernel (win32-qv) +* @brief QF/C port to Win32 API (single-threaded, like the QV kernel) * @ingroup ports * @cond ****************************************************************************** -* Last Updated for Version: 6.3.4 -* Date of the Last Update: 2018-09-04 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * * Q u a n t u m L e a P s * ------------------------ @@ -77,26 +77,31 @@ void QF_enterCriticalSection_(void); void QF_leaveCriticalSection_(void); -/* set clock tick rate (NOTE ticksPerSec==0 disables the "ticker thread" */ -void QF_setTickRate(uint32_t ticksPerSec); /* set clock tick rate */ +/* set clock tick rate (NOTE ticksPerSec==0 disables the "ticker thread") */ +void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); /* clock tick callback (NOTE not called when "ticker thread" is not running) */ void QF_onClockTick(void); /* clock tick callback (provided in the app) */ -/* special adaptations for QWIN GUI applications */ +/* special adaptations for QWIN GUI applications... */ #ifdef QWIN_GUI /* replace main() with main_gui() as the entry point to a GUI app. */ #define main() main_gui() int_t main_gui(); /* prototype of the GUI application entry point */ #endif -/* portable "safe" facilities from and */ -#ifdef _MSC_VER /* Microsoft Visual C++ */ +/* abstractions for console access... */ +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +/****************************************************************************/ +/* Microsoft C++: portable "safe" facilities from and */ +#ifdef _MSC_VER #if (_MSC_VER < 1900) /* before Visual Studio 2015 */ - #define snprintf _snprintf - #endif #define SNPRINTF_S(buf_, len_, format_, ...) \ @@ -132,7 +137,7 @@ void QF_onClockTick(void); /* clock tick callback (provided in the app) */ #define SSCANF_S(buf_, format_, ...) \ sscanf(buf_, format_, ##__VA_ARGS__) -#endif +#endif /* _MSC_VER */ /****************************************************************************/ /* interface used only inside QF implementation, but not in applications */ @@ -148,7 +153,7 @@ void QF_onClockTick(void); /* clock tick callback (provided in the app) */ Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QV_readySet_, (me_)->prio); \ - (void)SetEvent(QV_win32Event_) + (void)SetEvent(QV_win32Event_) /* native QF event pool operations */ #define QF_EPOOL_TYPE_ QMPool @@ -161,7 +166,6 @@ void QF_onClockTick(void); /* clock tick callback (provided in the app) */ #define WIN32_LEAN_AND_MEAN #include /* Win32 API */ - #include /* for malloc() */ extern QPSet QV_readySet_; /* QV-ready set of active objects */ extern HANDLE QV_win32Event_; /* Win32 event to signal events */ diff --git a/ports/win32-qv/qp.vcxproj b/ports/win32-qv/qp.vcxproj index 5bd1881c..2851a698 100644 --- a/ports/win32-qv/qp.vcxproj +++ b/ports/win32-qv/qp.vcxproj @@ -178,10 +178,14 @@ true - false + true true + + true + true + diff --git a/ports/win32-qv/qp.vcxproj.filters b/ports/win32-qv/qp.vcxproj.filters index b21938c2..3dfce37d 100644 --- a/ports/win32-qv/qp.vcxproj.filters +++ b/ports/win32-qv/qp.vcxproj.filters @@ -72,6 +72,9 @@ QS + + QP_port + diff --git a/ports/win32-qv/qs_port.c b/ports/win32-qv/qs_port.c new file mode 100644 index 00000000..0909a1fd --- /dev/null +++ b/ports/win32-qv/qs_port.c @@ -0,0 +1,243 @@ +/** +* @file +* @brief QS/C port to Win32 API +* @ingroup ports +* @cond +****************************************************************************** +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 +* +* 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 +****************************************************************************** +* @endcond +*/ +#ifndef Q_SPY + #error "Q_SPY must be defined to compile qs_port.c" +#endif /* Q_SPY */ + +#define QP_IMPL /* this is QP implementation */ +#include "qf_port.h" /* QF port */ +#include "qassert.h" /* QP embedded systems-friendly assertions */ +#include "qs_port.h" /* include QS port */ + +//Q_DEFINE_THIS_MODULE("qs_port") + +#include +#include +#include +#include +#include /* for Windows network facilities */ + +#define QS_TX_SIZE (4*1024) +#define QS_RX_SIZE 1024 +#define QS_IMEOUT_MS 100 + +/* local variables .........................................................*/ +static SOCKET l_sock = INVALID_SOCKET; + +/*..........................................................................*/ +uint8_t QS_onStartup(void const *arg) { + static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ + static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + static WSADATA wsaData; + char hostName[128]; + char const *src; + char *dst; + + USHORT port_local = 51234; /* default local port */ + USHORT port_remote = 6601; /* default QSPY server port */ + BOOL sockopt_bool; + ULONG ioctl_opt = 1; + struct sockaddr_in sa_local; + struct sockaddr_in sa_remote; + struct hostent *host; + + QS_initBuf(qsBuf, sizeof(qsBuf)); + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + /* initialize Windows sockets */ + if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { + fprintf(stderr, + " ERROR Windows Sockets cannot be initialized\n"); + goto error; + } + + src = (arg != (void const *)0) + ? (char const *)arg + : "localhost"; + dst = hostName; + while ((*src != '\0') + && (*src != ':') + && (dst < &hostName[sizeof(hostName)])) + { + *dst++ = *src++; + } + *dst = '\0'; + if (*src == ':') { + port_remote = (USHORT)strtoul(src + 1, NULL, 10); + } + + l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ + if (l_sock == INVALID_SOCKET){ + fprintf(stderr, + " ERROR cannot create client socket,WSAErr=%d\n", + WSAGetLastError()); + goto error; + } + + /* configure the socket */ + sockopt_bool = TRUE; + setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, + (const char *)&sockopt_bool, sizeof(sockopt_bool)); + + sockopt_bool = TRUE; + setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, + (const char *)&sockopt_bool, sizeof(sockopt_bool)); + + /* disable the Nagle algorithm (good for small messages) */ + //sockopt_bool = TRUE; + //setsockopt(l_sock, IPPROTO_TCP, TCP_NODELAY, + // (const char *)&sockopt_bool, sizeof(sockopt_bool)); + + /* local address:port */ + memset(&sa_local, 0, sizeof(sa_local)); + sa_local.sin_family = AF_INET; + sa_local.sin_port = htons(port_local); + host = gethostbyname(""); /* local host */ + sa_local.sin_addr.s_addr = inet_addr( + inet_ntoa(*(struct in_addr *)*host->h_addr_list)); + //if (bind(l_sock, &sa_local, sizeof(sa_local)) == -1) { + // fprintf(stderr, + // " WARNINIG Cannot bind to the local port, WSAErr=%d\n", + // WSAGetLastError()); + // /* no error */ + //} + + /* remote hostName:port (QSPY server socket) */ + host = gethostbyname(hostName); + if (host == NULL) { + fprintf(stderr, + " ERROR cannot resolve host Name=%s,WSAErr=%d\n", + hostName, WSAGetLastError()); + goto error; + } + + memset(&sa_remote, 0, sizeof(sa_remote)); + sa_remote.sin_family = AF_INET; + memcpy(&sa_remote.sin_addr, host->h_addr, host->h_length); + sa_remote.sin_port = htons(port_remote); + + /* try to connect to the QSPY server */ + if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) + == SOCKET_ERROR) + { + fprintf(stderr, + " ERROR socket configuration failed,WSAErr=%d\n", + WSAGetLastError()); + QS_EXIT(); + goto error; + } + + /* Set the socket to non-blocking mode. */ + if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { + fprintf(stderr, + " ERROR Socket configuration failed WASErr=%d\n", + WSAGetLastError()); + QS_EXIT(); + goto error; + } + + //printf(" Connected to QSPY at Host=%s:%d\n", + // hostName, port_remote); + QS_onFlush(); + + return (uint8_t)1; /* success */ + +error: + return (uint8_t)0; /* failure */ +} +/*..........................................................................*/ +void QS_onCleanup(void) { + if (l_sock != INVALID_SOCKET) { + closesocket(l_sock); + l_sock = INVALID_SOCKET; + } + WSACleanup(); + //printf(" Disconnected from QSPY\n"); +} +/*..........................................................................*/ +QSTimeCtr QS_onGetTime(void) { + return (QSTimeCtr)clock(); +} +/*..........................................................................*/ +void QS_onReset(void) { + QS_onCleanup(); + exit(0); +} +/*..........................................................................*/ +void QS_onFlush(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + nBytes = QS_TX_SIZE; + } + } +} + +/*..........................................................................*/ +void QS_rx_input(void) { + uint8_t buf[QS_RX_SIZE]; + int status = recv(l_sock, (char *)buf, (int)sizeof(buf), 0); + if (status != SOCKET_ERROR) { /* any data received? */ + uint8_t *pb; + int i = (int)QS_rxGetNfree(); + if (i > status) { + i = status; + } + status -= i; + /* reorder the received bytes into QS-RX buffer */ + for (pb = &buf[0]; i > 0; --i, ++pb) { + QS_RX_PUT(*pb); + } + QS_rxParse(); /* parse all n-bytes of data */ + } +} +/*..........................................................................*/ +void QS_output(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + } + } +} + diff --git a/ports/win32-qv/qs_port.h b/ports/win32-qv/qs_port.h index 263a4c9d..3696a012 100644 --- a/ports/win32-qv/qs_port.h +++ b/ports/win32-qv/qs_port.h @@ -4,14 +4,14 @@ * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 @@ -32,7 +32,7 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com ****************************************************************************** * @endcond @@ -50,6 +50,9 @@ #define QS_FUN_PTR_SIZE 4 #endif +void QS_output(void); /* handle the QS output */ +void QS_rx_input(void); /* handle the QS-RX input */ + /***************************************************************************** * NOTE: QS might be used with or without other QP components, in which * case the separate definitions of the macros QF_CRIT_STAT_TYPE, @@ -61,3 +64,4 @@ #include "qs.h" /* QS platform-independent public interface */ #endif /* qs_port_h */ + diff --git a/ports/win32/Makefile b/ports/win32/Makefile index bab51697..2e6fcdc2 100644 --- a/ports/win32/Makefile +++ b/ports/win32/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C port to Win32 API, MinGW toolset -# Last Updated for Version: 5.9.1 -# Date of the Last Update: 2017-05-25 +# Product: Makefile for QP/C port to Win32, MinGW toolset +# Last updated for version 6.3.6 +# Last updated on 2018-10-13 # -# 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) 2005-2017 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2002-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 ############################################################################## # examples of invoking this Makefile: @@ -101,7 +101,8 @@ C_QS_SRCS := \ qs.c \ qs_rx.c \ qs_fp.c \ - qs_64bit.c + qs_64bit.c \ + qs_port.c # C++ source files CPP_SRCS := diff --git a/ports/win32/qf_port.c b/ports/win32/qf_port.c index f75a05d8..7f20e712 100644 --- a/ports/win32/qf_port.c +++ b/ports/win32/qf_port.c @@ -4,12 +4,12 @@ * @ingroup ports * @cond ****************************************************************************** -* Last Updated for Version: 6.1.1 -* Date of the Last Update: 2018-03-06 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. * @@ -48,14 +48,15 @@ #endif /* Q_SPY */ #include /* limits of dynamic range for integers */ +#include /* console input/output */ Q_DEFINE_THIS_MODULE("qf_port") - /* Local objects ===========================================================*/ static CRITICAL_SECTION l_win32CritSect; static CRITICAL_SECTION l_startupCritSect; static DWORD l_tickMsec = 10U; /* clock tick in msec (argument for Sleep()) */ +static int_t l_tickPrio = 50; /* default priority of the "ticker" thread */ static bool l_isRunning; /* flag indicating when QF is running */ static DWORD WINAPI ao_thread(LPVOID arg); @@ -95,6 +96,8 @@ void QF_stop(void) { } /****************************************************************************/ int_t QF_run(void) { + int threadPrio = THREAD_PRIORITY_NORMAL; + QF_onStartup(); /* application-specific startup callback */ @@ -105,16 +108,22 @@ int_t QF_run(void) { l_isRunning = true; /* QF is running */ - /* set the ticker thread priority below normal to prevent - * flooding other threads with time events when the machine - * is very busy. + /* set the ticker (this thread) priority according to selection made in + * QF_setTickRate() */ - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + if (l_tickPrio < 33) { + threadPrio = THREAD_PRIORITY_BELOW_NORMAL; + } + else if (l_tickPrio > 66) { + threadPrio = THREAD_PRIORITY_ABOVE_NORMAL; + } + SetThreadPriority(GetCurrentThread(), threadPrio); while (l_isRunning) { Sleep(l_tickMsec); /* wait for the tick interval */ QF_onClockTick(); /* clock tick callback (must call QF_TICKX()) */ } + QF_onCleanup(); /* cleanup callback */ QS_EXIT(); /* cleanup the QSPY connection */ //DeleteCriticalSection(&l_startupCritSect); @@ -122,6 +131,12 @@ int_t QF_run(void) { return (int_t)0; /* return success */ } /****************************************************************************/ +void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { + Q_REQUIRE_ID(600, ticksPerSec != (uint32_t)0); + l_tickMsec = 1000UL / ticksPerSec; + l_tickPrio = tickPrio; +} +/****************************************************************************/ void QF_setWin32Prio(QActive *act, int_t win32Prio) { if (act->thread == (HANDLE)0) { /* thread not created yet? */ act->osObject = (void *)win32Prio; /* store the priority for later */ @@ -130,11 +145,6 @@ void QF_setWin32Prio(QActive *act, int_t win32Prio) { SetThreadPriority(act->thread, win32Prio); } } -/****************************************************************************/ -void QF_setTickRate(uint32_t ticksPerSec) { - Q_REQUIRE_ID(600, ticksPerSec != (uint32_t)0); - l_tickMsec = 1000UL / ticksPerSec; -} /* QActive functions =======================================================*/ void QActive_start_(QActive * const me, uint_fast8_t prio, @@ -185,6 +195,25 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, void QActive_stop(QActive * const me) { me->thread = (HANDLE)0; /* stop the AO event loop in thread_function() */ } + +/****************************************************************************/ +void QF_consoleSetup(void) { +} +/*..........................................................................*/ +void QF_consoleCleanup(void) { +} +/*..........................................................................*/ +int QF_consoleGetKey(void) { + if (_kbhit()) { /* any key pressed? */ + return _getch(); + } + return 0; +} +/*..........................................................................*/ +int QF_consoleWaitForKey(void) { + return _getch(); +} + /****************************************************************************/ static DWORD WINAPI ao_thread(LPVOID arg) { /* for CreateThread() */ QActive *act = (QActive *)arg; @@ -207,3 +236,4 @@ static DWORD WINAPI ao_thread(LPVOID arg) { /* for CreateThread() */ free((void *)act->eQueue.ring); /* free the fudged queue storage */ return (DWORD)0; /* return success */ } + diff --git a/ports/win32/qf_port.h b/ports/win32/qf_port.h index 5173067f..28fc6cfc 100644 --- a/ports/win32/qf_port.h +++ b/ports/win32/qf_port.h @@ -1,11 +1,11 @@ /** * @file -* @brief QF/C port to Win32 API +* @brief QF/C port to Win32 API (multi-threaded) * @ingroup ports * @cond ****************************************************************************** -* Last Updated for Version: 6.3.4 -* Date of the Last Update: 2018-09-04 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-15 * * Q u a n t u m L e a P s * ------------------------ @@ -74,6 +74,7 @@ #include "qmpool.h" /* Win32 needs the native memory-pool */ #include "qf.h" /* QF platform-independent public interface */ +/* internal functions for critical section management */ void QF_enterCriticalSection_(void); void QF_leaveCriticalSection_(void); @@ -82,25 +83,31 @@ void QF_leaveCriticalSection_(void); */ void QF_setWin32Prio(QActive *act, int_t win32Prio); -void QF_setTickRate(uint32_t ticksPerSec); /* set clock tick rate */ +/* set clock tick rate */ +void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); /* application-level clock tick callback */ void QF_onClockTick(void); -/* special adaptations for QWIN GUI applications */ +/* special adaptations for QWIN GUI applications... */ #ifdef QWIN_GUI /* replace main() with main_gui() as the entry point to a GUI app. */ #define main() main_gui() int_t main_gui(); /* prototype of the GUI application entry point */ #endif -/* portable "safe" facilities from and */ -#ifdef _MSC_VER /* Microsoft Visual C++ */ +/* abstractions for console access... */ +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +/****************************************************************************/ +/* Microsoft C++: portable "safe" facilities from and */ +#ifdef _MSC_VER #if (_MSC_VER < 1900) /* before Visual Studio 2015 */ - #define snprintf _snprintf - #endif #define SNPRINTF_S(buf_, len_, format_, ...) \ @@ -136,7 +143,7 @@ void QF_onClockTick(void); #define SSCANF_S(buf_, format_, ...) \ sscanf(buf_, format_, ##__VA_ARGS__) -#endif +#endif /* _MSC_VER */ /****************************************************************************/ /* interface used only inside QF implementation, but not in applications */ diff --git a/ports/win32/qp.vcxproj b/ports/win32/qp.vcxproj index be86e469..a0b0327b 100644 --- a/ports/win32/qp.vcxproj +++ b/ports/win32/qp.vcxproj @@ -178,10 +178,14 @@ true - false + true true + + true + true + diff --git a/ports/win32/qp.vcxproj.filters b/ports/win32/qp.vcxproj.filters index 56aef4cc..37fddc03 100644 --- a/ports/win32/qp.vcxproj.filters +++ b/ports/win32/qp.vcxproj.filters @@ -72,6 +72,9 @@ QS + + QP_port + diff --git a/ports/win32/qs_port.c b/ports/win32/qs_port.c new file mode 100644 index 00000000..0909a1fd --- /dev/null +++ b/ports/win32/qs_port.c @@ -0,0 +1,243 @@ +/** +* @file +* @brief QS/C port to Win32 API +* @ingroup ports +* @cond +****************************************************************************** +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 +* +* 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 +****************************************************************************** +* @endcond +*/ +#ifndef Q_SPY + #error "Q_SPY must be defined to compile qs_port.c" +#endif /* Q_SPY */ + +#define QP_IMPL /* this is QP implementation */ +#include "qf_port.h" /* QF port */ +#include "qassert.h" /* QP embedded systems-friendly assertions */ +#include "qs_port.h" /* include QS port */ + +//Q_DEFINE_THIS_MODULE("qs_port") + +#include +#include +#include +#include +#include /* for Windows network facilities */ + +#define QS_TX_SIZE (4*1024) +#define QS_RX_SIZE 1024 +#define QS_IMEOUT_MS 100 + +/* local variables .........................................................*/ +static SOCKET l_sock = INVALID_SOCKET; + +/*..........................................................................*/ +uint8_t QS_onStartup(void const *arg) { + static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ + static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + static WSADATA wsaData; + char hostName[128]; + char const *src; + char *dst; + + USHORT port_local = 51234; /* default local port */ + USHORT port_remote = 6601; /* default QSPY server port */ + BOOL sockopt_bool; + ULONG ioctl_opt = 1; + struct sockaddr_in sa_local; + struct sockaddr_in sa_remote; + struct hostent *host; + + QS_initBuf(qsBuf, sizeof(qsBuf)); + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + /* initialize Windows sockets */ + if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) { + fprintf(stderr, + " ERROR Windows Sockets cannot be initialized\n"); + goto error; + } + + src = (arg != (void const *)0) + ? (char const *)arg + : "localhost"; + dst = hostName; + while ((*src != '\0') + && (*src != ':') + && (dst < &hostName[sizeof(hostName)])) + { + *dst++ = *src++; + } + *dst = '\0'; + if (*src == ':') { + port_remote = (USHORT)strtoul(src + 1, NULL, 10); + } + + l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* TCP socket */ + if (l_sock == INVALID_SOCKET){ + fprintf(stderr, + " ERROR cannot create client socket,WSAErr=%d\n", + WSAGetLastError()); + goto error; + } + + /* configure the socket */ + sockopt_bool = TRUE; + setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, + (const char *)&sockopt_bool, sizeof(sockopt_bool)); + + sockopt_bool = TRUE; + setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, + (const char *)&sockopt_bool, sizeof(sockopt_bool)); + + /* disable the Nagle algorithm (good for small messages) */ + //sockopt_bool = TRUE; + //setsockopt(l_sock, IPPROTO_TCP, TCP_NODELAY, + // (const char *)&sockopt_bool, sizeof(sockopt_bool)); + + /* local address:port */ + memset(&sa_local, 0, sizeof(sa_local)); + sa_local.sin_family = AF_INET; + sa_local.sin_port = htons(port_local); + host = gethostbyname(""); /* local host */ + sa_local.sin_addr.s_addr = inet_addr( + inet_ntoa(*(struct in_addr *)*host->h_addr_list)); + //if (bind(l_sock, &sa_local, sizeof(sa_local)) == -1) { + // fprintf(stderr, + // " WARNINIG Cannot bind to the local port, WSAErr=%d\n", + // WSAGetLastError()); + // /* no error */ + //} + + /* remote hostName:port (QSPY server socket) */ + host = gethostbyname(hostName); + if (host == NULL) { + fprintf(stderr, + " ERROR cannot resolve host Name=%s,WSAErr=%d\n", + hostName, WSAGetLastError()); + goto error; + } + + memset(&sa_remote, 0, sizeof(sa_remote)); + sa_remote.sin_family = AF_INET; + memcpy(&sa_remote.sin_addr, host->h_addr, host->h_length); + sa_remote.sin_port = htons(port_remote); + + /* try to connect to the QSPY server */ + if (connect(l_sock, (struct sockaddr *)&sa_remote, sizeof(sa_remote)) + == SOCKET_ERROR) + { + fprintf(stderr, + " ERROR socket configuration failed,WSAErr=%d\n", + WSAGetLastError()); + QS_EXIT(); + goto error; + } + + /* Set the socket to non-blocking mode. */ + if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) == SOCKET_ERROR) { + fprintf(stderr, + " ERROR Socket configuration failed WASErr=%d\n", + WSAGetLastError()); + QS_EXIT(); + goto error; + } + + //printf(" Connected to QSPY at Host=%s:%d\n", + // hostName, port_remote); + QS_onFlush(); + + return (uint8_t)1; /* success */ + +error: + return (uint8_t)0; /* failure */ +} +/*..........................................................................*/ +void QS_onCleanup(void) { + if (l_sock != INVALID_SOCKET) { + closesocket(l_sock); + l_sock = INVALID_SOCKET; + } + WSACleanup(); + //printf(" Disconnected from QSPY\n"); +} +/*..........................................................................*/ +QSTimeCtr QS_onGetTime(void) { + return (QSTimeCtr)clock(); +} +/*..........................................................................*/ +void QS_onReset(void) { + QS_onCleanup(); + exit(0); +} +/*..........................................................................*/ +void QS_onFlush(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + nBytes = QS_TX_SIZE; + } + } +} + +/*..........................................................................*/ +void QS_rx_input(void) { + uint8_t buf[QS_RX_SIZE]; + int status = recv(l_sock, (char *)buf, (int)sizeof(buf), 0); + if (status != SOCKET_ERROR) { /* any data received? */ + uint8_t *pb; + int i = (int)QS_rxGetNfree(); + if (i > status) { + i = status; + } + status -= i; + /* reorder the received bytes into QS-RX buffer */ + for (pb = &buf[0]; i > 0; --i, ++pb) { + QS_RX_PUT(*pb); + } + QS_rxParse(); /* parse all n-bytes of data */ + } +} +/*..........................................................................*/ +void QS_output(void) { + if (l_sock != INVALID_SOCKET) { /* socket initialized? */ + uint16_t nBytes = QS_TX_SIZE; + uint8_t const *data; + if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { + send(l_sock, (char const *)data, nBytes, 0); + } + } +} + diff --git a/ports/win32/qs_port.h b/ports/win32/qs_port.h index 263a4c9d..3696a012 100644 --- a/ports/win32/qs_port.h +++ b/ports/win32/qs_port.h @@ -4,14 +4,14 @@ * @ingroup ports * @cond ****************************************************************************** -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 +* Last Updated for Version: 6.3.6 +* Date of the Last Update: 2018-10-14 * -* 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 @@ -32,7 +32,7 @@ * along with this program. If not, see . * * Contact information: -* https://state-machine.com +* https://www.state-machine.com * mailto:info@state-machine.com ****************************************************************************** * @endcond @@ -50,6 +50,9 @@ #define QS_FUN_PTR_SIZE 4 #endif +void QS_output(void); /* handle the QS output */ +void QS_rx_input(void); /* handle the QS-RX input */ + /***************************************************************************** * NOTE: QS might be used with or without other QP components, in which * case the separate definitions of the macros QF_CRIT_STAT_TYPE, @@ -61,3 +64,4 @@ #include "qs.h" /* QS platform-independent public interface */ #endif /* qs_port_h */ + diff --git a/src/qf/qf_actq.c b/src/qf/qf_actq.c index e33e0b80..6f56d8c1 100644 --- a/src/qf/qf_actq.c +++ b/src/qf/qf_actq.c @@ -9,12 +9,12 @@ * @ingroup qf * @cond ****************************************************************************** -* Last updated for version 6.3.2 -* Last updated on 2018-06-16 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -126,11 +126,17 @@ bool QActive_post_(QActive * const me, QEvt const * const e, status = false; /* cannot post, but don't assert */ } + /* is it a dynamic event? */ + if (e->poolId_ != (uint8_t)0) { + QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ + } + if (status) { /* can post the event? */ - /* is it a pool event? */ - if (e->poolId_ != (uint8_t)0) { - QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ + --nFree; /* one free entry just used up */ + me->eQueue.nFree = nFree; /* update the volatile */ + if (me->eQueue.nMin > nFree) { + me->eQueue.nMin = nFree; /* increase minimum so far */ } QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_FIFO, @@ -145,24 +151,18 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_END_NOCRIT_() #ifdef Q_UTEST - /* in QUTest the event is posted under the following conditions: - * 1. the test-probe#2 is provided; OR - * 2. the 'sender' is 'me' (self-posting); OR - * 3. the AO-local-filter is set and is 'me'; OR - * 4. the AO-local-filter is not set AND the 'sender' is QS_RX - */ - if ((qs_tp_ == (uint32_t)2) - || (sender == me) - || (QS_priv_.locFilter[AO_OBJ] == me) - || ((QS_priv_.locFilter[AO_OBJ] == (void *)0) - && (sender == &QS_rxPriv_))) - { -#endif - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* update minimum so far */ + /* callback to examine the posted event under the the same conditions + * as producing the QS_QF_ACTIVE_POST_FIFO trace record, which are: + * 1. the local AO-filter is not set (zero) OR + * 2. the local AO-filter is set to this AO ('me') + */ + if ((QS_priv_.locFilter[AO_OBJ] == (QActive *)0) + || (QS_priv_.locFilter[AO_OBJ] == me)) + { + /* callback to examine the posted event */ + QS_onTestPost(sender, me, e, status); } +#endif /* empty queue? */ if (me->eQueue.frontEvt == (QEvt const *)0) { @@ -173,14 +173,13 @@ bool QActive_post_(QActive * const me, QEvt const * const e, else { /* insert event into the ring buffer (FIFO) */ QF_PTR_AT_(me->eQueue.ring, me->eQueue.head) = e; + if (me->eQueue.head == (QEQueueCtr)0) { /* need to wrap head? */ me->eQueue.head = me->eQueue.end; /* wrap around */ } --me->eQueue.head; /* advance the head (counter clockwise) */ } -#ifdef Q_UTEST - } -#endif + QF_CRIT_EXIT_(); } else { /* cannot post the event */ @@ -193,9 +192,22 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_(me); /* this active object (recipient) */ QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ QS_EQC_(nFree); /* number of free entries */ - QS_EQC_(margin); /* margin requested */ + QS_EQC_((QEQueueCtr)margin); /* margin requested */ QS_END_NOCRIT_() +#ifdef Q_UTEST + /* callback to examine the posted event under the the same conditions + * as producing the QS_QF_ACTIVE_POST_FIFO trace record, which are: + * 1. the local AO-filter is not set (zero) OR + * 2. the local AO-filter is set to this AO ('me') + */ + if ((QS_priv_.locFilter[AO_OBJ] == (QActive *)0) + || (QS_priv_.locFilter[AO_OBJ] == me)) + { + QS_onTestPost(sender, me, e, status); + } +#endif + QF_CRIT_EXIT_(); QF_gc(e); /* recycle the event to avoid a leak */ @@ -244,6 +256,12 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ } + --nFree; /* one free entry just used up */ + me->eQueue.nFree = nFree; /* update the volatile */ + if (me->eQueue.nMin > nFree) { + me->eQueue.nMin = nFree; /* update minimum so far */ + } + QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, QS_priv_.locFilter[AO_OBJ], me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ @@ -253,11 +271,18 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QS_EQC_(me->eQueue.nMin); /* min number of free entries */ QS_END_NOCRIT_() - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* update minimum so far */ - } +#ifdef Q_UTEST + /* callback to examine the posted event under the the same conditions + * as producing the QS_QF_ACTIVE_POST_FIFO trace record, which are: + * 1. the local AO-filter is not set (zero) OR + * 2. the local AO-filter is set to this AO ('me') + */ + if ((QS_priv_.locFilter[AO_OBJ] == (QActive *)0) + || (QS_priv_.locFilter[AO_OBJ] == me)) + { + QS_onTestPost((QActive *)0, me, e, true); + } +#endif frontEvt = me->eQueue.frontEvt; /* read volatile into the temporary */ me->eQueue.frontEvt = e; /* deliver the event directly to the front */ diff --git a/src/qf/qf_dyn.c b/src/qf/qf_dyn.c index 4e02b042..46858a35 100644 --- a/src/qf/qf_dyn.c +++ b/src/qf/qf_dyn.c @@ -4,12 +4,12 @@ * @ingroup qf * @cond ****************************************************************************** -* Last updated for version 6.2.0 -* Last updated on 2018-03-16 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -122,6 +122,15 @@ void QF_poolInit(void * const poolSto, uint_fast32_t const poolSize, /* perform the platform-dependent initialization of the pool */ QF_EPOOL_INIT_(QF_pool_[QF_maxPool_], poolSto, poolSize, evtSize); ++QF_maxPool_; /* one more pool */ + +#ifdef Q_SPY + /* generate the object-dictionary entry for the initialized pool */ + { + char_t obj_name[9] = "EvtPool?"; + obj_name[7] = (char_t)((int8_t)'0' + (int8_t)QF_maxPool_); + QS_obj_dict(&QF_pool_[QF_maxPool_ - (uint_fast8_t)1], obj_name); + } +#endif /* Q_SPY*/ } /****************************************************************************/ diff --git a/src/qf/qf_mem.c b/src/qf/qf_mem.c index 3569e93d..321b7b64 100644 --- a/src/qf/qf_mem.c +++ b/src/qf/qf_mem.c @@ -4,12 +4,12 @@ * @brief ::QMPool implementatin (Memory Pool) * @cond ****************************************************************************** -* Last updated for version 6.2.0 -* Last updated on 2018-03-13 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -170,9 +170,9 @@ void QMPool_put(QMPool * const me, void *b) { me->free_head = b; /* set as new head of the free list */ ++me->nFree; /* one more free block in this pool */ - QS_BEGIN_NOCRIT_(QS_QF_MPOOL_PUT, QS_priv_.locFilter[MP_OBJ], me->start) + QS_BEGIN_NOCRIT_(QS_QF_MPOOL_PUT, QS_priv_.locFilter[MP_OBJ], me) QS_TIME_(); /* timestamp */ - QS_OBJ_(me->start); /* the memory managed by this pool */ + QS_OBJ_(me); /* this memory pool */ QS_MPC_(me->nFree); /* the number of free blocks in the pool */ QS_END_NOCRIT_() @@ -250,9 +250,9 @@ void *QMPool_get(QMPool * const me, uint_fast16_t const margin) { me->free_head = fb_next; /* set the head to the next free block */ QS_BEGIN_NOCRIT_(QS_QF_MPOOL_GET, - QS_priv_.locFilter[MP_OBJ], me->start) + QS_priv_.locFilter[MP_OBJ], me) QS_TIME_(); /* timestamp */ - QS_OBJ_(me->start); /* the memory managed by this pool */ + QS_OBJ_(me); /* this memory pool */ QS_MPC_(me->nFree); /* # of free blocks in the pool */ QS_MPC_(me->nMin); /* min # free blocks ever in the pool */ QS_END_NOCRIT_() @@ -262,9 +262,9 @@ void *QMPool_get(QMPool * const me, uint_fast16_t const margin) { fb = (QFreeBlock *)0; QS_BEGIN_NOCRIT_(QS_QF_MPOOL_GET_ATTEMPT, - QS_priv_.locFilter[MP_OBJ], me->start) + QS_priv_.locFilter[MP_OBJ], me) QS_TIME_(); /* timestamp */ - QS_OBJ_(me->start); /* the memory managed by this pool */ + QS_OBJ_(me); /* this memory pool */ QS_MPC_(me->nFree); /* the number of free blocks in the pool */ QS_MPC_(margin); /* the requested margin */ QS_END_NOCRIT_() diff --git a/src/qf/qf_qeq.c b/src/qf/qf_qeq.c index b0e79e76..b67bfc96 100644 --- a/src/qf/qf_qeq.c +++ b/src/qf/qf_qeq.c @@ -4,12 +4,12 @@ * @ingroup qf * @cond ****************************************************************************** -* Last updated for version 6.3.2 -* Last updated on 2018-06-16 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -133,6 +133,12 @@ bool QEQueue_post(QEQueue * const me, QEvt const * const e, QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ } + --nFree; /* one free entry just used up */ + me->nFree = nFree; /* update the volatile */ + if (me->nMin > nFree) { + me->nMin = nFree; /* update minimum so far */ + } + QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_FIFO, QS_priv_.locFilter[EQ_OBJ], me) QS_TIME_(); /* timestamp */ @@ -143,12 +149,6 @@ bool QEQueue_post(QEQueue * const me, QEvt const * const e, QS_EQC_(me->nMin); /* min number of free entries */ QS_END_NOCRIT_() - --nFree; /* one free entry just used up */ - me->nFree = nFree; /* update the volatile */ - if (me->nMin > nFree) { - me->nMin = nFree; /* update minimum so far */ - } - /* was the queue empty? */ if (me->frontEvt == (QEvt const *)0) { me->frontEvt = e; /* deliver event directly */ @@ -227,6 +227,12 @@ void QEQueue_postLIFO(QEQueue * const me, QEvt const * const e) { QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ } + --nFree; /* one free entry just used up */ + me->nFree = nFree; /* update the volatile */ + if (me->nMin > nFree) { + me->nMin = nFree; /* update minimum so far */ + } + QS_BEGIN_NOCRIT_(QS_QF_EQUEUE_POST_LIFO, QS_priv_.locFilter[EQ_OBJ], me) QS_TIME_(); /* timestamp */ QS_SIG_(e->sig); /* the signal of this event */ @@ -236,12 +242,6 @@ void QEQueue_postLIFO(QEQueue * const me, QEvt const * const e) { QS_EQC_(me->nMin); /* min number of free entries */ QS_END_NOCRIT_() - --nFree; /* one free entry just used up */ - me->nFree = nFree; /* update the volatile */ - if (me->nMin > nFree) { - me->nMin = nFree; /* update minimum so far */ - } - frontEvt = me->frontEvt; /* read volatile into the temporary */ me->frontEvt = e; /* deliver event directly to the front of the queue */ @@ -253,6 +253,7 @@ void QEQueue_postLIFO(QEQueue * const me, QEvt const * const e) { } QF_PTR_AT_(me->ring, me->tail) = frontEvt; /* save old front evt */ } + QF_CRIT_EXIT_(); } diff --git a/src/qs/qs.c b/src/qs/qs.c index 047f06ec..f13392f8 100644 --- a/src/qs/qs.c +++ b/src/qs/qs.c @@ -4,14 +4,14 @@ * @ingroup qs * @cond ****************************************************************************** -* Last updated for version 6.2.0 -* Last updated on 2018-03-16 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2002-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 @@ -180,6 +180,7 @@ void QS_filterOn(uint_fast8_t rec) { else if (rec == (uint_fast8_t)QS_U4_RECORDS) { QS_priv_.glbFilter[13] |= (uint8_t)0xC0U; QS_priv_.glbFilter[14] |= (uint8_t)0xFFU; + QS_priv_.glbFilter[15] |= (uint8_t)0x1FU; } else if (rec == (uint_fast8_t)QS_UA_RECORDS) { QS_priv_.glbFilter[8] |= (uint8_t)0xC0U; @@ -187,7 +188,9 @@ void QS_filterOn(uint_fast8_t rec) { QS_priv_.glbFilter[10] |= (uint8_t)0xFFU; QS_priv_.glbFilter[11] |= (uint8_t)0xFFU; QS_priv_.glbFilter[12] |= (uint8_t)0xFFU; + QS_priv_.glbFilter[13] |= (uint8_t)0xFFU; QS_priv_.glbFilter[14] |= (uint8_t)0xFFU; + QS_priv_.glbFilter[15] |= (uint8_t)0x1FU; } else { /* record numbers can't exceed QS_ESC, so they don't need escaping */ @@ -271,6 +274,7 @@ void QS_filterOff(uint_fast8_t rec) { else if (rec == (uint_fast8_t)QS_U4_RECORDS) { QS_priv_.glbFilter[13] &= (uint8_t)(~0xC0U); QS_priv_.glbFilter[14] = (uint8_t)0; + QS_priv_.glbFilter[15] &= (uint8_t)(~0x1FU); } else if (rec == (uint_fast8_t)QS_UA_RECORDS) { QS_priv_.glbFilter[8] &= (uint8_t)(~0xC0U); @@ -278,7 +282,9 @@ void QS_filterOff(uint_fast8_t rec) { QS_priv_.glbFilter[10] = (uint8_t)0; QS_priv_.glbFilter[11] = (uint8_t)0; QS_priv_.glbFilter[12] = (uint8_t)0; + QS_priv_.glbFilter[13] = (uint8_t)0; QS_priv_.glbFilter[14] = (uint8_t)0; + QS_priv_.glbFilter[15] &= (uint8_t)(~0x1FU); } else { /* record IDs can't exceed QS_ESC, so they don't need escaping */ diff --git a/src/qs/qs_rx.c b/src/qs/qs_rx.c index 2c7c16b8..10115767 100644 --- a/src/qs/qs_rx.c +++ b/src/qs/qs_rx.c @@ -4,12 +4,12 @@ * @ingroup qs * @cond ****************************************************************************** -* Last updated for version 6.3.0 -* Last updated on 2018-04-30 +* Last updated for version 6.3.6 +* Last updated on 2018-10-04 * -* 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) 2002-2018 Quantum Leaps, LLC. All rights reserved. * @@ -131,6 +131,7 @@ typedef struct { uint8_t idx; } EvtVar; +/* extended-state variables for the current state */ static struct { union Variant { CmdVar cmd; @@ -142,7 +143,7 @@ static struct { ObjVar obj; EvtVar evt; TPVar tp; - } var; /* extended-state variables for the current state */ + } var; uint8_t state; uint8_t esc; uint8_t seq; @@ -180,6 +181,8 @@ enum { WAIT4_OBJ_KIND, WAIT4_OBJ_ADDR, WAIT4_OBJ_FRAME, + WAIT4_QUERY_KIND, + WAIT4_QUERY_FRAME, WAIT4_EVT_PRIO, WAIT4_EVT_SIG, WAIT4_EVT_LEN, @@ -414,6 +417,10 @@ static void QS_rxParseData_(uint8_t b) { l_rx.var.obj.recId = (uint8_t)QS_RX_CURR_OBJ; QS_RX_TRAN_(WAIT4_OBJ_KIND); break; + case QS_RX_QUERY_CURR: + l_rx.var.obj.recId = (uint8_t)QS_RX_QUERY_CURR; + QS_RX_TRAN_(WAIT4_QUERY_KIND); + break; case QS_RX_EVENT: QS_RX_TRAN_(WAIT4_EVT_PRIO); break; @@ -656,6 +663,21 @@ static void QS_rxParseData_(uint8_t b) { /* keep ignoring the data until a frame is collected */ break; } + case WAIT4_QUERY_KIND: { + if (b < (uint8_t)MAX_OBJ) { + l_rx.var.obj.kind = b; + QS_RX_TRAN_(WAIT4_QUERY_FRAME); + } + else { + QS_rxReportError_(l_rx.var.obj.recId); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case WAIT4_QUERY_FRAME: { + /* keep ignoring the data until a frame is collected */ + break; + } case WAIT4_AO_FILTER_PRIO: { l_rx.var.aFlt.prio = b; QS_RX_TRAN_(WAIT4_AO_FILTER_FRAME); @@ -811,9 +833,11 @@ static void QS_rxHandleGoodFrame_(uint8_t state) { } case WAIT4_TICK_FRAME: { QS_rxReportAck_(QS_RX_TICK); - QF_tickX_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); #ifdef Q_UTEST + QS_tickX_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); QS_processTestEvts_(); /* process all events produced */ +#else + QF_tickX_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); #endif QS_rxReportDone_(QS_RX_TICK); break; @@ -886,7 +910,7 @@ static void QS_rxHandleGoodFrame_(uint8_t state) { l_rx.var.gFlt.data[8] |= (uint8_t)0x3F; /* never enable the last 3 records (0x7D, 0x7E, 0x7F) */ - l_rx.var.gFlt.data[15] &= (uint8_t)0xE0; + l_rx.var.gFlt.data[15] &= (uint8_t)0x1F; for (i=(uint8_t)0; i < (uint8_t)sizeof(QS_priv_.glbFilter); ++i) { QS_priv_.glbFilter[i] = l_rx.var.gFlt.data[i]; @@ -895,19 +919,18 @@ static void QS_rxHandleGoodFrame_(uint8_t state) { break; } case WAIT4_OBJ_FRAME: { - if (l_rx.var.obj.kind < (uint8_t)MAX_OBJ) { + i = l_rx.var.obj.kind; + if (i < (uint8_t)MAX_OBJ) { if (l_rx.var.obj.recId == (uint8_t)QS_RX_LOC_FILTER) { - QS_priv_.locFilter[l_rx.var.obj.kind] - = (void *)l_rx.var.obj.addr; + QS_priv_.locFilter[i] = (void *)l_rx.var.obj.addr; } - else { - QS_rxPriv_.currObj[l_rx.var.obj.kind] - = (void *)l_rx.var.obj.addr; + else { /* set the current object */ + QS_rxPriv_.currObj[i] = (void *)l_rx.var.obj.addr; } QS_rxReportAck_((enum QSpyRxRecords)l_rx.var.obj.recId); } /* both SM and AO */ - else if (l_rx.var.obj.kind == (uint8_t)SM_AO_OBJ) { + else if (i == (uint8_t)SM_AO_OBJ) { if (l_rx.var.obj.recId == (uint8_t)QS_RX_LOC_FILTER) { QS_priv_.locFilter[SM_OBJ] = (void *)l_rx.var.obj.addr; QS_priv_.locFilter[AO_OBJ] = (void *)l_rx.var.obj.addr; @@ -923,6 +946,52 @@ static void QS_rxHandleGoodFrame_(uint8_t state) { } break; } + case WAIT4_QUERY_FRAME: { + i = l_rx.var.obj.kind; + ptr = (uint8_t *)QS_rxPriv_.currObj[i]; + if (ptr != (void *)0) { + QS_beginRec((uint_fast8_t)QS_QUERY_DATA); + QS_TIME_(); /* timestamp */ + QS_U8_(i); /* object kind */ + QS_OBJ_(ptr); + switch (i) { + case SM_OBJ: + QS_FUN_(((QHsm *)ptr)->state.fun); + break; + +#ifdef Q_UTEST + case AO_OBJ: + QS_EQC_(((QActive *)ptr)->eQueue.nFree); + QS_EQC_(((QActive *)ptr)->eQueue.nMin); + break; + case MP_OBJ: + QS_MPC_(((QMPool *)ptr)->nFree); + QS_MPC_(((QMPool *)ptr)->nMin); + break; + case EQ_OBJ: + QS_EQC_(((QEQueue *)ptr)->nFree); + QS_EQC_(((QEQueue *)ptr)->nMin); + break; + case TE_OBJ: + QS_OBJ_(((QTimeEvt *)ptr)->act); + QS_TEC_(((QTimeEvt *)ptr)->ctr); + QS_TEC_(((QTimeEvt *)ptr)->interval); + QS_SIG_(((QTimeEvt *)ptr)->super.sig); + QS_U8_ (((QTimeEvt *)ptr)->super.refCtr_); + break; +#endif /* Q_UTEST */ + + default: + break; + } + QS_endRec(); + QS_REC_DONE(); + } + else { + QS_rxReportError_((uint8_t)QS_RX_QUERY_CURR); + } + break; + } case WAIT4_AO_FILTER_FRAME: { QS_rxReportAck_(QS_RX_AO_FILTER); if (l_rx.var.aFlt.prio <= (uint8_t)QF_MAX_ACTIVE) { diff --git a/src/qs/qutest.c b/src/qs/qutest.c index 80c409bb..2cc19964 100644 --- a/src/qs/qutest.c +++ b/src/qs/qutest.c @@ -4,14 +4,14 @@ * @ingroup qs * @cond ****************************************************************************** -* Last updated for version 6.3.4 -* Last updated on 2018-08-09 +* Last updated for version 6.3.6 +* Last updated on 2018-10-03 * -* 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) 2005-2018 Quantum Leaps, LLC. All rights reserved. +* Copyright (C) 2002-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 @@ -51,6 +51,10 @@ Q_DEFINE_THIS_MODULE("qutest") /* Global objects ==========================================================*/ uint8_t volatile QF_intNest; +enum { + TE_IS_LINKED = 1U << 7 /* flag */ +}; + /* QF functions ============================================================*/ void QF_init(void) { QF_maxPool_ = (uint_fast8_t)0; @@ -59,7 +63,8 @@ void QF_init(void) { QF_intNest = (uint8_t)0; QF_bzero(&QF_active_[0], (uint_fast16_t)sizeof(QF_active_)); - QF_bzero(&QS_rxPriv_.readySet, (uint_fast16_t)sizeof(QS_rxPriv_.readySet)); + QF_bzero(&QS_rxPriv_.readySet, + (uint_fast16_t)sizeof(QS_rxPriv_.readySet)); } /*..........................................................................*/ void QF_stop(void) { @@ -83,7 +88,8 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { - Q_REQUIRE_ID(500, ((uint_fast8_t)0 < prio) /* priority must be in range */ + /* priority must be in range */ + Q_REQUIRE_ID(200, ((uint_fast8_t)0 < prio) && (prio <= (uint_fast8_t)QF_MAX_ACTIVE)); (void)stkSto; @@ -91,10 +97,11 @@ void QActive_start_(QActive * const me, uint_fast8_t prio, QEQueue_init(&me->eQueue, qSto, qLen); /* initialize the built-in queue */ me->prio = (uint8_t)prio; /* set the current priority of the AO */ + QF_add_(me); /* make QF aware of this active object */ QHSM_INIT(&me->super, ie); /* take the top-most initial tran. */ - QS_FLUSH(); /* flush the trace buffer to the host */ + //QS_FLUSH(); /* flush the trace buffer to the host */ } /*..........................................................................*/ void QActive_stop(QActive * const me) { @@ -102,215 +109,177 @@ void QActive_stop(QActive * const me) { } /****************************************************************************/ -/* The following flags and bitmasks are for the fields of the @c refCtr_ -* attribute of the QTimeEvt struct (inherited from QEvt). This attribute -* is NOT used for reference counting in time events, because the @c poolId_ -* attribute is zero ("static events"). -*/ -enum { - TE_IS_LINKED = (uint8_t)(1U << 7), /* flag */ - TE_WAS_DISARMED = (uint8_t)(1U << 6), /* flag */ - TE_TICK_RATE = (uint8_t)0x0F /* bitmask */ -}; +static void QActiveDummy_init_(QHsm * const me, QEvt const * const e); +static void QActiveDummy_dispatch_(QHsm * const me, QEvt const * const e); + +static void QActiveDummy_start_(QActive * const me, uint_fast8_t prio, + QEvt const *qSto[], uint_fast16_t qLen, + void *stkSto, uint_fast16_t stkSize, + QEvt const *ie); +static bool QActiveDummy_post_(QActive * const me, QEvt const * const e, + uint_fast16_t const margin, void const * const sender); +static void QActiveDummy_postLIFO_(QActive * const me, QEvt const * const e); /*..........................................................................*/ -QTimeEvtCtr QTimeEvt_ctr(QTimeEvt const * const me) { - QTimeEvtCtr ret; - QF_CRIT_STAT_ - - QF_CRIT_ENTRY_(); - ret = me->ctr; - QF_CRIT_EXIT_(); - - return ret; +/*! "constructor" of QActiveDummy */ +void QActiveDummy_ctor(QActiveDummy * const me) { + static QActiveVtbl const vtbl = { /* QActiveVtbl virtual table */ + { &QActiveDummy_init_, + &QActiveDummy_dispatch_ }, + &QActiveDummy_start_, + &QActiveDummy_post_, + &QActiveDummy_postLIFO_ + }; + QActive_ctor(&me->super, Q_STATE_CAST(0)); /* superclass' ctor */ + me->super.super.vptr = &vtbl.super; /* hook the vptr */ } /*..........................................................................*/ -void QTimeEvt_ctorX(QTimeEvt * const me, QActive * const act, - enum_t const sig, uint_fast8_t tickRate) +static void QActiveDummy_start_(QActive * const me, uint_fast8_t prio, + QEvt const *qSto[], uint_fast16_t qLen, + void *stkSto, uint_fast16_t stkSize, + QEvt const *ie) { - /** @pre The signal must be valid and the tick rate in range */ - Q_REQUIRE_ID(300, (sig >= (enum_t)Q_USER_SIG) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE)); - - me->next = (QTimeEvt *)0; - me->ctr = (QTimeEvtCtr)0; - me->interval = (QTimeEvtCtr)0; - me->act = act; - - me->super.sig = (QSignal)sig; - me->super.poolId_ = (uint8_t)0; - /* The refCtr_ attribute is not used in time events, so it is - * reused to hold the tickRate as well as other information + /* priority must be in range + * queue must NOT be provided + * stack must NOT be provided + * initialization event (ie) must NOT be provided */ - me->super.refCtr_ = (uint8_t)tickRate; + Q_REQUIRE_ID(300, ((uint_fast8_t)0 < prio) + && ((uint_fast8_t)QF_MAX_ACTIVE) + && (qSto == (QEvt const **)0) + && (qLen == (uint_fast16_t)0) + && (stkSto == (void *)0) + && (stkSize == (uint_fast16_t)0) + && (ie == (QEvt const *)0)); + + me->prio = (uint8_t)prio; /* set the current priority of the AO */ + + QF_add_(me); /* make QF aware of this active object */ + + QHSM_INIT(&me->super, ie); /* take the top-most initial tran. */ + //QS_FLUSH(); /* flush the trace buffer to the host */ } /*..........................................................................*/ -void QTimeEvt_armX(QTimeEvt * const me, - QTimeEvtCtr const nTicks, QTimeEvtCtr const interval) +static void QActiveDummy_init_(QHsm * const me, QEvt const * const e) { + QS_CRIT_STAT_ + QS_BEGIN_(QS_QEP_STATE_INIT, QS_priv_.locFilter[SM_OBJ], me) + QS_OBJ_(me); /* this state machine object */ + QS_FUN_(me->state.fun); /* the source state */ + QS_FUN_(me->temp.fun); /* the target of the initial transition */ + QS_END_() + (void)e; /* unused parameter */ +} +/*..........................................................................*/ +static void QActiveDummy_dispatch_(QHsm * const me, QEvt const * const e) { + QS_CRIT_STAT_ + QS_BEGIN_(QS_QEP_DISPATCH, QS_priv_.locFilter[SM_OBJ], me) + QS_TIME_(); /* time stamp */ + QS_SIG_(e->sig); /* the signal of the event */ + QS_OBJ_(me); /* this state machine object */ + QS_FUN_(me->state.fun); /* the current state */ + QS_END_() +} +/*..........................................................................*/ +static bool QActiveDummy_post_(QActive * const me, QEvt const * const e, + uint_fast16_t const margin, + void const * const sender) { - uint_fast8_t tickRate = ((uint_fast8_t)me->super.refCtr_ - & (uint_fast8_t)TE_TICK_RATE); - QTimeEvtCtr ctr = me->ctr; + bool status = true; QF_CRIT_STAT_ + QS_TEST_PROBE_DEF(&QActive_post_) - /** @pre the host AO must be valid, time evnet must be disarmed, - * number of clock ticks cannot be zero, and the signal must be valid. - */ - Q_REQUIRE_ID(400, (me->act != (void *)0) - && (ctr == (QTimeEvtCtr)0) - && (nTicks != (QTimeEvtCtr)0) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) - && (me->super.sig >= (QSignal)Q_USER_SIG)); - - QF_CRIT_ENTRY_(); - me->ctr = nTicks; - me->interval = interval; - - QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_ARM, QS_priv_.locFilter[TE_OBJ], me) - QS_TIME_(); /* timestamp */ - QS_OBJ_(me); /* this time event object */ - QS_OBJ_(me->act); /* the active object */ - QS_TEC_(nTicks); /* the number of ticks */ - QS_TEC_(interval); /* the interval */ - QS_U8_((uint8_t)tickRate); /* tick rate */ - QS_END_NOCRIT_() - - QF_CRIT_EXIT_(); -} -/*..........................................................................*/ -bool QTimeEvt_disarm(QTimeEvt * const me) { - bool wasArmed; - QF_CRIT_STAT_ - - QF_CRIT_ENTRY_(); - - /* is the time event actually armed? */ - if (me->ctr != (QTimeEvtCtr)0) { - wasArmed = true; - me->super.refCtr_ |= (uint8_t)TE_WAS_DISARMED; - - QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM, QS_priv_.locFilter[TE_OBJ], me) - QS_TIME_(); /* timestamp */ - QS_OBJ_(me); /* this time event object */ - QS_OBJ_(me->act); /* the target AO */ - QS_TEC_(me->ctr); /* the number of ticks */ - QS_TEC_(me->interval); /* the interval */ - QS_U8_((uint8_t)(me->super.refCtr_ & (uint8_t)TE_TICK_RATE)); - QS_END_NOCRIT_() - - me->ctr = (QTimeEvtCtr)0; /* schedule removal from the list */ - } - else { /* the time event was already disarmed automatically */ - wasArmed = false; - me->super.refCtr_ &= (uint8_t)(~(uint8_t)TE_WAS_DISARMED); - - QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_DISARM_ATTEMPT, - QS_priv_.locFilter[TE_OBJ], me) - QS_TIME_(); /* timestamp */ - QS_OBJ_(me); /* this time event object */ - QS_OBJ_(me->act); /* the target AO */ - QS_U8_((uint8_t)(me->super.refCtr_ & (uint8_t)TE_TICK_RATE)); - QS_END_NOCRIT_() - - } - QF_CRIT_EXIT_(); - return wasArmed; -} -bool QTimeEvt_rearm(QTimeEvt * const me, QTimeEvtCtr const nTicks) { - uint_fast8_t tickRate = (uint_fast8_t)me->super.refCtr_ - & (uint_fast8_t)TE_TICK_RATE; - bool wasArmed; - QF_CRIT_STAT_ - - /** @pre AO must be valid, tick rate must be in range, nTicks must not - * be zero, and the signal of this time event must be valid - */ - Q_REQUIRE_ID(600, (me->act != (void *)0) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) - && (nTicks != (QTimeEvtCtr)0) - && (me->super.sig >= (QSignal)Q_USER_SIG)); - - QF_CRIT_ENTRY_(); - - /* is the time evt not running? */ - if (me->ctr == (QTimeEvtCtr)0) { - wasArmed = false; - - /* NOTE: For the duration of a single clock tick of the specified - * tick rate a time event can be disarmed and yet still linked into - * the list, because unlinking is performed exclusively in the - * QF_tickX() function. - */ - /* is the time event linked yet? */ - if ((me->super.refCtr_ & (uint8_t)TE_IS_LINKED) == (uint8_t)0) { - me->super.refCtr_ |= (uint8_t)TE_IS_LINKED; /* mark as linked */ + /* test-probe#1 for faking queue overflow */ + QS_TEST_PROBE_ID(1, + status = false; + if (margin == QF_NO_MARGIN) { + /* fake assertion Mod=qf_actq,Loc=110 */ + Q_onAssert("qf_actq", 110); } - } - else { /* the time event was armed */ - wasArmed = true; - } - me->ctr = nTicks; /* re-load the tick counter (shift the phasing) */ + ) - QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_REARM, QS_priv_.locFilter[TE_OBJ], me) - QS_TIME_(); /* timestamp */ - QS_OBJ_(me); /* this time event object */ - QS_OBJ_(me->act); /* the target AO */ - QS_TEC_(me->ctr); /* the number of ticks */ - QS_TEC_(me->interval); /* the interval */ - QS_2U8_((uint8_t)tickRate, - ((wasArmed != false) ? (uint8_t)1 : (uint8_t)0)); + QF_CRIT_ENTRY_(); + + /* is it a dynamic event? */ + if (e->poolId_ != (uint8_t)0) { + QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ + } + + QS_BEGIN_NOCRIT_((status ? QS_QF_ACTIVE_POST_FIFO + : QS_QF_ACTIVE_POST_ATTEMPT), + QS_priv_.locFilter[AO_OBJ], me) + QS_TIME_(); /* timestamp */ + QS_OBJ_(sender); /* the sender object */ + QS_SIG_(e->sig); /* the signal of the event */ + QS_OBJ_(me); /* this active object */ + QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & refCtr of the evt */ + QS_EQC_((QEQueueCtr)0); /* number of free entries */ + QS_EQC_((QEQueueCtr)margin); /* margin requested */ QS_END_NOCRIT_() + /* callback to examine the posted event under the the same conditions + * as producing the QS_QF_ACTIVE_POST_FIFO trace record, which are: + * 1. the local AO-filter is not set (zero) OR + * 2. the local AO-filter is set to this AO ('me') + */ + if ((QS_priv_.locFilter[AO_OBJ] == (QActive *)0) + || (QS_priv_.locFilter[AO_OBJ] == me)) + { + QS_onTestPost(sender, me, e, status); + } QF_CRIT_EXIT_(); - return wasArmed; + + /* recycle the event immediately, because it was not really posted */ + QF_gc(e); + + return status; /* the event is "posted" correctly */ } +/*..........................................................................*/ +static void QActiveDummy_postLIFO_(QActive * const me, QEvt const * const e) { + QF_CRIT_STAT_ + QS_TEST_PROBE_DEF(&QActive_postLIFO_) + + /* test-probe#1 for faking queue overflow */ + QS_TEST_PROBE_ID(1, + /* fake assertion Mod=qf_actq,Loc=210 */ + Q_onAssert("qf_actq", 210); + return; + ) + + QF_CRIT_ENTRY_(); + + /* is it a dynamic event? */ + if (e->poolId_ != (uint8_t)0) { + QF_EVT_REF_CTR_INC_(e); /* increment the reference counter */ + } + + QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_POST_LIFO, + QS_priv_.locFilter[AO_OBJ], me) + QS_TIME_(); /* timestamp */ + QS_SIG_(e->sig); /* the signal of this event */ + QS_OBJ_(me); /* this active object */ + QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & refCtr of the evt */ + QS_EQC_((QEQueueCtr)0); /* number of free entries */ + QS_EQC_((QEQueueCtr)0); /* min number of free entries */ + QS_END_NOCRIT_() + + /* callback to examine the posted event under the the same conditions + * as producing the QS_QF_ACTIVE_POST_FIFO trace record, which are: + * 1. the local AO-filter is not set (zero) OR + * 2. the local AO-filter is set to this AO ('me') + */ + if ((QS_priv_.locFilter[AO_OBJ] == (QActive *)0) + || (QS_priv_.locFilter[AO_OBJ] == me)) + { + QS_onTestPost((QActive *)0, me, e, true); + } + + QF_CRIT_EXIT_(); + + /* recycle the event immediately, because it was not really posted */ + QF_gc(e); +} + /****************************************************************************/ -bool QTimeEvt_wasDisarmed(QTimeEvt * const me) { - uint8_t wasDisarmed = (me->super.refCtr_ & (uint8_t)TE_WAS_DISARMED); - me->super.refCtr_ |= (uint8_t)TE_WAS_DISARMED; /* set the flag */ - return (wasDisarmed != (uint8_t)0) ? true : false; -} -/*..........................................................................*/ -void QF_tickX_(uint_fast8_t const tickRate, void const * const sender) { - QF_CRIT_STAT_ - - QF_CRIT_ENTRY_(); - if (QS_rxPriv_.currObj[TE_OBJ] != (void *)0) { - QTimeEvt *t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; - QActive *act = (QActive *)t->act; /* temp. for volatile */ - - if (t->interval == (QTimeEvtCtr)0) { /* single-shot TE? */ - t->ctr = (QTimeEvtCtr)0; /* auto-disarm */ - /* mark time event 't' as NOT linked */ - t->super.refCtr_ &= (uint8_t)(~(uint8_t)TE_IS_LINKED); - - QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM, - QS_priv_.locFilter[TE_OBJ], t) - QS_OBJ_(t); /* this time event object */ - QS_OBJ_(act); /* the target AO */ - QS_U8_((uint8_t)tickRate); /* tick rate */ - QS_END_NOCRIT_() - } - - QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, - QS_priv_.locFilter[TE_OBJ], t) - QS_TIME_(); /* timestamp */ - QS_OBJ_(t); /* the time event object */ - QS_SIG_(t->super.sig); /* signal of this time event */ - QS_OBJ_(act); /* the target AO */ - QS_U8_((uint8_t)tickRate); /* tick rate */ - QS_END_NOCRIT_() - - QF_CRIT_EXIT_(); /* exit critical section before posting */ - - QACTIVE_POST(act, &t->super, sender); /* asserts if queue overflows */ - } - else { - QF_CRIT_EXIT_(); - } -} - -/*..........................................................................*/ void QS_processTestEvts_(void) { QS_TEST_PROBE_DEF(&QS_processTestEvts_) @@ -340,6 +309,115 @@ void QS_processTestEvts_(void) { } } } +/*..........................................................................*/ +/* The testing version of system tick processing performs as follows: +* 1. If the Current Time Event (TE) Object is defined and the TE is armed, +* the TE is disarmed (if one-shot) and then posted to the recipient AO. +* 2. The linked-list of all armed Time Events is updated. +*/ +void QS_tickX_(uint_fast8_t const tickRate, void const * const sender) { + QTimeEvt *t; + QActive *act; + QTimeEvt *prev; + QF_CRIT_STAT_ + + QF_CRIT_ENTRY_(); + prev = &QF_timeEvtHead_[tickRate]; + + QS_BEGIN_NOCRIT_(QS_QF_TICK, (void *)0, (void *)0) + QS_TEC_((QTimeEvtCtr)(++prev->ctr)); /* tick ctr */ + QS_U8_((uint8_t)tickRate); /* tick rate */ + QS_END_NOCRIT_() + + // is current Time Event object provided? + t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; + if (t != (void *)0) { + + /* the time event must be armed */ + Q_ASSERT_ID(810, t->ctr != (QTimeEvtCtr)0); + + act = (QActive *)t->act; /* temp. for volatile */ + + /* the recipient AO must be provided */ + Q_ASSERT_ID(820, act != (QActive *)0); + + // periodic time evt? + if (t->interval != (QTimeEvtCtr)0) { + t->ctr = t->interval; /* rearm the time event */ + } + else { /* one-shot time event: automatically disarm */ + t->ctr = (QTimeEvtCtr)0; /* auto-disarm */ + /* mark time event 't' as NOT linked */ + t->super.refCtr_ &= (uint8_t)(~(uint8_t)TE_IS_LINKED); + + QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_AUTO_DISARM, + QS_priv_.locFilter[TE_OBJ], t) + QS_OBJ_(t); /* this time event object */ + QS_OBJ_(act); /* the target AO */ + QS_U8_((uint8_t)tickRate); /* tick rate */ + QS_END_NOCRIT_() + } + + QS_BEGIN_NOCRIT_(QS_QF_TIMEEVT_POST, + QS_priv_.locFilter[TE_OBJ], t) + QS_TIME_(); /* timestamp */ + QS_OBJ_(t); /* the time event object */ + QS_SIG_(t->super.sig); /* signal of this time event */ + QS_OBJ_(act); /* the target AO */ + QS_U8_((uint8_t)tickRate); /* tick rate */ + QS_END_NOCRIT_() + + QF_CRIT_EXIT_(); /* exit critical section before posting */ + + QACTIVE_POST(act, &t->super, sender); /* asserts if queue overflows */ + + QF_CRIT_ENTRY_(); + } + + /* update the linked list of time events */ + for (;;) { + t = prev->next; /* advance down the time evt. list */ + + /* end of the list? */ + if (t == (QTimeEvt *)0) { + + /* any new time events armed since the last run of QF_tickX_()? */ + if (QF_timeEvtHead_[tickRate].act != (void *)0) { + + /* sanity check */ + Q_ASSERT_CRIT_(830, prev != (QTimeEvt *)0); + prev->next = (QTimeEvt *)QF_timeEvtHead_[tickRate].act; + QF_timeEvtHead_[tickRate].act = (void *)0; + t = prev->next; /* switch to the new list */ + } + else { + break; /* all currently armed time evts. processed */ + } + } + + /* time event scheduled for removal? */ + if (t->ctr == (QTimeEvtCtr)0) { + prev->next = t->next; + /* mark time event 't' as NOT linked */ + t->super.refCtr_ &= (uint8_t)(~(uint8_t)TE_IS_LINKED); + /* do NOT advance the prev pointer */ + QF_CRIT_EXIT_(); /* exit crit. section to reduce latency */ + + /* prevent merging critical sections, see NOTE1 below */ + QF_CRIT_EXIT_NOP(); + } + else { + prev = t; /* advance to this time event */ + QF_CRIT_EXIT_(); /* exit crit. section to reduce latency */ + + /* prevent merging critical sections, see NOTE1 below */ + QF_CRIT_EXIT_NOP(); + } + QF_CRIT_ENTRY_(); /* re-enter crit. section to continue */ + } + + QF_CRIT_EXIT_(); +} /****************************************************************************/ void Q_onAssert(char_t const * const module, int_t loc) { diff --git a/version-6.3.4 b/version-6.3.4 deleted file mode 100644 index 6fe68829..00000000 --- a/version-6.3.4 +++ /dev/null @@ -1,2 +0,0 @@ -QP/C 6.3.4 -2018-08-09 diff --git a/version-6.3.6 b/version-6.3.6 new file mode 100644 index 00000000..3d180f0c --- /dev/null +++ b/version-6.3.6 @@ -0,0 +1,2 @@ +QP/C 6.3.6 +2018-10-20

    3. 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