mirror of
https://github.com/pvvx/RTL00MP3.git
synced 2025-02-05 15:25:17 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
aafc2a508f
197 changed files with 52917 additions and 3054 deletions
24
.cproject
24
.cproject
|
@ -114,8 +114,8 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
||||||
|
@ -180,8 +180,8 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
||||||
|
@ -257,7 +257,7 @@
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="RTL00_SDKV35a/component/common/drivers/sdio/realtek/sdio_host/src|RTL00_SDKV35a/component/common/file_system/fatfs/disk_if/src/usbdisk.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/app_start.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/sdio|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/core/option|RTL00_SDKV35a/component/common/api/wifi/rtw_wpa_supplicant/src/utils|RTL00_SDKV35a/component/common/api/platform/stdlib_patch.c|RTL00_SDKV35a/component/common/network/sntp|RTL00_SDKV35a/component/common/api/network/src|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/gspi|RTL00_SDKV35a/component/common/drivers/ethernet_mii/ethernet_mii.c|RTL00_SDKV35a/component/common/drivers/i2s/alc5651.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/wifi_skbuf.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/rtl_consol.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU|project/src/user/main_tst.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c|RTL00_SDKV35a/component/common/network/ssl/polarssl-1.3.8|RTL00_SDKV35a/component/soc/realtek/8195a/misc/gcc_utility|RTL00_SDKV35a/component/common/api/wifi/rtw_wowlan/dev_wowlan.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c|project/src/mad/synth_mono.c|project/src/user/main1111.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.5.0.beta|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/src/apps|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|RTL00_SDKV35a/component/soc/realtek/8195a/misc/bsp/lib/common/IAR|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.3.2|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/IAR|RTL00_SDKV35a/component/os/rtx|RTL00_SDKV35a/component/common/file_system/fatfs/r0.10c/src/option|RTL00_SDKV35a/component/common/utilities|RTL00_SDKV35a/component/common/application|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c|RTL00_SDKV35a/component/common/example|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Demo|RTL00_SDKV35a/component/soc/realtek/8195a/misc/iar_utility|RTL00_SDKV35a/doc|RTL00_SDKV35a/example_sources|RTL00_SDKV35a/project|project/realtek_ameba1_va0_example/disasm_to_c_boot|component/soc/realtek/8195a/misc/gcc_utility|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F|doc|project/realtek_ameba1_va0_example/example_sources|build|project/realtek_ameba1_va0_example/GCC-RELEASE|component/common/network/lwip/lwip_v1.5.0.beta|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c|component1|component/common/network/lwip/lwip_v1.3.2|flasher|component/os/freertos/freertos_v8.1.2/Source/portable/IAR|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/os/freertos/freertos_v8.1.2/Demo|component/os/freertos/freertos_v8.1.2/Source/portable/RVDS|component/soc/realtek/8195a/misc/iar_utility|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c|tools|component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
<entry excluding="RTL00_SDKV35a/component/common/drivers/sdio/realtek/sdio_host/src|RTL00_SDKV35a/component/common/file_system/fatfs/disk_if/src/usbdisk.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/app_start.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/sdio|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/core/option|RTL00_SDKV35a/component/common/api/wifi/rtw_wpa_supplicant/src/utils|RTL00_SDKV35a/component/common/api/platform/stdlib_patch.c|RTL00_SDKV35a/component/common/network/sntp|RTL00_SDKV35a/component/common/api/network/src|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/gspi|RTL00_SDKV35a/component/common/drivers/ethernet_mii/ethernet_mii.c|RTL00_SDKV35a/component/common/drivers/i2s/alc5651.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/wifi_skbuf.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/rtl_consol.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU|project/src/user/main_tst.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_4.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_3.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_2.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_1.c|RTL00_SDKV35a/component/common/network/ssl/polarssl-1.3.8|RTL00_SDKV35a/component/soc/realtek/8195a/misc/gcc_utility|RTL00_SDKV35a/component/common/api/wifi/rtw_wowlan/dev_wowlan.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c|project/src/mad/synth_mono.c|project/src/user/main1111.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.5.0.beta|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/src/apps|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|RTL00_SDKV35a/component/soc/realtek/8195a/misc/bsp/lib/common/IAR|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.3.2|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/RVDS|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/IAR|RTL00_SDKV35a/component/os/rtx|RTL00_SDKV35a/component/common/file_system/fatfs/r0.10c/src/option|RTL00_SDKV35a/component/common/utilities|RTL00_SDKV35a/component/common/application|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c|RTL00_SDKV35a/component/common/example|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Demo|RTL00_SDKV35a/component/soc/realtek/8195a/misc/iar_utility|RTL00_SDKV35a/doc|RTL00_SDKV35a/example_sources|RTL00_SDKV35a/project|project/realtek_ameba1_va0_example/disasm_to_c_boot|component/soc/realtek/8195a/misc/gcc_utility|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_1.c|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F|doc|project/realtek_ameba1_va0_example/example_sources|build|project/realtek_ameba1_va0_example/GCC-RELEASE|component/common/network/lwip/lwip_v1.5.0.beta|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_4.c|component1|component/common/network/lwip/lwip_v1.3.2|flasher|component/os/freertos/freertos_v9.0.0/Source/portable/IAR|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/os/freertos/freertos_v9.0.0/Demo|component/os/freertos/freertos_v9.0.0/Source/portable/RVDS|component/soc/realtek/8195a/misc/iar_utility|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_3.c|tools|component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_2.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
@ -378,8 +378,8 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
||||||
|
@ -444,8 +444,8 @@
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/project/src/mad}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/common/bsp}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/os/os_dep/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/soc/realtek/8195a/misc/driver}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
||||||
|
@ -613,8 +613,8 @@
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="project/src/user/main_tst.c|project/src/mad/synth_mono.c|project/src/user/main1111.c|RTL00_SDKV35a|${ProjSDK}|project/realtek_ameba1_va0_example/disasm_to_c_boot|component/soc/realtek/8195a/misc/gcc_utility|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F|doc|project/realtek_ameba1_va0_example/example_sources|build|project/realtek_ameba1_va0_example/GCC-RELEASE|component/common/network/lwip/lwip_v1.5.0.beta|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c|component1|component/common/network/lwip/lwip_v1.3.2|flasher|component/os/freertos/freertos_v8.1.2/Source/portable/IAR|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/os/freertos/freertos_v8.1.2/Demo|component/os/freertos/freertos_v8.1.2/Source/portable/RVDS|component/soc/realtek/8195a/misc/iar_utility|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c|tools|component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
<entry excluding="project/src/user/main_tst.c|project/src/mad/synth_mono.c|project/src/user/main1111.c|RTL00_SDKV35a|${ProjSDK}|project/realtek_ameba1_va0_example/disasm_to_c_boot|component/soc/realtek/8195a/misc/gcc_utility|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_1.c|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F|doc|project/realtek_ameba1_va0_example/example_sources|build|project/realtek_ameba1_va0_example/GCC-RELEASE|component/common/network/lwip/lwip_v1.5.0.beta|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_4.c|component1|component/common/network/lwip/lwip_v1.3.2|flasher|component/os/freertos/freertos_v9.0.0/Source/portable/IAR|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/os/freertos/freertos_v9.0.0/Demo|component/os/freertos/freertos_v9.0.0/Source/portable/RVDS|component/soc/realtek/8195a/misc/iar_utility|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_3.c|tools|component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_2.c" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
|
||||||
<entry excluding="component/common/drivers/sdio/realtek/sdio_host/src|component/common/file_system/fatfs/disk_if/src/usbdisk.c|component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c|component/soc/realtek/8195a/cmsis/device/app_start.c|component/common/drivers/wlan/realtek/src/hci/sdio|component/common/drivers/wlan/realtek/src/core/option|component/common/api/wifi/rtw_wpa_supplicant/src/utils|component/common/api/platform/stdlib_patch.c|component/common/network/sntp|component/common/api/network/src|component/common/drivers/wlan/realtek/src/hci/gspi|component/common/drivers/ethernet_mii/ethernet_mii.c|component/common/drivers/i2s/alc5651.c|component/common/drivers/wlan/realtek/src/wifi_skbuf.c|component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c|component/soc/realtek/8195a/misc/driver/rtl_consol.c|component/soc/realtek/8195a/misc/driver/low_level_io.c|component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c|component/common/network/ssl/polarssl-1.3.8|component/soc/realtek/8195a/misc/gcc_utility|component/common/api/wifi/rtw_wowlan/dev_wowlan.c|component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c|component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c|component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c|component/common/network/lwip/lwip_v1.5.0.beta|component/common/network/lwip/lwip_v1.4.1/src/apps|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/soc/realtek/8195a/misc/bsp/lib/common/IAR|component/common/network/lwip/lwip_v1.3.2|component/os/freertos/freertos_v8.1.2/Source/portable/RVDS|component/os/freertos/freertos_v8.1.2/Source/portable/IAR|component/os/rtx|component/common/file_system/fatfs/r0.10c/src/option|component/common/utilities|component/common/application|component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c|component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c|component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c|component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c|component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c|component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c|component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c|component/common/example|component/os/freertos/freertos_v8.1.2/Demo|component/soc/realtek/8195a/misc/iar_utility|doc|example_sources|.git/|.settings/|AutoMake/|build/|flasher/|LibAutoMake/|project/" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="RTL00_SDKV35a"/>
|
<entry excluding="component/common/drivers/sdio/realtek/sdio_host/src|component/common/file_system/fatfs/disk_if/src/usbdisk.c|component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c|component/soc/realtek/8195a/cmsis/device/app_start.c|component/common/drivers/wlan/realtek/src/hci/sdio|component/common/drivers/wlan/realtek/src/core/option|component/common/api/wifi/rtw_wpa_supplicant/src/utils|component/common/api/platform/stdlib_patch.c|component/common/network/sntp|component/common/api/network/src|component/common/drivers/wlan/realtek/src/hci/gspi|component/common/drivers/ethernet_mii/ethernet_mii.c|component/common/drivers/i2s/alc5651.c|component/common/drivers/wlan/realtek/src/wifi_skbuf.c|component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c|component/soc/realtek/8195a/misc/driver/rtl_consol.c|component/soc/realtek/8195a/misc/driver/low_level_io.c|component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_4.c|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_3.c|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_2.c|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_1.c|component/common/network/ssl/polarssl-1.3.8|component/soc/realtek/8195a/misc/gcc_utility|component/common/api/wifi/rtw_wowlan/dev_wowlan.c|component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c|component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c|component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c|component/common/network/lwip/lwip_v1.5.0.beta|component/common/network/lwip/lwip_v1.4.1/src/apps|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/soc/realtek/8195a/misc/bsp/lib/common/IAR|component/common/network/lwip/lwip_v1.3.2|component/os/freertos/freertos_v9.0.0/Source/portable/RVDS|component/os/freertos/freertos_v9.0.0/Source/portable/IAR|component/os/rtx|component/common/file_system/fatfs/r0.10c/src/option|component/common/utilities|component/common/application|component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c|component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c|component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c|component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c|component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c|component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c|component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c|component/common/example|component/os/freertos/freertos_v9.0.0/Demo|component/soc/realtek/8195a/misc/iar_utility|doc|example_sources|.git/|.settings/|AutoMake/|build/|flasher/|LibAutoMake/|project/" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="RTL00_SDKV35a"/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
@ -797,7 +797,7 @@
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="RTL00_SDKV35a/component/common/drivers/sdio/realtek/sdio_host/src|RTL00_SDKV35a/component/common/file_system/fatfs/disk_if/src/usbdisk.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/app_start.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/sdio|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/core/option|RTL00_SDKV35a/component/common/api/wifi/rtw_wpa_supplicant/src/utils|RTL00_SDKV35a/component/common/api/platform/stdlib_patch.c|RTL00_SDKV35a/component/common/network/sntp|RTL00_SDKV35a/component/common/api/network/src|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/gspi|RTL00_SDKV35a/component/common/drivers/ethernet_mii/ethernet_mii.c|RTL00_SDKV35a/component/common/drivers/i2s/alc5651.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/wifi_skbuf.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/rtl_consol.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU|project/src/user/main_tst.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c|RTL00_SDKV35a/component/common/network/ssl/polarssl-1.3.8|RTL00_SDKV35a/component/soc/realtek/8195a/misc/gcc_utility|RTL00_SDKV35a/component/common/api/wifi/rtw_wowlan/dev_wowlan.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c|project/src/mad/synth_mono.c|project/src/user/main1111.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.5.0.beta|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/src/apps|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|RTL00_SDKV35a/component/soc/realtek/8195a/misc/bsp/lib/common/IAR|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.3.2|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Source/portable/IAR|RTL00_SDKV35a/component/os/rtx|RTL00_SDKV35a/component/common/file_system/fatfs/r0.10c/src/option|RTL00_SDKV35a/component/common/utilities|RTL00_SDKV35a/component/common/application|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c|RTL00_SDKV35a/component/common/example|RTL00_SDKV35a/component/os/freertos/freertos_v8.1.2/Demo|RTL00_SDKV35a/component/soc/realtek/8195a/misc/iar_utility|RTL00_SDKV35a/doc|RTL00_SDKV35a/example_sources|RTL00_SDKV35a/project|project/realtek_ameba1_va0_example/disasm_to_c_boot|component/soc/realtek/8195a/misc/gcc_utility|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F|doc|project/realtek_ameba1_va0_example/example_sources|build|project/realtek_ameba1_va0_example/GCC-RELEASE|component/common/network/lwip/lwip_v1.5.0.beta|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c|component1|component/common/network/lwip/lwip_v1.3.2|flasher|component/os/freertos/freertos_v8.1.2/Source/portable/IAR|component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/os/freertos/freertos_v8.1.2/Demo|component/os/freertos/freertos_v8.1.2/Source/portable/RVDS|component/soc/realtek/8195a/misc/iar_utility|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c|tools|component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c|component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
<entry excluding="RTL00_SDKV35a/component/common/drivers/sdio/realtek/sdio_host/src|RTL00_SDKV35a/component/common/file_system/fatfs/disk_if/src/usbdisk.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c|RTL00_SDKV35a/component/soc/realtek/8195a/cmsis/device/app_start.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/sdio|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/core/option|RTL00_SDKV35a/component/common/api/wifi/rtw_wpa_supplicant/src/utils|RTL00_SDKV35a/component/common/api/platform/stdlib_patch.c|RTL00_SDKV35a/component/common/network/sntp|RTL00_SDKV35a/component/common/api/network/src|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/hci/gspi|RTL00_SDKV35a/component/common/drivers/ethernet_mii/ethernet_mii.c|RTL00_SDKV35a/component/common/drivers/i2s/alc5651.c|RTL00_SDKV35a/component/common/drivers/wlan/realtek/src/wifi_skbuf.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/rtl_consol.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/driver/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU|project/src/user/main_tst.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_4.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_3.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_2.c|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_1.c|RTL00_SDKV35a/component/common/network/ssl/polarssl-1.3.8|RTL00_SDKV35a/component/soc/realtek/8195a/misc/gcc_utility|RTL00_SDKV35a/component/common/api/wifi/rtw_wowlan/dev_wowlan.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c|project/src/mad/synth_mono.c|project/src/user/main1111.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.5.0.beta|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/src/apps|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|RTL00_SDKV35a/component/soc/realtek/8195a/misc/bsp/lib/common/IAR|RTL00_SDKV35a/component/common/network/lwip/lwip_v1.3.2|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/RVDS|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Source/portable/IAR|RTL00_SDKV35a/component/os/rtx|RTL00_SDKV35a/component/common/file_system/fatfs/r0.10c/src/option|RTL00_SDKV35a/component/common/utilities|RTL00_SDKV35a/component/common/application|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c|RTL00_SDKV35a/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c|RTL00_SDKV35a/component/common/example|RTL00_SDKV35a/component/os/freertos/freertos_v9.0.0/Demo|RTL00_SDKV35a/component/soc/realtek/8195a/misc/iar_utility|RTL00_SDKV35a/doc|RTL00_SDKV35a/example_sources|RTL00_SDKV35a/project|project/realtek_ameba1_va0_example/disasm_to_c_boot|component/soc/realtek/8195a/misc/gcc_utility|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_1.c|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F|doc|project/realtek_ameba1_va0_example/example_sources|build|project/realtek_ameba1_va0_example/GCC-RELEASE|component/common/network/lwip/lwip_v1.5.0.beta|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_4.c|component1|component/common/network/lwip/lwip_v1.3.2|flasher|component/os/freertos/freertos_v9.0.0/Source/portable/IAR|component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU|component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7|component/os/freertos/freertos_v9.0.0/Demo|component/os/freertos/freertos_v9.0.0/Source/portable/RVDS|component/soc/realtek/8195a/misc/iar_utility|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_3.c|tools|component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c|component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_2.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|
35
Makefile
35
Makefile
|
@ -1,50 +1,39 @@
|
||||||
|
include userset.mk
|
||||||
|
|
||||||
all: ram_all
|
all: ram_all
|
||||||
mp: ram_all_mp
|
mp: ram_all_mp
|
||||||
|
|
||||||
.PHONY: ram_all
|
.PHONY: ram_all
|
||||||
ram_all:
|
ram_all:
|
||||||
@$(MAKE) -f sdkbuild.mk
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk
|
||||||
@$(MAKE) -f flasher.mk genbin1 genbin23
|
@$(MAKE) -f $(SDK_PATH)flasher.mk genbin1 genbin23
|
||||||
|
|
||||||
.PHONY: ram_all_mp
|
.PHONY: ram_all_mp
|
||||||
ram_all_mp:
|
ram_all_mp:
|
||||||
@$(MAKE) -f sdkbuild.mk mp
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk mp
|
||||||
@$(MAKE) -f flasher.mk mp
|
@$(MAKE) -f $(SDK_PATH)flasher.mk mp
|
||||||
|
|
||||||
.PHONY: clean clean_all
|
.PHONY: clean clean_all
|
||||||
clean:
|
clean:
|
||||||
@$(MAKE) -f sdkbuild.mk clean
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk clean
|
||||||
|
|
||||||
clean_all:
|
clean_all:
|
||||||
@$(MAKE) -f sdkbuild.mk clean_all
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk clean_all
|
||||||
|
|
||||||
.PHONY: flashburn runram reset test readfullflash flashwebfs
|
.PHONY: flashburn runram reset test readfullflash flashwebfs
|
||||||
flashburn:
|
flashburn:
|
||||||
#JLinkGDB-WrFlash.bat
|
@$(MAKE) -f $(SDK_PATH)flasher.mk flashburn
|
||||||
@$(MAKE) -f flasher.mk flashburn
|
|
||||||
|
|
||||||
flash_OTA:
|
flash_OTA:
|
||||||
@$(MAKE) -f flasher.mk flash_OTA
|
@$(MAKE) -f $(SDK_PATH)flasher.mk flash_OTA
|
||||||
|
|
||||||
|
|
||||||
runram:
|
runram:
|
||||||
#JLink-RunRAM.bat
|
@$(MAKE) --f $(SDK_PATH)flasher.mk runram
|
||||||
@$(MAKE) --f flasher.mk runram
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
#JLink-Reset.bat
|
@$(MAKE) -f $(SDK_PATH)flasher.mk reset
|
||||||
@$(MAKE) -f flasher.mk reset
|
|
||||||
|
|
||||||
test:
|
|
||||||
JLink-RTL00ConsoleROM.bat
|
|
||||||
#@make -f flasher.mk test
|
|
||||||
|
|
||||||
readfullflash:
|
readfullflash:
|
||||||
#JLink-RdFullFlash.bat
|
@$(MAKE) -f $(SDK_PATH)flasher.mk readfullflash
|
||||||
@$(MAKE) -f flasher.mk readfullflash
|
|
||||||
|
|
||||||
.PHONY: prerequirement
|
|
||||||
prerequirement:
|
|
||||||
@$(file >DEPENDENCY_LIST.txt,$(DEPENDENCY_LIST))
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# RTL00(RTL8710AF) Test MP3 SDK V3.5.1 GCC
|
# RTL00(RTL8710AF) Test MP3 SDK V3.5.2 GCC
|
||||||
---
|
---
|
||||||
|
|
||||||
MP3 stereo player V0004<br>
|
MP3 stereo player V0004<br>
|
||||||
|
|
39
RTL00_SDKV35a/Makefile
Normal file
39
RTL00_SDKV35a/Makefile
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
include userset.mk
|
||||||
|
|
||||||
|
all: ram_all
|
||||||
|
mp: ram_all_mp
|
||||||
|
|
||||||
|
.PHONY: ram_all
|
||||||
|
ram_all:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk
|
||||||
|
@$(MAKE) -f $(SDK_PATH)flasher.mk genbin1 genbin23
|
||||||
|
|
||||||
|
.PHONY: ram_all_mp
|
||||||
|
ram_all_mp:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk mp
|
||||||
|
@$(MAKE) -f $(SDK_PATH)flasher.mk mp
|
||||||
|
|
||||||
|
.PHONY: clean clean_all
|
||||||
|
clean:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk clean
|
||||||
|
|
||||||
|
clean_all:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)sdkbuild.mk clean_all
|
||||||
|
|
||||||
|
.PHONY: flashburn runram reset test readfullflash flashwebfs
|
||||||
|
flashburn:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)flasher.mk flashburn
|
||||||
|
|
||||||
|
flash_OTA:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)flasher.mk flash_OTA
|
||||||
|
|
||||||
|
|
||||||
|
runram:
|
||||||
|
@$(MAKE) --f $(SDK_PATH)flasher.mk runram
|
||||||
|
|
||||||
|
reset:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)flasher.mk reset
|
||||||
|
|
||||||
|
readfullflash:
|
||||||
|
@$(MAKE) -f $(SDK_PATH)flasher.mk readfullflash
|
||||||
|
|
|
@ -510,7 +510,7 @@ void fATWx(void *arg){
|
||||||
printf("\tMAC => "MAC_FMT"\n",
|
printf("\tMAC => "MAC_FMT"\n",
|
||||||
MAC_ARG(client_info.mac_list[client_number].octet));
|
MAC_ARG(client_info.mac_list[client_number].octet));
|
||||||
#if CONFIG_EXAMPLE_UART_ATCMD
|
#if CONFIG_EXAMPLE_UART_ATCMD
|
||||||
at_printf("CLIENT : %d,"MAC_FMT"\n", client_number + 1, MAC_ARG(client_info.mac_list[client_number].octet));
|
at_printf("CLIENT:%d,"MAC_FMT"\n", client_number + 1, MAC_ARG(client_info.mac_list[client_number].octet));
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_INIC_CMD_RSP
|
#if CONFIG_INIC_CMD_RSP
|
||||||
if(info){
|
if(info){
|
||||||
|
|
|
@ -438,7 +438,7 @@ void start_log_service(void)
|
||||||
xTaskHandle CreatedTask;
|
xTaskHandle CreatedTask;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
#if CONFIG_USE_TCM_HEAP
|
#if 0 // CONFIG_USE_TCM_HEAP
|
||||||
extern void *tcm_heap_malloc(int size);
|
extern void *tcm_heap_malloc(int size);
|
||||||
void *stack_addr = tcm_heap_malloc(STACKSIZE * sizeof(int));
|
void *stack_addr = tcm_heap_malloc(STACKSIZE * sizeof(int));
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ void start_log_service(void)
|
||||||
|
|
||||||
result = xTaskGenericCreate(
|
result = xTaskGenericCreate(
|
||||||
log_service,
|
log_service,
|
||||||
( signed portCHAR * ) "log_service",
|
( signed portCHAR * ) "log_srv",
|
||||||
STACKSIZE,
|
STACKSIZE,
|
||||||
NULL,
|
NULL,
|
||||||
tskIDLE_PRIORITY + 5,
|
tskIDLE_PRIORITY + 5,
|
||||||
|
@ -455,7 +455,7 @@ void start_log_service(void)
|
||||||
stack_addr,
|
stack_addr,
|
||||||
NULL);
|
NULL);
|
||||||
#else
|
#else
|
||||||
result = xTaskCreate( log_service, ( signed portCHAR * ) "log_service", STACKSIZE, NULL, tskIDLE_PRIORITY + 5, &CreatedTask );
|
result = xTaskCreate( log_service, ( signed portCHAR * ) "log_srv", STACKSIZE, NULL, tskIDLE_PRIORITY + 5, &CreatedTask );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(result != pdPASS) {
|
if(result != pdPASS) {
|
||||||
|
|
|
@ -81,13 +81,11 @@ int wifi_start_p2p_go(char *ssid, char *passphrase, u8 channel)
|
||||||
netif_set_addr(pnetif, &ipaddr, &netmask,&gw);
|
netif_set_addr(pnetif, &ipaddr, &netmask,&gw);
|
||||||
|
|
||||||
// start ap
|
// start ap
|
||||||
if(wifi_start_ap(ssid,
|
if(wifi_start_ap( ssid,
|
||||||
RTW_SECURITY_WPA2_AES_PSK,
|
RTW_SECURITY_WPA2_AES_PSK,
|
||||||
passphrase,
|
passphrase,
|
||||||
strlen(ssid),
|
channel,
|
||||||
strlen(passphrase),
|
0) != RTW_SUCCESS) {
|
||||||
channel
|
|
||||||
) != RTW_SUCCESS) {
|
|
||||||
printf("ERROR: Operation failed!\n");
|
printf("ERROR: Operation failed!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,6 +342,7 @@ static int wps_connect_to_AP_by_open_system(char *target_ssid)
|
||||||
0,
|
0,
|
||||||
target_ssid,
|
target_ssid,
|
||||||
RTW_SECURITY_OPEN,
|
RTW_SECURITY_OPEN,
|
||||||
|
NULL,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
if (ret == RTW_SUCCESS) {
|
if (ret == RTW_SUCCESS) {
|
||||||
|
|
|
@ -1378,13 +1378,13 @@ int wifi_show_setting(const char *ifname, rtw_wifi_setting_t *pSetting) {
|
||||||
switch (pSetting->mode) {
|
switch (pSetting->mode) {
|
||||||
case RTW_MODE_AP:
|
case RTW_MODE_AP:
|
||||||
#if CONFIG_EXAMPLE_UART_ATCMD
|
#if CONFIG_EXAMPLE_UART_ATCMD
|
||||||
at_printf("AP,");
|
at_printf("AP:");
|
||||||
#endif
|
#endif
|
||||||
printf("\tMODE => AP\n");
|
printf("\tMODE => AP\n");
|
||||||
break;
|
break;
|
||||||
case RTW_MODE_STA:
|
case RTW_MODE_STA:
|
||||||
#if CONFIG_EXAMPLE_UART_ATCMD
|
#if CONFIG_EXAMPLE_UART_ATCMD
|
||||||
at_printf("STA,");
|
at_printf("STA:");
|
||||||
#endif
|
#endif
|
||||||
printf("\tMODE => STATION\n");
|
printf("\tMODE => STATION\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -109,7 +109,9 @@
|
||||||
|
|
||||||
#if defined(CONFIG_PLATFORM_AMEBA_X)
|
#if defined(CONFIG_PLATFORM_AMEBA_X)
|
||||||
#if !defined(CONFIG_PLATFORM_8711B)
|
#if !defined(CONFIG_PLATFORM_8711B)
|
||||||
|
#ifndef CONFIG_USE_TCM_HEAP
|
||||||
#define CONFIG_USE_TCM_HEAP 1 /* USE TCM HEAP */
|
#define CONFIG_USE_TCM_HEAP 1 /* USE TCM HEAP */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define CONFIG_RECV_TASKLET_THREAD
|
#define CONFIG_RECV_TASKLET_THREAD
|
||||||
#define CONFIG_XMIT_TASKLET_THREAD
|
#define CONFIG_XMIT_TASKLET_THREAD
|
||||||
|
|
|
@ -88,7 +88,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||||
i2c_sel = (uint32_t)pinmap_merge(i2c_sda, i2c_scl);
|
i2c_sel = (uint32_t)pinmap_merge(i2c_sda, i2c_scl);
|
||||||
i2c_idx = RTL_GET_PERI_IDX(i2c_sel);
|
i2c_idx = RTL_GET_PERI_IDX(i2c_sel);
|
||||||
if (unlikely(i2c_idx == NC)) {
|
if (unlikely(i2c_idx == NC)) {
|
||||||
DBG_8195A("%s: Cannot find matched UART\n", __FUNCTION__);
|
DBG_8195A("%s: Cannot find matched port i2c\n", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,6 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
|
||||||
|
|
||||||
pSalI2CMngtAdpt->InnerTimeOut = pSalI2CHND->TimeOut;
|
pSalI2CMngtAdpt->InnerTimeOut = pSalI2CHND->TimeOut;
|
||||||
|
|
||||||
|
|
||||||
/* Deinit I2C first */
|
/* Deinit I2C first */
|
||||||
//i2c_reset(obj);
|
//i2c_reset(obj);
|
||||||
|
|
||||||
|
@ -200,8 +199,6 @@ void i2c_frequency(i2c_t *obj, int hz) {
|
||||||
|
|
||||||
uint16_t i2c_default_clk = (uint16_t) pSalI2CHND->I2CClk;
|
uint16_t i2c_default_clk = (uint16_t) pSalI2CHND->I2CClk;
|
||||||
uint16_t i2c_user_clk = (uint16_t) (hz/1000);
|
uint16_t i2c_user_clk = (uint16_t) (hz/1000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (i2c_default_clk != i2c_user_clk) {
|
if (i2c_default_clk != i2c_user_clk) {
|
||||||
/* Deinit I2C first */
|
/* Deinit I2C first */
|
||||||
|
|
|
@ -443,6 +443,7 @@ void sys_mutex_unlock(sys_mutex_t *mutex)
|
||||||
thread() function. The id of the new thread is returned. Both the id and
|
thread() function. The id of the new thread is returned. Both the id and
|
||||||
the priority are system dependent.
|
the priority are system dependent.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
|
sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio)
|
||||||
{
|
{
|
||||||
xTaskHandle CreatedTask;
|
xTaskHandle CreatedTask;
|
||||||
|
@ -455,9 +456,6 @@ int result;
|
||||||
{
|
{
|
||||||
void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int));
|
void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int));
|
||||||
|
|
||||||
if(stack_addr == NULL){
|
|
||||||
}
|
|
||||||
|
|
||||||
result = xTaskGenericCreate(
|
result = xTaskGenericCreate(
|
||||||
thread,
|
thread,
|
||||||
( signed portCHAR * ) name,
|
( signed portCHAR * ) name,
|
||||||
|
@ -491,6 +489,7 @@ int result;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
// TODO
|
// TODO
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -472,7 +472,7 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg)
|
||||||
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
|
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
#if CONFIG_USE_TCM_HEAP
|
#if 0 // CONFIG_USE_TCM_HEAP
|
||||||
sys_thread_new_tcm(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
sys_thread_new_tcm(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
||||||
#else
|
#else
|
||||||
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
||||||
|
|
|
@ -222,7 +222,7 @@ void sys_mbox_set_invalid(sys_mbox_t *mbox);
|
||||||
* @param stacksize stack size in bytes for the new thread (may be ignored by ports)
|
* @param stacksize stack size in bytes for the new thread (may be ignored by ports)
|
||||||
* @param prio priority of the new thread (may be ignored by ports) */
|
* @param prio priority of the new thread (may be ignored by ports) */
|
||||||
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio);
|
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio);
|
||||||
sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio);
|
//sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio);
|
||||||
|
|
||||||
#endif /* NO_SYS */
|
#endif /* NO_SYS */
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ static void tcpecho_thread(void *arg)
|
||||||
|
|
||||||
void tcpecho_init(void)
|
void tcpecho_init(void)
|
||||||
{
|
{
|
||||||
sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPECHO_THREAD_PRIO);
|
sys_thread_new("tcpecho", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPECHO_THREAD_PRIO);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ static void udpecho_thread(void *arg)
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void udpecho_init(void)
|
void udpecho_init(void)
|
||||||
{
|
{
|
||||||
sys_thread_new("udpecho_thread", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE,UDPECHO_THREAD_PRIO );
|
sys_thread_new("udpecho", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE,UDPECHO_THREAD_PRIO );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LWIP_NETCONN */
|
#endif /* LWIP_NETCONN */
|
||||||
|
|
|
@ -544,7 +544,7 @@ static int _freertos_create_task(struct task_struct *ptask, const char *name,
|
||||||
|
|
||||||
priority += tskIDLE_PRIORITY + PRIORITIE_OFFSET;
|
priority += tskIDLE_PRIORITY + PRIORITIE_OFFSET;
|
||||||
|
|
||||||
#if CONFIG_USE_TCM_HEAP
|
#if 0 // CONFIG_USE_TCM_HEAP
|
||||||
void *stack_addr = tcm_heap_malloc(stack_size*sizeof(int));
|
void *stack_addr = tcm_heap_malloc(stack_size*sizeof(int));
|
||||||
//void *stack_addr = rtw_malloc(stack_size*sizeof(int));
|
//void *stack_addr = rtw_malloc(stack_size*sizeof(int));
|
||||||
if(stack_addr == NULL){
|
if(stack_addr == NULL){
|
||||||
|
|
|
@ -90,9 +90,27 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PLATFORM_AUTOCONFIG_H_
|
||||||
|
#include "platform_autoconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Application specific configuration options. */
|
/* Application specific configuration options. */
|
||||||
#include "FreeRTOSConfig.h"
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
//-----------
|
||||||
|
#if defined(CONFIG_PLATFORM_8195A)
|
||||||
|
#ifndef CONFIG_USE_TCM_HEAP
|
||||||
|
#define CONFIG_USE_TCM_HEAP 1
|
||||||
|
#endif
|
||||||
|
#ifndef configUSE_STACK_TCM_HEAP
|
||||||
|
#define configUSE_STACK_TCM_HEAP 5 // min priority use tcm
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#undef configUSE_STACK_TCM_HEAP
|
||||||
|
#define configUSE_STACK_TCM_HEAP 0
|
||||||
|
#endif
|
||||||
|
//-----------
|
||||||
|
|
||||||
/* Basic FreeRTOS definitions. */
|
/* Basic FreeRTOS definitions. */
|
||||||
#include "projdefs.h"
|
#include "projdefs.h"
|
||||||
|
|
||||||
|
|
|
@ -724,12 +724,18 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||||
#endif /* configASSERT_DEFINED */
|
#endif /* configASSERT_DEFINED */
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
#if configUSE_IDLE_HOOK
|
||||||
void vApplicationIdleHook( void )
|
void vApplicationIdleHook( void )
|
||||||
{
|
{
|
||||||
/* Use the idle task to place the CPU into a low power mode. Greater power
|
/* Use the idle task to place the CPU into a low power mode. Greater power
|
||||||
saving could be achieved by not including any demo tasks that never block. */
|
saving could be achieved by not including any demo tasks that never block. */
|
||||||
|
#ifdef CONFIG_WDG_ON_IDLE
|
||||||
|
WDGRefresh();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configCHECK_FOR_STACK_OVERFLOW
|
||||||
#include "diag.h"
|
#include "diag.h"
|
||||||
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
|
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
|
||||||
{
|
{
|
||||||
|
@ -741,6 +747,6 @@ void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName
|
||||||
DiagPrintf("\n[%s] STACK OVERFLOW - TaskName(%s)\n", __FUNCTION__, pcTaskName);
|
DiagPrintf("\n[%s] STACK OVERFLOW - TaskName(%s)\n", __FUNCTION__, pcTaskName);
|
||||||
for( ;; );
|
for( ;; );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -530,7 +530,14 @@ static void prvResetNextTaskUnblockTime( void );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode,
|
||||||
|
const char * const pcName,
|
||||||
|
const uint16_t usStackDepth,
|
||||||
|
void * const pvParameters,
|
||||||
|
UBaseType_t uxPriority,
|
||||||
|
TaskHandle_t * const pxCreatedTask,
|
||||||
|
StackType_t * const puxStackBuffer,
|
||||||
|
const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
TCB_t * pxNewTCB;
|
TCB_t * pxNewTCB;
|
||||||
|
@ -1704,11 +1711,11 @@ TickType_t xTaskGetTickCount( void )
|
||||||
TickType_t xTicks;
|
TickType_t xTicks;
|
||||||
|
|
||||||
/* Critical section required if running on a 16 bit processor. */
|
/* Critical section required if running on a 16 bit processor. */
|
||||||
taskENTER_CRITICAL();
|
// taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
xTicks = xTickCount;
|
xTicks = xTickCount;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
// taskEXIT_CRITICAL();
|
||||||
|
|
||||||
return xTicks;
|
return xTicks;
|
||||||
}
|
}
|
||||||
|
@ -2753,9 +2760,6 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
||||||
{
|
{
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_WDG_ON_IDLE
|
|
||||||
WDGRefresh();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* configUSE_TICKLESS_IDLE */
|
#endif /* configUSE_TICKLESS_IDLE */
|
||||||
}
|
}
|
||||||
|
@ -3019,7 +3023,6 @@ static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
|
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
|
||||||
{
|
{
|
||||||
TCB_t *pxNewTCB;
|
TCB_t *pxNewTCB;
|
||||||
|
@ -3033,12 +3036,12 @@ TCB_t *pxNewTCB;
|
||||||
/* Allocate space for the stack used by the task being created.
|
/* Allocate space for the stack used by the task being created.
|
||||||
The base of the stack memory stored in the TCB so the task can
|
The base of the stack memory stored in the TCB so the task can
|
||||||
be deleted later if required. */
|
be deleted later if required. */
|
||||||
//pvvx
|
#if configUSE_STACK_TCM_HEAP
|
||||||
#if CONFIG_USE_TCM_HEAP
|
|
||||||
if(puxStackBuffer == NULL) {
|
if(puxStackBuffer == NULL) {
|
||||||
pxNewTCB->pxStack = ( StackType_t * ) tcm_heap_malloc((( size_t ) puxStackBuffer) * sizeof(StackType_t));
|
pxNewTCB->pxStack = ( StackType_t * ) tcm_heap_malloc((( size_t ) usStackDepth) * sizeof(StackType_t));
|
||||||
if(pxNewTCB->pxStack == NULL) pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc((( size_t ) puxStackBuffer) * sizeof(StackType_t));
|
if(pxNewTCB->pxStack == NULL) pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc((( size_t ) usStackDepth) * sizeof(StackType_t));
|
||||||
}
|
}
|
||||||
|
else pxNewTCB->pxStack = puxStackBuffer;
|
||||||
#else
|
#else
|
||||||
pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,350 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates six tasks that operate on three queues as follows:
|
||||||
|
*
|
||||||
|
* The first two tasks send and receive an incrementing number to/from a queue.
|
||||||
|
* One task acts as a producer and the other as the consumer. The consumer is a
|
||||||
|
* higher priority than the producer and is set to block on queue reads. The queue
|
||||||
|
* only has space for one item - as soon as the producer posts a message on the
|
||||||
|
* queue the consumer will unblock, pre-empt the producer, and remove the item.
|
||||||
|
*
|
||||||
|
* The second two tasks work the other way around. Again the queue used only has
|
||||||
|
* enough space for one item. This time the consumer has a lower priority than the
|
||||||
|
* producer. The producer will try to post on the queue blocking when the queue is
|
||||||
|
* full. When the consumer wakes it will remove the item from the queue, causing
|
||||||
|
* the producer to unblock, pre-empt the consumer, and immediately re-fill the
|
||||||
|
* queue.
|
||||||
|
*
|
||||||
|
* The last two tasks use the same queue producer and consumer functions. This time the queue has
|
||||||
|
* enough space for lots of items and the tasks operate at the same priority. The
|
||||||
|
* producer will execute, placing items into the queue. The consumer will start
|
||||||
|
* executing when either the queue becomes full (causing the producer to block) or
|
||||||
|
* a context switch occurs (tasks of the same priority will time slice).
|
||||||
|
*
|
||||||
|
* \page BlockQC blockQ.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.00:
|
||||||
|
|
||||||
|
+ Reversed the priority and block times of the second two demo tasks so
|
||||||
|
they operate as per the description above.
|
||||||
|
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
|
||||||
|
Changes from V4.0.2
|
||||||
|
|
||||||
|
+ The second set of tasks were created the wrong way around. This has been
|
||||||
|
corrected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "BlockQ.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
#define blckqSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE )
|
||||||
|
#define blckqNUM_TASK_SETS ( 3 )
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to the blocking queue tasks. */
|
||||||
|
typedef struct BLOCKING_QUEUE_PARAMETERS
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue; /*< The queue to be used by the task. */
|
||||||
|
TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */
|
||||||
|
volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */
|
||||||
|
} xBlockingQueueParameters;
|
||||||
|
|
||||||
|
/* Task function that creates an incrementing number and posts it on a queue. */
|
||||||
|
static void vBlockingQueueProducer( void *pvParameters );
|
||||||
|
|
||||||
|
/* Task function that removes the incrementing number from a queue and checks that
|
||||||
|
it is the expected number. */
|
||||||
|
static void vBlockingQueueConsumer( void *pvParameters );
|
||||||
|
|
||||||
|
/* Variables which are incremented each time an item is removed from a queue, and
|
||||||
|
found to be the expected value.
|
||||||
|
These are used to check that the tasks are still running. */
|
||||||
|
static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 };
|
||||||
|
|
||||||
|
/* Variable which are incremented each time an item is posted on a queue. These
|
||||||
|
are used to check that the tasks are still running. */
|
||||||
|
static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 };
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
|
||||||
|
const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5;
|
||||||
|
const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS;
|
||||||
|
const TickType_t xDontBlock = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Create the first two tasks as described at the top of the file. */
|
||||||
|
|
||||||
|
/* First create the structure used to pass parameters to the consumer tasks. */
|
||||||
|
pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
|
||||||
|
/* Create the queue used by the first two tasks to pass the incrementing number.
|
||||||
|
Pass a pointer to the queue in the parameter structure. */
|
||||||
|
pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
|
||||||
|
|
||||||
|
/* The consumer is created first so gets a block time as described above. */
|
||||||
|
pxQueueParameters1->xBlockTime = xBlockTime;
|
||||||
|
|
||||||
|
/* Pass in the variable that this task is going to increment so we can check it
|
||||||
|
is still running. */
|
||||||
|
pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] );
|
||||||
|
|
||||||
|
/* Create the structure used to pass parameters to the producer task. */
|
||||||
|
pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
|
||||||
|
/* Pass the queue to this task also, using the parameter structure. */
|
||||||
|
pxQueueParameters2->xQueue = pxQueueParameters1->xQueue;
|
||||||
|
|
||||||
|
/* The producer is not going to block - as soon as it posts the consumer will
|
||||||
|
wake and remove the item so the producer should always have room to post. */
|
||||||
|
pxQueueParameters2->xBlockTime = xDontBlock;
|
||||||
|
|
||||||
|
/* Pass in the variable that this task is going to increment so we can check
|
||||||
|
it is still running. */
|
||||||
|
pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] );
|
||||||
|
|
||||||
|
|
||||||
|
/* Note the producer has a lower priority than the consumer when the tasks are
|
||||||
|
spawned. */
|
||||||
|
xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );
|
||||||
|
xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the second two tasks as described at the top of the file. This uses
|
||||||
|
the same mechanism but reverses the task priorities. */
|
||||||
|
|
||||||
|
pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
|
||||||
|
pxQueueParameters3->xBlockTime = xDontBlock;
|
||||||
|
pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] );
|
||||||
|
|
||||||
|
pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters4->xQueue = pxQueueParameters3->xQueue;
|
||||||
|
pxQueueParameters4->xBlockTime = xBlockTime;
|
||||||
|
pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] );
|
||||||
|
|
||||||
|
xTaskCreate( vBlockingQueueProducer, "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vBlockingQueueConsumer, "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the last two tasks as described above. The mechanism is again just
|
||||||
|
the same. This time both parameter structures are given a block time. */
|
||||||
|
pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
|
||||||
|
pxQueueParameters5->xBlockTime = xBlockTime;
|
||||||
|
pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] );
|
||||||
|
|
||||||
|
pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters6->xQueue = pxQueueParameters5->xQueue;
|
||||||
|
pxQueueParameters6->xBlockTime = xBlockTime;
|
||||||
|
pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] );
|
||||||
|
|
||||||
|
xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vBlockingQueueProducer( void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned short usValue = 0;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters;
|
||||||
|
const char * const pcTaskStartMsg = "Blocking queue producer started.\r\n";
|
||||||
|
const char * const pcTaskErrorMsg = "Could not post on blocking queue\r\n";
|
||||||
|
short sErrorEverOccurred = pdFALSE;
|
||||||
|
|
||||||
|
pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xQueueSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskErrorMsg );
|
||||||
|
sErrorEverOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have successfully posted a message, so increment the variable
|
||||||
|
used to check we are still running. */
|
||||||
|
if( sErrorEverOccurred == pdFALSE )
|
||||||
|
{
|
||||||
|
( *pxQueueParameters->psCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the variable we are going to post next time round. The
|
||||||
|
consumer will expect the numbers to follow in numerical order. */
|
||||||
|
++usValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vBlockingQueueConsumer( void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned short usData, usExpectedValue = 0;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters;
|
||||||
|
const char * const pcTaskStartMsg = "Blocking queue consumer started.\r\n";
|
||||||
|
const char * const pcTaskErrorMsg = "Incorrect value received on blocking queue.\r\n";
|
||||||
|
short sErrorEverOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )
|
||||||
|
{
|
||||||
|
if( usData != usExpectedValue )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskErrorMsg );
|
||||||
|
|
||||||
|
/* Catch-up. */
|
||||||
|
usExpectedValue = usData;
|
||||||
|
|
||||||
|
sErrorEverOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have successfully received a message, so increment the
|
||||||
|
variable used to check we are still running. */
|
||||||
|
if( sErrorEverOccurred == pdFALSE )
|
||||||
|
{
|
||||||
|
( *pxQueueParameters->psCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the value we expect to remove from the queue next time
|
||||||
|
round. */
|
||||||
|
++usExpectedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
portBASE_TYPE xAreBlockingQueuesStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 };
|
||||||
|
static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 };
|
||||||
|
portBASE_TYPE xReturn = pdPASS, xTasks;
|
||||||
|
|
||||||
|
/* Not too worried about mutual exclusion on these variables as they are 16
|
||||||
|
bits and we are only reading them. We also only care to see if they have
|
||||||
|
changed or not.
|
||||||
|
|
||||||
|
Loop through each check variable and return pdFALSE if any are found not
|
||||||
|
to have changed since the last call. */
|
||||||
|
|
||||||
|
for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ )
|
||||||
|
{
|
||||||
|
if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ];
|
||||||
|
|
||||||
|
|
||||||
|
if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a very simple queue test. See the BlockQ. c documentation for a more
|
||||||
|
* comprehensive version.
|
||||||
|
*
|
||||||
|
* Creates two tasks that communicate over a single queue. One task acts as a
|
||||||
|
* producer, the other a consumer.
|
||||||
|
*
|
||||||
|
* The producer loops for three iteration, posting an incrementing number onto the
|
||||||
|
* queue each cycle. It then delays for a fixed period before doing exactly the
|
||||||
|
* same again.
|
||||||
|
*
|
||||||
|
* The consumer loops emptying the queue. Each item removed from the queue is
|
||||||
|
* checked to ensure it contains the expected value. When the queue is empty it
|
||||||
|
* blocks for a fixed period, then does the same again.
|
||||||
|
*
|
||||||
|
* All queue access is performed without blocking. The consumer completely empties
|
||||||
|
* the queue each time it runs so the producer should never find the queue full.
|
||||||
|
*
|
||||||
|
* An error is flagged if the consumer obtains an unexpected value or the producer
|
||||||
|
* find the queue is full.
|
||||||
|
*
|
||||||
|
* \page PollQC pollQ.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "PollQ.h"
|
||||||
|
|
||||||
|
#define pollqSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE )
|
||||||
|
|
||||||
|
/* The task that posts the incrementing number onto the queue. */
|
||||||
|
static void vPolledQueueProducer( void *pvParameters );
|
||||||
|
|
||||||
|
/* The task that empties the queue. */
|
||||||
|
static void vPolledQueueConsumer( void *pvParameters );
|
||||||
|
|
||||||
|
/* Variables that are used to check that the tasks are still running with no errors. */
|
||||||
|
static volatile short sPollingConsumerCount = 0, sPollingProducerCount = 0;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
static QueueHandle_t xPolledQueue;
|
||||||
|
const unsigned portBASE_TYPE uxQueueSize = 10;
|
||||||
|
|
||||||
|
/* Create the queue used by the producer and consumer. */
|
||||||
|
xPolledQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
|
||||||
|
|
||||||
|
/* Spawn the producer and consumer. */
|
||||||
|
xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL );
|
||||||
|
xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vPolledQueueProducer( void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned short usValue = 0, usLoop;
|
||||||
|
QueueHandle_t *pxQueue;
|
||||||
|
const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS;
|
||||||
|
const unsigned short usNumToProduce = 3;
|
||||||
|
const char * const pcTaskStartMsg = "Polled queue producer started.\r\n";
|
||||||
|
const char * const pcTaskErrorMsg = "Could not post on polled queue.\r\n";
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The queue being used is passed in as the parameter. */
|
||||||
|
pxQueue = ( QueueHandle_t * ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
for( usLoop = 0; usLoop < usNumToProduce; ++usLoop )
|
||||||
|
{
|
||||||
|
/* Send an incrementing number on the queue without blocking. */
|
||||||
|
if( xQueueSendToBack( *pxQueue, ( void * ) &usValue, ( TickType_t ) 0 ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We should never find the queue full - this is an error. */
|
||||||
|
vPrintDisplayMessage( &pcTaskErrorMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If an error has ever been recorded we stop incrementing the
|
||||||
|
check variable. */
|
||||||
|
++sPollingProducerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the value we are going to post next time around. */
|
||||||
|
++usValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait before we start posting again to ensure the consumer runs and
|
||||||
|
empties the queue. */
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vPolledQueueConsumer( void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned short usData, usExpectedValue = 0;
|
||||||
|
QueueHandle_t *pxQueue;
|
||||||
|
const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS;
|
||||||
|
const char * const pcTaskStartMsg = "Polled queue consumer started.\r\n";
|
||||||
|
const char * const pcTaskErrorMsg = "Incorrect value received on polled queue.\r\n";
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The queue being used is passed in as the parameter. */
|
||||||
|
pxQueue = ( QueueHandle_t * ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Loop until the queue is empty. */
|
||||||
|
while( uxQueueMessagesWaiting( *pxQueue ) )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( *pxQueue, &usData, ( TickType_t ) 0 ) == pdPASS )
|
||||||
|
{
|
||||||
|
if( usData != usExpectedValue )
|
||||||
|
{
|
||||||
|
/* This is not what we expected to receive so an error has
|
||||||
|
occurred. */
|
||||||
|
vPrintDisplayMessage( &pcTaskErrorMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
/* Catch-up to the value we received so our next expected value
|
||||||
|
should again be correct. */
|
||||||
|
usExpectedValue = usData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Only increment the check variable if no errors have
|
||||||
|
occurred. */
|
||||||
|
++sPollingConsumerCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++usExpectedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now the queue is empty we block, allowing the producer to place more
|
||||||
|
items in the queue. */
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running with no errors. */
|
||||||
|
portBASE_TYPE xArePollingQueuesStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastPollingConsumerCount = 0, sLastPollingProducerCount = 0;
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
|
if( ( sLastPollingConsumerCount == sPollingConsumerCount ) ||
|
||||||
|
( sLastPollingProducerCount == sPollingProducerCount )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLastPollingConsumerCount = sPollingConsumerCount;
|
||||||
|
sLastPollingProducerCount = sPollingProducerCount;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
|
@ -0,0 +1,388 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates two tasks that operate on an interrupt driven serial port. A loopback
|
||||||
|
* connector should be used so that everything that is transmitted is also received.
|
||||||
|
* The serial port does not use any flow control. On a standard 9way 'D' connector
|
||||||
|
* pins two and three should be connected together.
|
||||||
|
*
|
||||||
|
* The first task repeatedly sends a string to a queue, character at a time. The
|
||||||
|
* serial port interrupt will empty the queue and transmit the characters. The
|
||||||
|
* task blocks for a pseudo random period before resending the string.
|
||||||
|
*
|
||||||
|
* The second task blocks on a queue waiting for a character to be received.
|
||||||
|
* Characters received by the serial port interrupt routine are posted onto the
|
||||||
|
* queue - unblocking the task making it ready to execute. If this is then the
|
||||||
|
* highest priority task ready to run it will run immediately - with a context
|
||||||
|
* switch occurring at the end of the interrupt service routine. The task
|
||||||
|
* receiving characters is spawned with a higher priority than the task
|
||||||
|
* transmitting the characters.
|
||||||
|
*
|
||||||
|
* With the loop back connector in place, one task will transmit a string and the
|
||||||
|
* other will immediately receive it. The receiving task knows the string it
|
||||||
|
* expects to receive so can detect an error.
|
||||||
|
*
|
||||||
|
* This also creates a third task. This is used to test semaphore usage from an
|
||||||
|
* ISR and does nothing interesting.
|
||||||
|
*
|
||||||
|
* \page ComTestC comtest.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.00:
|
||||||
|
|
||||||
|
+ The priority of the Rx task has been lowered. Received characters are
|
||||||
|
now processed (read from the queue) at the idle priority, allowing low
|
||||||
|
priority tasks to run evenly at times of a high communications overhead.
|
||||||
|
|
||||||
|
Changes from V1.01:
|
||||||
|
|
||||||
|
+ The Tx task now waits a pseudo random time between transissions.
|
||||||
|
Previously a fixed period was used but this was not such a good test as
|
||||||
|
interrupts fired at regular intervals.
|
||||||
|
|
||||||
|
Changes From V1.2.0:
|
||||||
|
|
||||||
|
+ Use vSerialPutString() instead of single character puts.
|
||||||
|
+ Only stop the check variable incrementing after two consecutive errors.
|
||||||
|
|
||||||
|
Changed from V1.2.5
|
||||||
|
|
||||||
|
+ Made the Rx task 2 priorities higher than the Tx task. Previously it was
|
||||||
|
only 1. This is done to tie in better with the other demo application
|
||||||
|
tasks.
|
||||||
|
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
+ Slight modification to task priorities.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "serial.h"
|
||||||
|
#include "comtest.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* The Tx task will transmit the sequence of characters at a pseudo random
|
||||||
|
interval. This is the maximum and minimum block time between sends. */
|
||||||
|
#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x15e )
|
||||||
|
#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0xc8 )
|
||||||
|
|
||||||
|
#define comMAX_CONSECUTIVE_ERRORS ( 2 )
|
||||||
|
|
||||||
|
#define comSTACK_SIZE ( ( unsigned short ) 256 )
|
||||||
|
|
||||||
|
#define comRX_RELATIVE_PRIORITY ( 1 )
|
||||||
|
|
||||||
|
/* Handle to the com port used by both tasks. */
|
||||||
|
static xComPortHandle xPort;
|
||||||
|
|
||||||
|
/* The transmit function as described at the top of the file. */
|
||||||
|
static void vComTxTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* The receive function as described at the top of the file. */
|
||||||
|
static void vComRxTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* The semaphore test function as described at the top of the file. */
|
||||||
|
static void vSemTestTask( void * pvParameters );
|
||||||
|
|
||||||
|
/* The string that is repeatedly transmitted. */
|
||||||
|
const char * const pcMessageToExchange = "Send this message over and over again to check communications interrupts. "
|
||||||
|
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";
|
||||||
|
|
||||||
|
/* Variables that are incremented on each cycle of each task. These are used to
|
||||||
|
check that both tasks are still executing. */
|
||||||
|
volatile short sTxCount = 0, sRxCount = 0, sSemCount = 0;
|
||||||
|
|
||||||
|
/* The handle to the semaphore test task. */
|
||||||
|
static TaskHandle_t xSemTestTaskHandle = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartComTestTasks( unsigned portBASE_TYPE uxPriority, eCOMPort ePort, eBaud eBaudRate )
|
||||||
|
{
|
||||||
|
const unsigned portBASE_TYPE uxBufferLength = 255;
|
||||||
|
|
||||||
|
/* Initialise the com port then spawn both tasks. */
|
||||||
|
xPort = xSerialPortInit( ePort, eBaudRate, serNO_PARITY, serBITS_8, serSTOP_1, uxBufferLength );
|
||||||
|
xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority, NULL );
|
||||||
|
xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority + comRX_RELATIVE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vSemTestTask, "ISRSem", comSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xSemTestTaskHandle );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vComTxTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const char * const pcTaskStartMsg = "COM Tx task started.\r\n";
|
||||||
|
TickType_t xTimeToWait;
|
||||||
|
|
||||||
|
/* Stop warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Send the string to the serial port. */
|
||||||
|
vSerialPutString( xPort, pcMessageToExchange, strlen( pcMessageToExchange ) );
|
||||||
|
|
||||||
|
/* We have posted all the characters in the string - increment the variable
|
||||||
|
used to check that this task is still running, then wait before re-sending
|
||||||
|
the string. */
|
||||||
|
sTxCount++;
|
||||||
|
|
||||||
|
xTimeToWait = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* Make sure we don't wait too long... */
|
||||||
|
xTimeToWait %= comTX_MAX_BLOCK_TIME;
|
||||||
|
|
||||||
|
/* ...but we do want to wait. */
|
||||||
|
if( xTimeToWait < comTX_MIN_BLOCK_TIME )
|
||||||
|
{
|
||||||
|
xTimeToWait = comTX_MIN_BLOCK_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay( xTimeToWait );
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vComRxTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const char * const pcTaskStartMsg = "COM Rx task started.\r\n";
|
||||||
|
const char * const pcTaskErrorMsg = "COM read error\r\n";
|
||||||
|
const char * const pcTaskRestartMsg = "COM resynced\r\n";
|
||||||
|
const char * const pcTaskTimeoutMsg = "COM Rx timed out\r\n";
|
||||||
|
const TickType_t xBlockTime = ( TickType_t ) 0xffff / portTICK_PERIOD_MS;
|
||||||
|
const char *pcExpectedChar;
|
||||||
|
portBASE_TYPE xGotChar;
|
||||||
|
char cRxedChar;
|
||||||
|
short sResyncRequired, sConsecutiveErrors, sLatchedError;
|
||||||
|
|
||||||
|
/* Stop warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The first expected character is the first character in the string. */
|
||||||
|
pcExpectedChar = pcMessageToExchange;
|
||||||
|
sResyncRequired = pdFALSE;
|
||||||
|
sConsecutiveErrors = 0;
|
||||||
|
sLatchedError = pdFALSE;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Receive a message from the com port interrupt routine. If a message is
|
||||||
|
not yet available the call will block the task. */
|
||||||
|
xGotChar = xSerialGetChar( xPort, &cRxedChar, xBlockTime );
|
||||||
|
if( xGotChar == pdTRUE )
|
||||||
|
{
|
||||||
|
if( sResyncRequired == pdTRUE )
|
||||||
|
{
|
||||||
|
/* We got out of sequence and are waiting for the start of the next
|
||||||
|
transmission of the string. */
|
||||||
|
if( cRxedChar == '\n' )
|
||||||
|
{
|
||||||
|
/* This is the end of the message so we can start again - with
|
||||||
|
the first character in the string being the next thing we expect
|
||||||
|
to receive. */
|
||||||
|
pcExpectedChar = pcMessageToExchange;
|
||||||
|
sResyncRequired = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say that we are going to try
|
||||||
|
again. */
|
||||||
|
vPrintDisplayMessage( &pcTaskRestartMsg );
|
||||||
|
|
||||||
|
/* Stop incrementing the check variable, if consecutive errors occur. */
|
||||||
|
sConsecutiveErrors++;
|
||||||
|
if( sConsecutiveErrors >= comMAX_CONSECUTIVE_ERRORS )
|
||||||
|
{
|
||||||
|
sLatchedError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have received a character, but is it the expected character? */
|
||||||
|
if( cRxedChar != *pcExpectedChar )
|
||||||
|
{
|
||||||
|
/* This was not the expected character so post a message for
|
||||||
|
printing to say that an error has occurred. We will then wait
|
||||||
|
to resynchronise. */
|
||||||
|
vPrintDisplayMessage( &pcTaskErrorMsg );
|
||||||
|
sResyncRequired = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This was the expected character so next time we will expect
|
||||||
|
the next character in the string. Wrap back to the beginning
|
||||||
|
of the string when the null terminator has been reached. */
|
||||||
|
pcExpectedChar++;
|
||||||
|
if( *pcExpectedChar == '\0' )
|
||||||
|
{
|
||||||
|
pcExpectedChar = pcMessageToExchange;
|
||||||
|
|
||||||
|
/* We have got through the entire string without error. */
|
||||||
|
sConsecutiveErrors = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the count that is used to check that this task is still
|
||||||
|
running. This is only done if an error has never occurred. */
|
||||||
|
if( sLatchedError == pdFALSE )
|
||||||
|
{
|
||||||
|
sRxCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskTimeoutMsg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vSemTestTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
const char * const pcTaskStartMsg = "ISR Semaphore test started.\r\n";
|
||||||
|
portBASE_TYPE xError = pdFALSE;
|
||||||
|
|
||||||
|
/* Stop warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xSerialWaitForSemaphore( xPort ) )
|
||||||
|
{
|
||||||
|
if( xError == pdFALSE )
|
||||||
|
{
|
||||||
|
sSemCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e830 !e818 pvParameters not used but function prototype must be standard for task function. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
portBASE_TYPE xAreComTestTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastTxCount = 0, sLastRxCount = 0, sLastSemCount = 0;
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
|
/* Not too worried about mutual exclusion on these variables as they are 16
|
||||||
|
bits and we are only reading them. We also only care to see if they have
|
||||||
|
changed or not. */
|
||||||
|
|
||||||
|
if( ( sTxCount == sLastTxCount ) || ( sRxCount == sLastRxCount ) || ( sSemCount == sLastSemCount ) )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLastTxCount = sTxCount;
|
||||||
|
sLastRxCount = sRxCount;
|
||||||
|
sLastSemCount = sSemCount;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vComTestUnsuspendTask( void )
|
||||||
|
{
|
||||||
|
/* The task that is suspended on the semaphore will be referenced from the
|
||||||
|
Suspended list as it is blocking indefinitely. This call just checks that
|
||||||
|
the kernel correctly detects this and does not attempt to unsuspend the
|
||||||
|
task. */
|
||||||
|
xTaskResumeFromISR( xSemTestTaskHandle );
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single persistent task which periodically dynamically creates another
|
||||||
|
* four tasks. The original task is called the creator task, the four tasks it
|
||||||
|
* creates are called suicidal tasks.
|
||||||
|
*
|
||||||
|
* Two of the created suicidal tasks kill one other suicidal task before killing
|
||||||
|
* themselves - leaving just the original task remaining.
|
||||||
|
*
|
||||||
|
* The creator task must be spawned after all of the other demo application tasks
|
||||||
|
* as it keeps a check on the number of tasks under the scheduler control. The
|
||||||
|
* number of tasks it expects to see running should never be greater than the
|
||||||
|
* number of tasks that were in existence when the creator task was spawned, plus
|
||||||
|
* one set of four suicidal tasks. If this number is exceeded an error is flagged.
|
||||||
|
*
|
||||||
|
* \page DeathC death.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "death.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
#define deathSTACK_SIZE ( ( unsigned short ) 512 )
|
||||||
|
|
||||||
|
/* The task originally created which is responsible for periodically dynamically
|
||||||
|
creating another four tasks. */
|
||||||
|
static void vCreateTasks( void *pvParameters );
|
||||||
|
|
||||||
|
/* The task function of the dynamically created tasks. */
|
||||||
|
static void vSuicidalTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* A variable which is incremented every time the dynamic tasks are created. This
|
||||||
|
is used to check that the task is still running. */
|
||||||
|
static volatile short sCreationCount = 0;
|
||||||
|
|
||||||
|
/* Used to store the number of tasks that were originally running so the creator
|
||||||
|
task can tell if any of the suicidal tasks have failed to die. */
|
||||||
|
static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0;
|
||||||
|
static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5;
|
||||||
|
|
||||||
|
/* Used to store a handle to the tasks that should be killed by a suicidal task,
|
||||||
|
before it kills itself. */
|
||||||
|
TaskHandle_t xCreatedTask1, xCreatedTask2;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
unsigned portBASE_TYPE *puxPriority;
|
||||||
|
|
||||||
|
/* Create the Creator tasks - passing in as a parameter the priority at which
|
||||||
|
the suicidal tasks should be created. */
|
||||||
|
puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) );
|
||||||
|
*puxPriority = uxPriority;
|
||||||
|
|
||||||
|
xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );
|
||||||
|
|
||||||
|
/* Record the number of tasks that are running now so we know if any of the
|
||||||
|
suicidal tasks have failed to be killed. */
|
||||||
|
uxTasksRunningAtStart = uxTaskGetNumberOfTasks();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vSuicidalTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
portDOUBLE d1, d2;
|
||||||
|
TaskHandle_t xTaskToKill;
|
||||||
|
const TickType_t xDelay = ( TickType_t ) 500 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
if( pvParameters != NULL )
|
||||||
|
{
|
||||||
|
/* This task is periodically created four times. Tow created tasks are
|
||||||
|
passed a handle to the other task so it can kill it before killing itself.
|
||||||
|
The other task is passed in null. */
|
||||||
|
xTaskToKill = *( TaskHandle_t* )pvParameters;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xTaskToKill = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Do something random just to use some stack and registers. */
|
||||||
|
d1 = 2.4;
|
||||||
|
d2 = 89.2;
|
||||||
|
d2 *= d1;
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
|
||||||
|
if( xTaskToKill != NULL )
|
||||||
|
{
|
||||||
|
/* Make sure the other task has a go before we delete it. */
|
||||||
|
vTaskDelay( ( TickType_t ) 0 );
|
||||||
|
/* Kill the other task that was created by vCreateTasks(). */
|
||||||
|
vTaskDelete( xTaskToKill );
|
||||||
|
/* Kill ourselves. */
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCreateTasks( void *pvParameters )
|
||||||
|
{
|
||||||
|
const TickType_t xDelay = ( TickType_t ) 1000 / portTICK_PERIOD_MS;
|
||||||
|
unsigned portBASE_TYPE uxPriority;
|
||||||
|
const char * const pcTaskStartMsg = "Create task started.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
uxPriority = *( unsigned portBASE_TYPE * ) pvParameters;
|
||||||
|
vPortFree( pvParameters );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Just loop round, delaying then creating the four suicidal tasks. */
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
|
||||||
|
xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 );
|
||||||
|
xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL );
|
||||||
|
|
||||||
|
xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 );
|
||||||
|
xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL );
|
||||||
|
|
||||||
|
++sCreationCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that the creator task is still running and that there
|
||||||
|
are not any more than four extra tasks. */
|
||||||
|
portBASE_TYPE xIsCreateTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastCreationCount = 0;
|
||||||
|
short sReturn = pdTRUE;
|
||||||
|
unsigned portBASE_TYPE uxTasksRunningNow;
|
||||||
|
|
||||||
|
if( sLastCreationCount == sCreationCount )
|
||||||
|
{
|
||||||
|
sReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uxTasksRunningNow = uxTaskGetNumberOfTasks();
|
||||||
|
|
||||||
|
if( uxTasksRunningNow < uxTasksRunningAtStart )
|
||||||
|
{
|
||||||
|
sReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning )
|
||||||
|
{
|
||||||
|
sReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Everything is okay. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return sReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,620 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first test creates three tasks - two counter tasks (one continuous count
|
||||||
|
* and one limited count) and one controller. A "count" variable is shared
|
||||||
|
* between all three tasks. The two counter tasks should never be in a "ready"
|
||||||
|
* state at the same time. The controller task runs at the same priority as
|
||||||
|
* the continuous count task, and at a lower priority than the limited count
|
||||||
|
* task.
|
||||||
|
*
|
||||||
|
* One counter task loops indefinitely, incrementing the shared count variable
|
||||||
|
* on each iteration. To ensure it has exclusive access to the variable it
|
||||||
|
* raises it's priority above that of the controller task before each
|
||||||
|
* increment, lowering it again to it's original priority before starting the
|
||||||
|
* next iteration.
|
||||||
|
*
|
||||||
|
* The other counter task increments the shared count variable on each
|
||||||
|
* iteration of it's loop until the count has reached a limit of 0xff - at
|
||||||
|
* which point it suspends itself. It will not start a new loop until the
|
||||||
|
* controller task has made it "ready" again by calling vTaskResume ().
|
||||||
|
* This second counter task operates at a higher priority than controller
|
||||||
|
* task so does not need to worry about mutual exclusion of the counter
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* The controller task is in two sections. The first section controls and
|
||||||
|
* monitors the continuous count task. When this section is operational the
|
||||||
|
* limited count task is suspended. Likewise, the second section controls
|
||||||
|
* and monitors the limited count task. When this section is operational the
|
||||||
|
* continuous count task is suspended.
|
||||||
|
*
|
||||||
|
* In the first section the controller task first takes a copy of the shared
|
||||||
|
* count variable. To ensure mutual exclusion on the count variable it
|
||||||
|
* suspends the continuous count task, resuming it again when the copy has been
|
||||||
|
* taken. The controller task then sleeps for a fixed period - during which
|
||||||
|
* the continuous count task will execute and increment the shared variable.
|
||||||
|
* When the controller task wakes it checks that the continuous count task
|
||||||
|
* has executed by comparing the copy of the shared variable with its current
|
||||||
|
* value. This time, to ensure mutual exclusion, the scheduler itself is
|
||||||
|
* suspended with a call to vTaskSuspendAll (). This is for demonstration
|
||||||
|
* purposes only and is not a recommended technique due to its inefficiency.
|
||||||
|
*
|
||||||
|
* After a fixed number of iterations the controller task suspends the
|
||||||
|
* continuous count task, and moves on to its second section.
|
||||||
|
*
|
||||||
|
* At the start of the second section the shared variable is cleared to zero.
|
||||||
|
* The limited count task is then woken from it's suspension by a call to
|
||||||
|
* vTaskResume (). As this counter task operates at a higher priority than
|
||||||
|
* the controller task the controller task should not run again until the
|
||||||
|
* shared variable has been counted up to the limited value causing the counter
|
||||||
|
* task to suspend itself. The next line after vTaskResume () is therefore
|
||||||
|
* a check on the shared variable to ensure everything is as expected.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The second test consists of a couple of very simple tasks that post onto a
|
||||||
|
* queue while the scheduler is suspended. This test was added to test parts
|
||||||
|
* of the scheduler not exercised by the first test.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The final set of two tasks implements a third test. This simply raises the
|
||||||
|
* priority of a task while the scheduler is suspended. Again this test was
|
||||||
|
* added to exercise parts of the code not covered by the first test.
|
||||||
|
*
|
||||||
|
* \page Priorities dynamic.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
+ Added a second, simple test that uses the functions
|
||||||
|
vQueueReceiveWhenSuspendedTask() and vQueueSendWhenSuspendedTask().
|
||||||
|
|
||||||
|
Changes from V3.1.1
|
||||||
|
|
||||||
|
+ Added a third simple test that uses the vTaskPrioritySet() function
|
||||||
|
while the scheduler is suspended.
|
||||||
|
+ Modified the controller task slightly to test the calling of
|
||||||
|
vTaskResumeAll() while the scheduler is suspended.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo app include files. */
|
||||||
|
#include "dynamic.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* Function that implements the "limited count" task as described above. */
|
||||||
|
static void vLimitedIncrementTask( void * pvParameters );
|
||||||
|
|
||||||
|
/* Function that implements the "continuous count" task as described above. */
|
||||||
|
static void vContinuousIncrementTask( void * pvParameters );
|
||||||
|
|
||||||
|
/* Function that implements the controller task as described above. */
|
||||||
|
static void vCounterControlTask( void * pvParameters );
|
||||||
|
|
||||||
|
/* The simple test functions that check sending and receiving while the
|
||||||
|
scheduler is suspended. */
|
||||||
|
static void vQueueReceiveWhenSuspendedTask( void *pvParameters );
|
||||||
|
static void vQueueSendWhenSuspendedTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* The simple test functions that check raising and lowering of task priorities
|
||||||
|
while the scheduler is suspended. */
|
||||||
|
static void prvChangePriorityWhenSuspendedTask( void *pvParameters );
|
||||||
|
static void prvChangePriorityHelperTask( void *pvParameters );
|
||||||
|
|
||||||
|
|
||||||
|
/* Demo task specific constants. */
|
||||||
|
#define priSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE )
|
||||||
|
#define priSLEEP_TIME ( ( TickType_t ) 50 )
|
||||||
|
#define priLOOPS ( 5 )
|
||||||
|
#define priMAX_COUNT ( ( unsigned long ) 0xff )
|
||||||
|
#define priNO_BLOCK ( ( TickType_t ) 0 )
|
||||||
|
#define priSUSPENDED_QUEUE_LENGTH ( 1 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Handles to the two counter tasks. These could be passed in as parameters
|
||||||
|
to the controller task to prevent them having to be file scope. */
|
||||||
|
static TaskHandle_t xContinuousIncrementHandle, xLimitedIncrementHandle, xChangePriorityWhenSuspendedHandle;
|
||||||
|
|
||||||
|
/* The shared counter variable. This is passed in as a parameter to the two
|
||||||
|
counter variables for demonstration purposes. */
|
||||||
|
static unsigned long ulCounter;
|
||||||
|
|
||||||
|
/* Variable used in a similar way by the test that checks the raising and
|
||||||
|
lowering of task priorities while the scheduler is suspended. */
|
||||||
|
static unsigned long ulPrioritySetCounter;
|
||||||
|
|
||||||
|
/* Variables used to check that the tasks are still operating without error.
|
||||||
|
Each complete iteration of the controller task increments this variable
|
||||||
|
provided no errors have been found. The variable maintaining the same value
|
||||||
|
is therefore indication of an error. */
|
||||||
|
static unsigned short usCheckVariable = ( unsigned short ) 0;
|
||||||
|
static portBASE_TYPE xSuspendedQueueSendError = pdFALSE;
|
||||||
|
static portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE;
|
||||||
|
static portBASE_TYPE xPriorityRaiseWhenSuspendedError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue used by the second test. */
|
||||||
|
QueueHandle_t xSuspendedTestQueue;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Start the seven tasks as described at the top of the file.
|
||||||
|
* Note that the limited count task is given a higher priority.
|
||||||
|
*/
|
||||||
|
void vStartDynamicPriorityTasks( void )
|
||||||
|
{
|
||||||
|
xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) );
|
||||||
|
xTaskCreate( vContinuousIncrementTask, "CONT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle );
|
||||||
|
xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );
|
||||||
|
xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_SEND", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RECV", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvChangePriorityWhenSuspendedTask, "1st_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );
|
||||||
|
xTaskCreate( prvChangePriorityHelperTask, "2nd_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xChangePriorityWhenSuspendedHandle );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just loops around incrementing the shared variable until the limit has been
|
||||||
|
* reached. Once the limit has been reached it suspends itself.
|
||||||
|
*/
|
||||||
|
static void vLimitedIncrementTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
unsigned long *pulCounter;
|
||||||
|
|
||||||
|
/* Take a pointer to the shared variable from the parameters passed into
|
||||||
|
the task. */
|
||||||
|
pulCounter = ( unsigned long * ) pvParameters;
|
||||||
|
|
||||||
|
/* This will run before the control task, so the first thing it does is
|
||||||
|
suspend - the control task will resume it when ready. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Just count up to a value then suspend. */
|
||||||
|
( *pulCounter )++;
|
||||||
|
|
||||||
|
if( *pulCounter >= priMAX_COUNT )
|
||||||
|
{
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just keep counting the shared variable up. The control task will suspend
|
||||||
|
* this task when it wants.
|
||||||
|
*/
|
||||||
|
static void vContinuousIncrementTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
unsigned long *pulCounter;
|
||||||
|
unsigned portBASE_TYPE uxOurPriority;
|
||||||
|
|
||||||
|
/* Take a pointer to the shared variable from the parameters passed into
|
||||||
|
the task. */
|
||||||
|
pulCounter = ( unsigned long * ) pvParameters;
|
||||||
|
|
||||||
|
/* Query our priority so we can raise it when exclusive access to the
|
||||||
|
shared variable is required. */
|
||||||
|
uxOurPriority = uxTaskPriorityGet( NULL );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Raise our priority above the controller task to ensure a context
|
||||||
|
switch does not occur while we are accessing this variable. */
|
||||||
|
vTaskPrioritySet( NULL, uxOurPriority + 1 );
|
||||||
|
( *pulCounter )++;
|
||||||
|
vTaskPrioritySet( NULL, uxOurPriority );
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controller task as described above.
|
||||||
|
*/
|
||||||
|
static void vCounterControlTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
unsigned long ulLastCounter;
|
||||||
|
short sLoops;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n";
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Start with the counter at zero. */
|
||||||
|
ulCounter = ( unsigned long ) 0;
|
||||||
|
|
||||||
|
/* First section : */
|
||||||
|
|
||||||
|
/* Check the continuous count task is running. */
|
||||||
|
for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
|
||||||
|
{
|
||||||
|
/* Suspend the continuous count task so we can take a mirror of the
|
||||||
|
shared variable without risk of corruption. */
|
||||||
|
vTaskSuspend( xContinuousIncrementHandle );
|
||||||
|
ulLastCounter = ulCounter;
|
||||||
|
vTaskResume( xContinuousIncrementHandle );
|
||||||
|
|
||||||
|
/* Now delay to ensure the other task has processor time. */
|
||||||
|
vTaskDelay( priSLEEP_TIME );
|
||||||
|
|
||||||
|
/* Check the shared variable again. This time to ensure mutual
|
||||||
|
exclusion the whole scheduler will be locked. This is just for
|
||||||
|
demo purposes! */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
if( ulLastCounter == ulCounter )
|
||||||
|
{
|
||||||
|
/* The shared variable has not changed. There is a problem
|
||||||
|
with the continuous count task so flag an error. */
|
||||||
|
sError = pdTRUE;
|
||||||
|
xTaskResumeAll();
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
vTaskSuspendAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Second section: */
|
||||||
|
|
||||||
|
/* Suspend the continuous counter task so it stops accessing the shared variable. */
|
||||||
|
vTaskSuspend( xContinuousIncrementHandle );
|
||||||
|
|
||||||
|
/* Reset the variable. */
|
||||||
|
ulCounter = ( unsigned long ) 0;
|
||||||
|
|
||||||
|
/* Resume the limited count task which has a higher priority than us.
|
||||||
|
We should therefore not return from this call until the limited count
|
||||||
|
task has suspended itself with a known value in the counter variable.
|
||||||
|
The scheduler suspension is not necessary but is included for test
|
||||||
|
purposes. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
vTaskResume( xLimitedIncrementHandle );
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
/* Does the counter variable have the expected value? */
|
||||||
|
if( ulCounter != priMAX_COUNT )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If no errors have occurred then increment the check variable. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
usCheckVariable++;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Resume the continuous count task and do it all again. */
|
||||||
|
vTaskResume( xContinuousIncrementHandle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vQueueSendWhenSuspendedTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
static unsigned long ulValueToSend = ( unsigned long ) 0;
|
||||||
|
const char * const pcTaskStartMsg = "Queue send while suspended task started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Queue send while suspended failed.\r\n";
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
/* We must not block while the scheduler is suspended! */
|
||||||
|
if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE )
|
||||||
|
{
|
||||||
|
if( xSuspendedQueueSendError == pdFALSE )
|
||||||
|
{
|
||||||
|
xTaskResumeAll();
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
vTaskSuspendAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
xSuspendedQueueSendError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
vTaskDelay( priSLEEP_TIME );
|
||||||
|
|
||||||
|
++ulValueToSend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vQueueReceiveWhenSuspendedTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue;
|
||||||
|
const char * const pcTaskStartMsg = "Queue receive while suspended task started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Queue receive while suspended failed.\r\n";
|
||||||
|
portBASE_TYPE xGotValue;
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Suspending the scheduler here is fairly pointless and
|
||||||
|
undesirable for a normal application. It is done here purely
|
||||||
|
to test the scheduler. The inner xTaskResumeAll() should
|
||||||
|
never return pdTRUE as the scheduler is still locked by the
|
||||||
|
outer call. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK );
|
||||||
|
}
|
||||||
|
if( xTaskResumeAll() )
|
||||||
|
{
|
||||||
|
xSuspendedQueueReceiveError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} while( xGotValue == pdFALSE );
|
||||||
|
|
||||||
|
if( ulReceivedValue != ulExpectedValue )
|
||||||
|
{
|
||||||
|
if( xSuspendedQueueReceiveError == pdFALSE )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
}
|
||||||
|
xSuspendedQueueReceiveError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ulExpectedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvChangePriorityWhenSuspendedTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const char * const pcTaskStartMsg = "Priority change when suspended task started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n";
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Start with the counter at 0 so we know what the counter should be
|
||||||
|
when we check it next. */
|
||||||
|
ulPrioritySetCounter = ( unsigned long ) 0;
|
||||||
|
|
||||||
|
/* Resume the helper task. At this time it has a priority lower than
|
||||||
|
ours so no context switch should occur. */
|
||||||
|
vTaskResume( xChangePriorityWhenSuspendedHandle );
|
||||||
|
|
||||||
|
/* Check to ensure the task just resumed has not executed. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( ulPrioritySetCounter != ( unsigned long ) 0 )
|
||||||
|
{
|
||||||
|
xPriorityRaiseWhenSuspendedError = pdTRUE;
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
/* Now try raising the priority while the scheduler is suspended. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) );
|
||||||
|
|
||||||
|
/* Again, even though the helper task has a priority greater than
|
||||||
|
ours, it should not have executed yet because the scheduler is
|
||||||
|
suspended. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( ulPrioritySetCounter != ( unsigned long ) 0 )
|
||||||
|
{
|
||||||
|
xPriorityRaiseWhenSuspendedError = pdTRUE;
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
/* Now the scheduler has been resumed the helper task should
|
||||||
|
immediately preempt us and execute. When it executes it will increment
|
||||||
|
the ulPrioritySetCounter exactly once before suspending itself.
|
||||||
|
|
||||||
|
We should now always find the counter set to 1. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( ulPrioritySetCounter != ( unsigned long ) 1 )
|
||||||
|
{
|
||||||
|
xPriorityRaiseWhenSuspendedError = pdTRUE;
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
/* Delay until we try this again. */
|
||||||
|
vTaskDelay( priSLEEP_TIME * 2 );
|
||||||
|
|
||||||
|
/* Set the priority of the helper task back ready for the next
|
||||||
|
execution of this task. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY );
|
||||||
|
xTaskResumeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvChangePriorityHelperTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* This is the helper task for prvChangePriorityWhenSuspendedTask().
|
||||||
|
It has it's priority raised and lowered. When it runs it simply
|
||||||
|
increments the counter then suspends itself again. This allows
|
||||||
|
prvChangePriorityWhenSuspendedTask() to know how many times it has
|
||||||
|
executed. */
|
||||||
|
ulPrioritySetCounter++;
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Called to check that all the created tasks are still running without error. */
|
||||||
|
portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
/* Keep a history of the check variables so we know if it has been incremented
|
||||||
|
since the last call. */
|
||||||
|
static unsigned short usLastTaskCheck = ( unsigned short ) 0;
|
||||||
|
portBASE_TYPE xReturn = pdTRUE;
|
||||||
|
|
||||||
|
/* Check the tasks are still running by ensuring the check variable
|
||||||
|
is still incrementing. */
|
||||||
|
|
||||||
|
if( usCheckVariable == usLastTaskCheck )
|
||||||
|
{
|
||||||
|
/* The check has not incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSuspendedQueueSendError == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSuspendedQueueReceiveError == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xPriorityRaiseWhenSuspendedError == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
usLastTaskCheck = usCheckVariable;
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,410 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file exercises the event mechanism whereby more than one task is
|
||||||
|
* blocked waiting for the same event.
|
||||||
|
*
|
||||||
|
* The demo creates five tasks - four 'event' tasks, and a controlling task.
|
||||||
|
* The event tasks have various different priorities and all block on reading
|
||||||
|
* the same queue. The controlling task writes data to the queue, then checks
|
||||||
|
* to see which of the event tasks read the data from the queue. The
|
||||||
|
* controlling task has the lowest priority of all the tasks so is guaranteed
|
||||||
|
* to always get preempted immediately upon writing to the queue.
|
||||||
|
*
|
||||||
|
* By selectively suspending and resuming the event tasks the controlling task
|
||||||
|
* can check that the highest priority task that is blocked on the queue is the
|
||||||
|
* task that reads the posted data from the queue.
|
||||||
|
*
|
||||||
|
* Two of the event tasks share the same priority. When neither of these tasks
|
||||||
|
* are suspended they should alternate - one reading one message from the queue,
|
||||||
|
* the other the next message, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "mevents.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* Demo specific constants. */
|
||||||
|
#define evtSTACK_SIZE ( ( unsigned portBASE_TYPE ) configMINIMAL_STACK_SIZE )
|
||||||
|
#define evtNUM_TASKS ( 4 )
|
||||||
|
#define evtQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 3 )
|
||||||
|
#define evtNO_DELAY 0
|
||||||
|
|
||||||
|
/* Just indexes used to uniquely identify the tasks. Note that two tasks are
|
||||||
|
'highest' priority. */
|
||||||
|
#define evtHIGHEST_PRIORITY_INDEX_2 3
|
||||||
|
#define evtHIGHEST_PRIORITY_INDEX_1 2
|
||||||
|
#define evtMEDIUM_PRIORITY_INDEX 1
|
||||||
|
#define evtLOWEST_PRIORITY_INDEX 0
|
||||||
|
|
||||||
|
/* Each event task increments one of these counters each time it reads data
|
||||||
|
from the queue. */
|
||||||
|
static volatile portBASE_TYPE xTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
/* Each time the controlling task posts onto the queue it increments the
|
||||||
|
expected count of the task that it expected to read the data from the queue
|
||||||
|
(i.e. the task with the highest priority that should be blocked on the queue).
|
||||||
|
|
||||||
|
xExpectedTaskCounters are incremented from the controlling task, and
|
||||||
|
xTaskCounters are incremented from the individual event tasks - therefore
|
||||||
|
comparing xTaskCounters to xExpectedTaskCounters shows whether or not the
|
||||||
|
correct task was unblocked by the post. */
|
||||||
|
static portBASE_TYPE xExpectedTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
/* Handles to the four event tasks. These are required to suspend and resume
|
||||||
|
the tasks. */
|
||||||
|
static TaskHandle_t xCreatedTasks[ evtNUM_TASKS ];
|
||||||
|
|
||||||
|
/* The single queue onto which the controlling task posts, and the four event
|
||||||
|
tasks block. */
|
||||||
|
static QueueHandle_t xQueue;
|
||||||
|
|
||||||
|
/* Flag used to indicate whether or not an error has occurred at any time.
|
||||||
|
An error is either the queue being full when not expected, or an unexpected
|
||||||
|
task reading data from the queue. */
|
||||||
|
static portBASE_TYPE xHealthStatus = pdPASS;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Function that implements the event task. This is created four times. */
|
||||||
|
static void prvMultiEventTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* Function that implements the controlling task. */
|
||||||
|
static void prvEventControllerTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* This is a utility function that posts data to the queue, then compares
|
||||||
|
xExpectedTaskCounters with xTaskCounters to ensure everything worked as
|
||||||
|
expected.
|
||||||
|
|
||||||
|
The event tasks all have higher priorities the controlling task. Therefore
|
||||||
|
the controlling task will always get preempted between writhing to the queue
|
||||||
|
and checking the task counters.
|
||||||
|
|
||||||
|
@param xExpectedTask The index to the task that the controlling task thinks
|
||||||
|
should be the highest priority task waiting for data, and
|
||||||
|
therefore the task that will unblock.
|
||||||
|
|
||||||
|
@param xIncrement The number of items that should be written to the queue.
|
||||||
|
*/
|
||||||
|
static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement );
|
||||||
|
|
||||||
|
/* This is just incremented each cycle of the controlling tasks function so
|
||||||
|
the main application can ensure the test is still running. */
|
||||||
|
static portBASE_TYPE xCheckVariable = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartMultiEventTasks( void )
|
||||||
|
{
|
||||||
|
/* Create the queue to be used for all the communications. */
|
||||||
|
xQueue = xQueueCreate( evtQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );
|
||||||
|
|
||||||
|
/* Start the controlling task. This has the idle priority to ensure it is
|
||||||
|
always preempted by the event tasks. */
|
||||||
|
xTaskCreate( prvEventControllerTask, "EvntCTRL", evtSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Start the four event tasks. Note that two have priority 3, one
|
||||||
|
priority 2 and the other priority 1. */
|
||||||
|
xTaskCreate( prvMultiEventTask, "Event0", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 0 ] ), 1, &( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ) );
|
||||||
|
xTaskCreate( prvMultiEventTask, "Event1", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 1 ] ), 2, &( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ) );
|
||||||
|
xTaskCreate( prvMultiEventTask, "Event2", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 2 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ) );
|
||||||
|
xTaskCreate( prvMultiEventTask, "Event3", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 3 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvMultiEventTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
portBASE_TYPE *pxCounter;
|
||||||
|
unsigned portBASE_TYPE uxDummy;
|
||||||
|
const char * const pcTaskStartMsg = "Multi event task started.\r\n";
|
||||||
|
|
||||||
|
/* The variable this task will increment is passed in as a parameter. */
|
||||||
|
pxCounter = ( portBASE_TYPE * ) pvParameters;
|
||||||
|
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Block on the queue. */
|
||||||
|
if( xQueueReceive( xQueue, &uxDummy, portMAX_DELAY ) )
|
||||||
|
{
|
||||||
|
/* We unblocked by reading the queue - so simply increment
|
||||||
|
the counter specific to this task instance. */
|
||||||
|
( *pxCounter )++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvEventControllerTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const char * const pcTaskStartMsg = "Multi event controller task started.\r\n";
|
||||||
|
portBASE_TYPE xDummy = 0;
|
||||||
|
|
||||||
|
/* Just to stop warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* All tasks are blocked on the queue. When a message is posted one of
|
||||||
|
the two tasks that share the highest priority should unblock to read
|
||||||
|
the queue. The next message written should unblock the other task with
|
||||||
|
the same high priority, and so on in order. No other task should
|
||||||
|
unblock to read data as they have lower priorities. */
|
||||||
|
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 );
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 );
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
|
||||||
|
|
||||||
|
/* For the rest of these tests we don't need the second 'highest'
|
||||||
|
priority task - so it is suspended. */
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Now suspend the other highest priority task. The medium priority
|
||||||
|
task will then be the task with the highest priority that remains
|
||||||
|
blocked on the queue. */
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
|
||||||
|
/* This time, when we post onto the queue we will expect the medium
|
||||||
|
priority task to unblock and preempt us. */
|
||||||
|
prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 );
|
||||||
|
|
||||||
|
/* Now try resuming the highest priority task while the scheduler is
|
||||||
|
suspended. The task should start executing as soon as the scheduler
|
||||||
|
is resumed - therefore when we post to the queue again, the highest
|
||||||
|
priority task should again preempt us. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
xTaskResumeAll();
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
|
||||||
|
|
||||||
|
/* Now we are going to suspend the high and medium priority tasks. The
|
||||||
|
low priority task should then preempt us. Again the task suspension is
|
||||||
|
done with the whole scheduler suspended just for test purposes. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
|
||||||
|
xTaskResumeAll();
|
||||||
|
prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 );
|
||||||
|
|
||||||
|
/* Do the same basic test another few times - selectively suspending
|
||||||
|
and resuming tasks and each time calling prvCheckTaskCounters() passing
|
||||||
|
to the function the number of the task we expected to be unblocked by
|
||||||
|
the post. */
|
||||||
|
|
||||||
|
vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
|
||||||
|
|
||||||
|
vTaskSuspendAll(); /* Just for test. */
|
||||||
|
vTaskSuspendAll(); /* Just for test. */
|
||||||
|
vTaskSuspendAll(); /* Just for even more test. */
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
xTaskResumeAll();
|
||||||
|
xTaskResumeAll();
|
||||||
|
xTaskResumeAll();
|
||||||
|
prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 );
|
||||||
|
|
||||||
|
vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
|
||||||
|
prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 );
|
||||||
|
|
||||||
|
vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
|
||||||
|
|
||||||
|
/* Now a slight change, first suspend all tasks. */
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
|
||||||
|
|
||||||
|
/* Now when we resume the low priority task and write to the queue 3
|
||||||
|
times. We expect the low priority task to service the queue three
|
||||||
|
times. */
|
||||||
|
vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
|
||||||
|
prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH );
|
||||||
|
|
||||||
|
/* Again suspend all tasks (only the low priority task is not suspended
|
||||||
|
already). */
|
||||||
|
vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
|
||||||
|
|
||||||
|
/* This time we are going to suspend the scheduler, resume the low
|
||||||
|
priority task, then resume the high priority task. In this state we
|
||||||
|
will write to the queue three times. When the scheduler is resumed
|
||||||
|
we expect the high priority task to service all three messages. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
|
||||||
|
vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
|
||||||
|
|
||||||
|
for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ )
|
||||||
|
{
|
||||||
|
if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE )
|
||||||
|
{
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The queue should not have been serviced yet!. The scheduler
|
||||||
|
is still suspended. */
|
||||||
|
if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
|
||||||
|
{
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
/* We should have been preempted by resuming the scheduler - so by the
|
||||||
|
time we are running again we expect the high priority task to have
|
||||||
|
removed three items from the queue. */
|
||||||
|
xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH;
|
||||||
|
if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
|
||||||
|
{
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The medium priority and second high priority tasks are still
|
||||||
|
suspended. Make sure to resume them before starting again. */
|
||||||
|
vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
|
||||||
|
vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] );
|
||||||
|
|
||||||
|
/* Just keep incrementing to show the task is still executing. */
|
||||||
|
xCheckVariable++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xDummy = 0;
|
||||||
|
|
||||||
|
/* Write to the queue the requested number of times. The data written is
|
||||||
|
not important. */
|
||||||
|
for( xDummy = 0; xDummy < xIncrement; xDummy++ )
|
||||||
|
{
|
||||||
|
if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE )
|
||||||
|
{
|
||||||
|
/* Did not expect to ever find the queue full. */
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All the tasks blocked on the queue have a priority higher than the
|
||||||
|
controlling task. Writing to the queue will therefore have caused this
|
||||||
|
task to be preempted. By the time this line executes the event task will
|
||||||
|
have executed and incremented its counter. Increment the expected counter
|
||||||
|
to the same value. */
|
||||||
|
( xExpectedTaskCounters[ xExpectedTask ] ) += xIncrement;
|
||||||
|
|
||||||
|
/* Check the actual counts and expected counts really are the same. */
|
||||||
|
if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
|
||||||
|
{
|
||||||
|
/* The counters were not the same. This means a task we did not expect
|
||||||
|
to unblock actually did unblock. */
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xAreMultiEventTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static portBASE_TYPE xPreviousCheckVariable = 0;
|
||||||
|
|
||||||
|
/* Called externally to periodically check that this test is still
|
||||||
|
operational. */
|
||||||
|
|
||||||
|
if( xPreviousCheckVariable == xCheckVariable )
|
||||||
|
{
|
||||||
|
xHealthStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xPreviousCheckVariable = xCheckVariable;
|
||||||
|
|
||||||
|
return xHealthStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates eight tasks, each of which flash an LED at a different rate. The first
|
||||||
|
* LED flashes every 125ms, the second every 250ms, the third every 375ms, etc.
|
||||||
|
*
|
||||||
|
* The LED flash tasks provide instant visual feedback. They show that the scheduler
|
||||||
|
* is still operational.
|
||||||
|
*
|
||||||
|
* The PC port uses the standard parallel port for outputs, the Flashlite 186 port
|
||||||
|
* uses IO port F.
|
||||||
|
*
|
||||||
|
* \page flashC flash.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
|
||||||
|
Changes from V2.1.1
|
||||||
|
|
||||||
|
+ The stack size now uses configMINIMAL_STACK_SIZE.
|
||||||
|
+ String constants made file scope to decrease stack depth on 8051 port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "partest.h"
|
||||||
|
#include "flash.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
#define ledSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to the LED tasks. */
|
||||||
|
typedef struct LED_PARAMETERS
|
||||||
|
{
|
||||||
|
unsigned portBASE_TYPE uxLED; /*< The output the task should use. */
|
||||||
|
TickType_t xFlashRate; /*< The rate at which the LED should flash. */
|
||||||
|
} xLEDParameters;
|
||||||
|
|
||||||
|
/* The task that is created eight times - each time with a different xLEDParaemtes
|
||||||
|
structure passed in as the parameter. */
|
||||||
|
static void vLEDFlashTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* String to print if USE_STDIO is defined. */
|
||||||
|
const char * const pcTaskStartMsg = "LED flash task started.\r\n";
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
unsigned portBASE_TYPE uxLEDTask;
|
||||||
|
xLEDParameters *pxLEDParameters;
|
||||||
|
const unsigned portBASE_TYPE uxNumOfLEDs = 8;
|
||||||
|
const TickType_t xFlashRate = 125;
|
||||||
|
|
||||||
|
/* Create the eight tasks. */
|
||||||
|
for( uxLEDTask = 0; uxLEDTask < uxNumOfLEDs; ++uxLEDTask )
|
||||||
|
{
|
||||||
|
/* Create and complete the structure used to pass parameters to the next
|
||||||
|
created task. */
|
||||||
|
pxLEDParameters = ( xLEDParameters * ) pvPortMalloc( sizeof( xLEDParameters ) );
|
||||||
|
pxLEDParameters->uxLED = uxLEDTask;
|
||||||
|
pxLEDParameters->xFlashRate = ( xFlashRate + ( xFlashRate * ( TickType_t ) uxLEDTask ) );
|
||||||
|
pxLEDParameters->xFlashRate /= portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
/* Spawn the task. */
|
||||||
|
xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, ( void * ) pxLEDParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vLEDFlashTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
xLEDParameters *pxParameters;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
pxParameters = ( xLEDParameters * ) pvParameters;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
/* Delay for half the flash period then turn the LED on. */
|
||||||
|
vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 );
|
||||||
|
vParTestToggleLED( pxParameters->uxLED );
|
||||||
|
|
||||||
|
/* Delay for half the flash period then turn the LED off. */
|
||||||
|
vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 );
|
||||||
|
vParTestToggleLED( pxParameters->uxLED );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.2.3
|
||||||
|
|
||||||
|
+ The created tasks now include calls to tskYIELD(), allowing them to be used
|
||||||
|
with the cooperative scheduler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates eight tasks, each of which loops continuously performing an (emulated)
|
||||||
|
* floating point calculation.
|
||||||
|
*
|
||||||
|
* All the tasks run at the idle priority and never block or yield. This causes
|
||||||
|
* all eight tasks to time slice with the idle task. Running at the idle priority
|
||||||
|
* means that these tasks will get pre-empted any time another task is ready to run
|
||||||
|
* or a time slice occurs. More often than not the pre-emption will occur mid
|
||||||
|
* calculation, creating a good test of the schedulers context switch mechanism - a
|
||||||
|
* calculation producing an unexpected result could be a symptom of a corruption in
|
||||||
|
* the context of a task.
|
||||||
|
*
|
||||||
|
* \page FlopC flop.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "flop.h"
|
||||||
|
|
||||||
|
#define mathSTACK_SIZE ( ( unsigned short ) 512 )
|
||||||
|
#define mathNUMBER_OF_TASKS ( 8 )
|
||||||
|
|
||||||
|
/* Four tasks, each of which performs a different floating point calculation.
|
||||||
|
Each of the four is created twice. */
|
||||||
|
static void vCompetingMathTask1( void *pvParameters );
|
||||||
|
static void vCompetingMathTask2( void *pvParameters );
|
||||||
|
static void vCompetingMathTask3( void *pvParameters );
|
||||||
|
static void vCompetingMathTask4( void *pvParameters );
|
||||||
|
|
||||||
|
/* These variables are used to check that all the tasks are still running. If a
|
||||||
|
task gets a calculation wrong it will
|
||||||
|
stop incrementing its check variable. */
|
||||||
|
static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartMathTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompetingMathTask1( void *pvParameters )
|
||||||
|
{
|
||||||
|
portDOUBLE d1, d2, d3, d4;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const portDOUBLE dAnswer = ( 123.4567 + 2345.6789 ) * -918.222;
|
||||||
|
const char * const pcTaskStartMsg = "Math task 1 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Math task 1 failed.\r\n";
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
d1 = 123.4567;
|
||||||
|
d2 = 2345.6789;
|
||||||
|
d3 = -918.222;
|
||||||
|
|
||||||
|
d4 = ( d1 + d2 ) * d3;
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( fabs( d4 - dAnswer ) > 0.001 )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompetingMathTask2( void *pvParameters )
|
||||||
|
{
|
||||||
|
portDOUBLE d1, d2, d3, d4;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const portDOUBLE dAnswer = ( -389.38 / 32498.2 ) * -2.0001;
|
||||||
|
const char * const pcTaskStartMsg = "Math task 2 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Math task 2 failed.\r\n";
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
d1 = -389.38;
|
||||||
|
d2 = 32498.2;
|
||||||
|
d3 = -2.0001;
|
||||||
|
|
||||||
|
d4 = ( d1 / d2 ) * d3;
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( fabs( d4 - dAnswer ) > 0.001 )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know
|
||||||
|
this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompetingMathTask3( void *pvParameters )
|
||||||
|
{
|
||||||
|
portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const unsigned short usArraySize = 250;
|
||||||
|
unsigned short usPosition;
|
||||||
|
const char * const pcTaskStartMsg = "Math task 3 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Math task 3 failed.\r\n";
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) );
|
||||||
|
|
||||||
|
/* Keep filling an array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
dTotal1 = 0.0;
|
||||||
|
dTotal2 = 0.0;
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
pdArray[ usPosition ] = ( portDOUBLE ) usPosition + 5.5;
|
||||||
|
dTotal1 += ( portDOUBLE ) usPosition + 5.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
dTotal2 += pdArray[ usPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
dDifference = dTotal1 - dTotal2;
|
||||||
|
if( fabs( dDifference ) > 0.001 )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompetingMathTask4( void *pvParameters )
|
||||||
|
{
|
||||||
|
portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const unsigned short usArraySize = 250;
|
||||||
|
unsigned short usPosition;
|
||||||
|
const char * const pcTaskStartMsg = "Math task 4 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Math task 4 failed.\r\n";
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) );
|
||||||
|
|
||||||
|
/* Keep filling an array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
dTotal1 = 0.0;
|
||||||
|
dTotal2 = 0.0;
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
pdArray[ usPosition ] = ( portDOUBLE ) usPosition * 12.123;
|
||||||
|
dTotal1 += ( portDOUBLE ) usPosition * 12.123;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
dTotal2 += pdArray[ usPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
dDifference = dTotal1 - dTotal2;
|
||||||
|
if( fabs( dDifference ) > 0.001 )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
portBASE_TYPE xAreMathsTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
/* Keep a history of the check variables so we know if they have been incremented
|
||||||
|
since the last call. */
|
||||||
|
static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
|
||||||
|
portBASE_TYPE xReturn = pdTRUE, xTask;
|
||||||
|
|
||||||
|
/* Check the maths tasks are still running by ensuring their check variables
|
||||||
|
are still incrementing. */
|
||||||
|
for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
|
||||||
|
{
|
||||||
|
if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
|
||||||
|
{
|
||||||
|
/* The check has not incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,369 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.2.3
|
||||||
|
|
||||||
|
+ The created tasks now include calls to tskYIELD(), allowing them to be used
|
||||||
|
with the cooperative scheduler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This does the same as flop. c, but uses variables of type long instead of
|
||||||
|
* type double.
|
||||||
|
*
|
||||||
|
* As with flop. c, the tasks created in this file are a good test of the
|
||||||
|
* scheduler context switch mechanism. The processor has to access 32bit
|
||||||
|
* variables in two or four chunks (depending on the processor). The low
|
||||||
|
* priority of these tasks means there is a high probability that a context
|
||||||
|
* switch will occur mid calculation. See the flop. c documentation for
|
||||||
|
* more information.
|
||||||
|
*
|
||||||
|
* \page IntegerC integer.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.2.1
|
||||||
|
|
||||||
|
+ The constants used in the calculations are larger to ensure the
|
||||||
|
optimiser does not truncate them to 16 bits.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "integer.h"
|
||||||
|
|
||||||
|
#define intgSTACK_SIZE ( ( unsigned short ) 256 )
|
||||||
|
#define intgNUMBER_OF_TASKS ( 8 )
|
||||||
|
|
||||||
|
/* Four tasks, each of which performs a different calculation on four byte
|
||||||
|
variables. Each of the four is created twice. */
|
||||||
|
static void vCompeteingIntMathTask1( void *pvParameters );
|
||||||
|
static void vCompeteingIntMathTask2( void *pvParameters );
|
||||||
|
static void vCompeteingIntMathTask3( void *pvParameters );
|
||||||
|
static void vCompeteingIntMathTask4( void *pvParameters );
|
||||||
|
|
||||||
|
/* These variables are used to check that all the tasks are still running. If a
|
||||||
|
task gets a calculation wrong it will stop incrementing its check variable. */
|
||||||
|
static volatile unsigned short usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompeteingIntMathTask1( void *pvParameters )
|
||||||
|
{
|
||||||
|
long l1, l2, l3, l4;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const long lAnswer = ( ( long ) 74565L + ( long ) 1234567L ) * ( long ) -918L;
|
||||||
|
const char * const pcTaskStartMsg = "Integer math task 1 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Integer math task 1 failed.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
l1 = ( long ) 74565L;
|
||||||
|
l2 = ( long ) 1234567L;
|
||||||
|
l3 = ( long ) -918L;
|
||||||
|
|
||||||
|
l4 = ( l1 + l2 ) * l3;
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( l4 != lAnswer )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompeteingIntMathTask2( void *pvParameters )
|
||||||
|
{
|
||||||
|
long l1, l2, l3, l4;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const long lAnswer = ( ( long ) -389000L / ( long ) 329999L ) * ( long ) -89L;
|
||||||
|
const char * const pcTaskStartMsg = "Integer math task 2 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Integer math task 2 failed.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
l1 = -389000L;
|
||||||
|
l2 = 329999L;
|
||||||
|
l3 = -89L;
|
||||||
|
|
||||||
|
l4 = ( l1 / l2 ) * l3;
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( l4 != lAnswer )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompeteingIntMathTask3( void *pvParameters )
|
||||||
|
{
|
||||||
|
long *plArray, lTotal1, lTotal2;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const unsigned short usArraySize = ( unsigned short ) 250;
|
||||||
|
unsigned short usPosition;
|
||||||
|
const char * const pcTaskStartMsg = "Integer math task 3 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Integer math task 3 failed.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
/* Create the array we are going to use for our check calculation. */
|
||||||
|
plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) );
|
||||||
|
|
||||||
|
/* Keep filling the array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
lTotal1 = ( long ) 0;
|
||||||
|
lTotal2 = ( long ) 0;
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
plArray[ usPosition ] = ( long ) usPosition + ( long ) 5;
|
||||||
|
lTotal1 += ( long ) usPosition + ( long ) 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
lTotal2 += plArray[ usPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lTotal1 != lTotal2 )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vCompeteingIntMathTask4( void *pvParameters )
|
||||||
|
{
|
||||||
|
long *plArray, lTotal1, lTotal2;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
volatile unsigned short *pusTaskCheckVariable;
|
||||||
|
const unsigned short usArraySize = 250;
|
||||||
|
unsigned short usPosition;
|
||||||
|
const char * const pcTaskStartMsg = "Integer math task 4 started.\r\n";
|
||||||
|
const char * const pcTaskFailMsg = "Integer math task 4 failed.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( unsigned short * ) pvParameters;
|
||||||
|
|
||||||
|
/* Create the array we are going to use for our check calculation. */
|
||||||
|
plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) );
|
||||||
|
|
||||||
|
/* Keep filling the array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
lTotal1 = ( long ) 0;
|
||||||
|
lTotal2 = ( long ) 0;
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
plArray[ usPosition ] = ( long ) usPosition * ( long ) 12;
|
||||||
|
lTotal1 += ( long ) usPosition * ( long ) 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
for( usPosition = 0; usPosition < usArraySize; usPosition++ )
|
||||||
|
{
|
||||||
|
lTotal2 += plArray[ usPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( lTotal1 != lTotal2 )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcTaskFailMsg );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
/* Keep a history of the check variables so we know if they have been incremented
|
||||||
|
since the last call. */
|
||||||
|
static unsigned short usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
|
||||||
|
portBASE_TYPE xReturn = pdTRUE, xTask;
|
||||||
|
|
||||||
|
/* Check the maths tasks are still running by ensuring their check variables
|
||||||
|
are still incrementing. */
|
||||||
|
for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ )
|
||||||
|
{
|
||||||
|
if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
|
||||||
|
{
|
||||||
|
/* The check has not incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages a queue of strings that are waiting to be displayed. This is used to
|
||||||
|
* ensure mutual exclusion of console output.
|
||||||
|
*
|
||||||
|
* A task wishing to display a message will call vPrintDisplayMessage (), with a
|
||||||
|
* pointer to the string as the parameter. The pointer is posted onto the
|
||||||
|
* xPrintQueue queue.
|
||||||
|
*
|
||||||
|
* The task spawned in main. c blocks on xPrintQueue. When a message becomes
|
||||||
|
* available it calls pcPrintGetNextMessage () to obtain a pointer to the next
|
||||||
|
* string, then uses the functions defined in the portable layer FileIO. c to
|
||||||
|
* display the message.
|
||||||
|
*
|
||||||
|
* <b>NOTE:</b>
|
||||||
|
* Using console IO can disrupt real time performance - depending on the port.
|
||||||
|
* Standard C IO routines are not designed for real time applications. While
|
||||||
|
* standard IO is useful for demonstration and debugging an alternative method
|
||||||
|
* should be used if you actually require console IO as part of your application.
|
||||||
|
*
|
||||||
|
* \page PrintC print.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
static QueueHandle_t xPrintQueue;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPrintInitialise( void )
|
||||||
|
{
|
||||||
|
const unsigned portBASE_TYPE uxQueueSize = 20;
|
||||||
|
|
||||||
|
/* Create the queue on which errors will be reported. */
|
||||||
|
xPrintQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( char * ) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPrintDisplayMessage( const char * const * ppcMessageToSend )
|
||||||
|
{
|
||||||
|
#ifdef USE_STDIO
|
||||||
|
xQueueSend( xPrintQueue, ( void * ) ppcMessageToSend, ( TickType_t ) 0 );
|
||||||
|
#else
|
||||||
|
/* Stop warnings. */
|
||||||
|
( void ) ppcMessageToSend;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
const char *pcPrintGetNextMessage( TickType_t xPrintRate )
|
||||||
|
{
|
||||||
|
char *pcMessage;
|
||||||
|
|
||||||
|
if( xQueueReceive( xPrintQueue, &pcMessage, xPrintRate ) == pdPASS )
|
||||||
|
{
|
||||||
|
return pcMessage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates two sets of two tasks. The tasks within a set share a variable, access
|
||||||
|
* to which is guarded by a semaphore.
|
||||||
|
*
|
||||||
|
* Each task starts by attempting to obtain the semaphore. On obtaining a
|
||||||
|
* semaphore a task checks to ensure that the guarded variable has an expected
|
||||||
|
* value. It then clears the variable to zero before counting it back up to the
|
||||||
|
* expected value in increments of 1. After each increment the variable is checked
|
||||||
|
* to ensure it contains the value to which it was just set. When the starting
|
||||||
|
* value is again reached the task releases the semaphore giving the other task in
|
||||||
|
* the set a chance to do exactly the same thing. The starting value is high
|
||||||
|
* enough to ensure that a tick is likely to occur during the incrementing loop.
|
||||||
|
*
|
||||||
|
* An error is flagged if at any time during the process a shared variable is
|
||||||
|
* found to have a value other than that expected. Such an occurrence would
|
||||||
|
* suggest an error in the mutual exclusion mechanism by which access to the
|
||||||
|
* variable is restricted.
|
||||||
|
*
|
||||||
|
* The first set of two tasks poll their semaphore. The second set use blocking
|
||||||
|
* calls.
|
||||||
|
*
|
||||||
|
* \page SemTestC semtest.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V1.2.0:
|
||||||
|
|
||||||
|
+ The tasks that operate at the idle priority now use a lower expected
|
||||||
|
count than those running at a higher priority. This prevents the low
|
||||||
|
priority tasks from signaling an error because they have not been
|
||||||
|
scheduled enough time for each of them to count the shared variable to
|
||||||
|
the high value.
|
||||||
|
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than unsigned long.
|
||||||
|
|
||||||
|
Changes from V2.1.1
|
||||||
|
|
||||||
|
+ The stack size now uses configMINIMAL_STACK_SIZE.
|
||||||
|
+ String constants made file scope to decrease stack depth on 8051 port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo app include files. */
|
||||||
|
#include "semtest.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
/* The value to which the shared variables are counted. */
|
||||||
|
#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xfff )
|
||||||
|
#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xff )
|
||||||
|
|
||||||
|
#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
#define semtstNUM_TASKS ( 4 )
|
||||||
|
|
||||||
|
#define semtstDELAY_FACTOR ( ( TickType_t ) 10 )
|
||||||
|
|
||||||
|
/* The task function as described at the top of the file. */
|
||||||
|
static void prvSemaphoreTest( void *pvParameters );
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to each task. */
|
||||||
|
typedef struct SEMAPHORE_PARAMETERS
|
||||||
|
{
|
||||||
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
volatile unsigned long *pulSharedVariable;
|
||||||
|
TickType_t xBlockTime;
|
||||||
|
} xSemaphoreParameters;
|
||||||
|
|
||||||
|
/* Variables used to check that all the tasks are still running without errors. */
|
||||||
|
static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };
|
||||||
|
static volatile short sNextCheckVariable = 0;
|
||||||
|
|
||||||
|
/* Strings to print if USE_STDIO is defined. */
|
||||||
|
const char * const pcPollingSemaphoreTaskError = "Guarded shared variable in unexpected state.\r\n";
|
||||||
|
const char * const pcSemaphoreTaskStart = "Guarded shared variable task started.\r\n";
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority )
|
||||||
|
{
|
||||||
|
xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;
|
||||||
|
const TickType_t xBlockTime = ( TickType_t ) 100;
|
||||||
|
|
||||||
|
/* Create the structure used to pass parameters to the first two tasks. */
|
||||||
|
pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
|
||||||
|
|
||||||
|
if( pxFirstSemaphoreParameters != NULL )
|
||||||
|
{
|
||||||
|
/* Create the semaphore used by the first two tasks. */
|
||||||
|
vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore );
|
||||||
|
|
||||||
|
if( pxFirstSemaphoreParameters->xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
/* Create the variable which is to be shared by the first two tasks. */
|
||||||
|
pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
|
||||||
|
|
||||||
|
/* Initialise the share variable to the value the tasks expect. */
|
||||||
|
*( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE;
|
||||||
|
|
||||||
|
/* The first two tasks do not block on semaphore calls. */
|
||||||
|
pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Spawn the first two tasks. As they poll they operate at the idle priority. */
|
||||||
|
xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
|
||||||
|
xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do exactly the same to create the second set of tasks, only this time
|
||||||
|
provide a block time for the semaphore calls. */
|
||||||
|
pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
|
||||||
|
if( pxSecondSemaphoreParameters != NULL )
|
||||||
|
{
|
||||||
|
vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore );
|
||||||
|
|
||||||
|
if( pxSecondSemaphoreParameters->xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );
|
||||||
|
*( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;
|
||||||
|
pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSemaphoreTest( void *pvParameters )
|
||||||
|
{
|
||||||
|
xSemaphoreParameters *pxParameters;
|
||||||
|
volatile unsigned long *pulSharedVariable, ulExpectedValue;
|
||||||
|
unsigned long ulCounter;
|
||||||
|
short sError = pdFALSE, sCheckVariableToUse;
|
||||||
|
|
||||||
|
/* See which check variable to use. sNextCheckVariable is not semaphore
|
||||||
|
protected! */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
sCheckVariableToUse = sNextCheckVariable;
|
||||||
|
sNextCheckVariable++;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcSemaphoreTaskStart );
|
||||||
|
|
||||||
|
/* A structure is passed in as the parameter. This contains the shared
|
||||||
|
variable being guarded. */
|
||||||
|
pxParameters = ( xSemaphoreParameters * ) pvParameters;
|
||||||
|
pulSharedVariable = pxParameters->pulSharedVariable;
|
||||||
|
|
||||||
|
/* If we are blocking we use a much higher count to ensure loads of context
|
||||||
|
switches occur during the count. */
|
||||||
|
if( pxParameters->xBlockTime > ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Try to obtain the semaphore. */
|
||||||
|
if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )
|
||||||
|
{
|
||||||
|
/* We have the semaphore and so expect any other tasks using the
|
||||||
|
shared variable to have left it in the state we expect to find
|
||||||
|
it. */
|
||||||
|
if( *pulSharedVariable != ulExpectedValue )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcPollingSemaphoreTaskError );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the variable, then count it back up to the expected value
|
||||||
|
before releasing the semaphore. Would expect a context switch or
|
||||||
|
two during this time. */
|
||||||
|
for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ )
|
||||||
|
{
|
||||||
|
*pulSharedVariable = ulCounter;
|
||||||
|
if( *pulSharedVariable != ulCounter )
|
||||||
|
{
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcPollingSemaphoreTaskError );
|
||||||
|
}
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the semaphore, and if no errors have occurred increment the check
|
||||||
|
variable. */
|
||||||
|
if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )
|
||||||
|
{
|
||||||
|
vPrintDisplayMessage( &pcPollingSemaphoreTaskError );
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
if( sCheckVariableToUse < semtstNUM_TASKS )
|
||||||
|
{
|
||||||
|
( sCheckVariables[ sCheckVariableToUse ] )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have a block time then we are running at a priority higher
|
||||||
|
than the idle priority. This task takes a long time to complete
|
||||||
|
a cycle (deliberately so to test the guarding) so will be starving
|
||||||
|
out lower priority tasks. Block for some time to allow give lower
|
||||||
|
priority tasks some processor time. */
|
||||||
|
vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( pxParameters->xBlockTime == ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* We have not got the semaphore yet, so no point using the
|
||||||
|
processor. We are not blocking when attempting to obtain the
|
||||||
|
semaphore. */
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
portBASE_TYPE xAreSemaphoreTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };
|
||||||
|
portBASE_TYPE xTask, xReturn = pdTRUE;
|
||||||
|
|
||||||
|
for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ )
|
||||||
|
{
|
||||||
|
if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,681 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains some test scenarios that ensure tasks respond correctly
|
||||||
|
* to xTaskAbortDelay() calls.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "event_groups.h"
|
||||||
|
|
||||||
|
/* Demo includes. */
|
||||||
|
#include "AbortDelay.h"
|
||||||
|
|
||||||
|
/* This file can only be used if the functionality it tests is included in the
|
||||||
|
build. Remove the whole file if this is not the case. */
|
||||||
|
#if( INCLUDE_xTaskAbortDelay == 1 )
|
||||||
|
|
||||||
|
#if( INCLUDE_xTaskGetHandle != 1 )
|
||||||
|
#error This test file uses the xTaskGetHandle() API function so INCLUDE_xTaskGetHandle must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Task priorities. Allow these to be overridden. */
|
||||||
|
#ifndef abtCONTROLLING_PRIORITY
|
||||||
|
#define abtCONTROLLING_PRIORITY ( configMAX_PRIORITIES - 3 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef abtBLOCKING_PRIORITY
|
||||||
|
#define abtBLOCKING_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The tests that are performed. */
|
||||||
|
#define abtNOTIFY_WAIT_ABORTS 0
|
||||||
|
#define abtNOTIFY_TAKE_ABORTS 1
|
||||||
|
#define abtDELAY_ABORTS 2
|
||||||
|
#define abtDELAY_UNTIL_ABORTS 3
|
||||||
|
#define abtSEMAPHORE_TAKE_ABORTS 4
|
||||||
|
#define abtEVENT_GROUP_ABORTS 5
|
||||||
|
#define abtQUEUE_SEND_ABORTS 6
|
||||||
|
#define abtMAX_TESTS 7
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The two test tasks. The controlling task specifies which test to executed.
|
||||||
|
* More information is provided in the comments within the tasks.
|
||||||
|
*/
|
||||||
|
static void prvControllingTask( void *pvParameters );
|
||||||
|
static void prvBlockingTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test functions called by the blocking task. Each function follows the same
|
||||||
|
* pattern, but the way the task blocks is different in each case.
|
||||||
|
*
|
||||||
|
* In each function three blocking calls are made. The first and third
|
||||||
|
* blocking call is expected to time out, while the middle blocking call is
|
||||||
|
* expected to be aborted by the controlling task half way through the block
|
||||||
|
* time.
|
||||||
|
*/
|
||||||
|
static void prvTestAbortingTaskNotifyWait( void );
|
||||||
|
static void prvTestAbortingTaskNotifyTake( void );
|
||||||
|
static void prvTestAbortingTaskDelay( void );
|
||||||
|
static void prvTestAbortingTaskDelayUntil( void );
|
||||||
|
static void prvTestAbortingSemaphoreTake( void );
|
||||||
|
static void prvTestAbortingEventGroupWait( void );
|
||||||
|
static void prvTestAbortingQueueSend( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks the amount of time a task spent in the Blocked state is within the
|
||||||
|
* expected bounds.
|
||||||
|
*/
|
||||||
|
static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Used to ensure that tasks are still executing without error. */
|
||||||
|
static volatile BaseType_t xControllingCycles = 0, xBlockingCycles = 0;
|
||||||
|
static volatile BaseType_t xErrorOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Each task needs to know the other tasks handle so they can send signals to
|
||||||
|
each other. The handle is obtained from the task's name. */
|
||||||
|
static const char *pcControllingTaskName = "AbtCtrl", *pcBlockingTaskName = "AbtBlk";
|
||||||
|
|
||||||
|
/* The maximum amount of time a task will block for. */
|
||||||
|
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 100 );
|
||||||
|
const TickType_t xHalfMaxBlockTime = pdMS_TO_TICKS( 50 );
|
||||||
|
|
||||||
|
/* The actual block time is dependent on the priority of other tasks in the
|
||||||
|
system so the actual block time might be greater than that expected, but it
|
||||||
|
should be within an acceptable upper bound. */
|
||||||
|
const TickType_t xAllowableMargin = pdMS_TO_TICKS( 7 );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCreateAbortDelayTasks( void )
|
||||||
|
{
|
||||||
|
/* Create the two test tasks described above. */
|
||||||
|
xTaskCreate( prvControllingTask, pcControllingTaskName, configMINIMAL_STACK_SIZE, NULL, abtCONTROLLING_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvBlockingTask, pcBlockingTaskName, configMINIMAL_STACK_SIZE, NULL, abtBLOCKING_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvControllingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
TaskHandle_t xBlockingTask;
|
||||||
|
uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS;
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
const TickType_t xStartMargin = 2UL;
|
||||||
|
|
||||||
|
/* Just to remove compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
xBlockingTask = xTaskGetHandle( pcBlockingTaskName );
|
||||||
|
configASSERT( xBlockingTask );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Tell the secondary task to perform the next test. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
xTaskNotify( xBlockingTask, ulTestToPerform, eSetValueWithOverwrite );
|
||||||
|
|
||||||
|
/* The secondary task has a higher priority, so will now be in the
|
||||||
|
Blocked state to wait for a maximum of xMaxBlockTime. It expects that
|
||||||
|
period to complete with a timeout. It will then block for
|
||||||
|
xMaxBlockTimeAgain, but this time it expects to the block time to abort
|
||||||
|
half way through. Block until it is time to send the abort to the
|
||||||
|
secondary task. xStartMargin is used because this task takes timing
|
||||||
|
from the beginning of the test, whereas the blocking task takes timing
|
||||||
|
from the entry into the Blocked state - and as the tasks run at
|
||||||
|
different priorities, there may be some discrepancy. Also, temporarily
|
||||||
|
raise the priority of the controlling task to that of the blocking
|
||||||
|
task to minimise discrepancies. */
|
||||||
|
vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY );
|
||||||
|
vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin );
|
||||||
|
xTaskAbortDelay( xBlockingTask );
|
||||||
|
|
||||||
|
/* Reset the priority to the normal controlling priority. */
|
||||||
|
vTaskPrioritySet( NULL, abtCONTROLLING_PRIORITY );
|
||||||
|
|
||||||
|
/* Now wait to be notified that the secondary task has completed its
|
||||||
|
test. */
|
||||||
|
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* Did the entire test run for the expected time, which is two full
|
||||||
|
block times plus the half block time caused by calling
|
||||||
|
xTaskAbortDelay()? */
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, ( xMaxBlockTime + xMaxBlockTime + xHalfMaxBlockTime ) );
|
||||||
|
|
||||||
|
/* Move onto the next test. */
|
||||||
|
ulTestToPerform++;
|
||||||
|
|
||||||
|
if( ulTestToPerform >= abtMAX_TESTS )
|
||||||
|
{
|
||||||
|
ulTestToPerform = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* To indicate this task is still executing. */
|
||||||
|
xControllingCycles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvBlockingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
TaskHandle_t xControllingTask;
|
||||||
|
uint32_t ulNotificationValue;
|
||||||
|
const uint32_t ulMax = 0xffffffffUL;
|
||||||
|
|
||||||
|
/* Just to remove compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
xControllingTask = xTaskGetHandle( pcControllingTaskName );
|
||||||
|
configASSERT( xControllingTask );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait to be notified of the test that is to be performed next. */
|
||||||
|
xTaskNotifyWait( 0, ulMax, &ulNotificationValue, portMAX_DELAY );
|
||||||
|
|
||||||
|
switch( ulNotificationValue )
|
||||||
|
{
|
||||||
|
case abtNOTIFY_WAIT_ABORTS:
|
||||||
|
prvTestAbortingTaskNotifyWait();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case abtNOTIFY_TAKE_ABORTS:
|
||||||
|
prvTestAbortingTaskNotifyTake();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case abtDELAY_ABORTS:
|
||||||
|
prvTestAbortingTaskDelay();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case abtDELAY_UNTIL_ABORTS:
|
||||||
|
prvTestAbortingTaskDelayUntil();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case abtSEMAPHORE_TAKE_ABORTS:
|
||||||
|
prvTestAbortingSemaphoreTake();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case abtEVENT_GROUP_ABORTS:
|
||||||
|
prvTestAbortingEventGroupWait();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case abtQUEUE_SEND_ABORTS:
|
||||||
|
prvTestAbortingQueueSend();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Should not get here. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let the primary task know the test is complete. */
|
||||||
|
xTaskNotifyGive( xControllingTask );
|
||||||
|
|
||||||
|
/* To indicate this task is still executing. */
|
||||||
|
xBlockingCycles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingTaskDelayUntil( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart, xLastBlockTime;
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* Take a copy of the time as it is updated in the call to
|
||||||
|
vTaskDelayUntil() but its original value is needed to determine the actual
|
||||||
|
time spend in the Blocked state. */
|
||||||
|
xLastBlockTime = xTimeAtStart;
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. Again take a copy of the time as it is updated in the call to
|
||||||
|
vTaskDelayUntil() buts its original value is needed to determine the amount
|
||||||
|
of time actually spent in the Blocked state. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
xLastBlockTime = xTimeAtStart;
|
||||||
|
vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* As with the other tests, the third block period should not time out. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
xLastBlockTime = xTimeAtStart;
|
||||||
|
vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime );
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingTaskDelay( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
vTaskDelay( xMaxBlockTime );
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. */
|
||||||
|
vTaskDelay( xMaxBlockTime );
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This third delay should just time out again. */
|
||||||
|
vTaskDelay( xMaxBlockTime );
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingTaskNotifyTake( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
|
||||||
|
if( ulReturn != 0 )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. */
|
||||||
|
ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
|
||||||
|
if( ulReturn != 0 )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This third delay should just time out again. */
|
||||||
|
ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime );
|
||||||
|
if( ulReturn != 0 )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingEventGroupWait( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
EventGroupHandle_t xEventGroup;
|
||||||
|
EventBits_t xBitsToWaitFor = ( EventBits_t ) 0x01, xReturn;
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
static StaticEventGroup_t xEventGroupBuffer;
|
||||||
|
|
||||||
|
/* Create the event group. Statically allocated memory is used so the
|
||||||
|
creation cannot fail. */
|
||||||
|
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
xEventGroup = xEventGroupCreate();
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
|
||||||
|
if( xReturn != 0x00 )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. */
|
||||||
|
xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
|
||||||
|
if( xReturn != 0x00 )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This third delay should just time out again. */
|
||||||
|
xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime );
|
||||||
|
if( xReturn != 0x00 )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Not really necessary in this case, but for completeness. */
|
||||||
|
vEventGroupDelete( xEventGroup );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingQueueSend( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
const UBaseType_t xQueueLength = ( UBaseType_t ) 1;
|
||||||
|
QueueHandle_t xQueue;
|
||||||
|
uint8_t ucItemToQueue;
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
static StaticQueue_t xQueueBuffer;
|
||||||
|
static uint8_t ucQueueStorage[ sizeof( uint8_t ) ];
|
||||||
|
|
||||||
|
/* Create the queue. Statically allocated memory is used so the
|
||||||
|
creation cannot fail. */
|
||||||
|
xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
xQueue = xQueueCreate( xQueueLength, sizeof( uint8_t ) );
|
||||||
|
configASSERT( xQueue );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This function tests aborting when in the blocked state waiting to send,
|
||||||
|
so the queue must be full. There is only one space in the queue. */
|
||||||
|
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
|
||||||
|
if( xReturn != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. */
|
||||||
|
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This third delay should just time out again. */
|
||||||
|
xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Not really necessary in this case, but for completeness. */
|
||||||
|
vQueueDelete( xQueue );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingSemaphoreTake( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
static StaticSemaphore_t xSemaphoreBuffer;
|
||||||
|
|
||||||
|
/* Create the semaphore. Statically allocated memory is used so the
|
||||||
|
creation cannot fail. */
|
||||||
|
xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
xSemaphore = xSemaphoreCreateBinary();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. */
|
||||||
|
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This third delay should just time out again. */
|
||||||
|
xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Not really necessary in this case, but for completeness. */
|
||||||
|
vSemaphoreDelete( xSemaphore );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTestAbortingTaskNotifyWait( void )
|
||||||
|
{
|
||||||
|
TickType_t xTimeAtStart;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This first delay should just time out. */
|
||||||
|
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This second delay should be aborted by the primary task half way
|
||||||
|
through. */
|
||||||
|
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime );
|
||||||
|
|
||||||
|
/* Note the time before the delay so the length of the delay is known. */
|
||||||
|
xTimeAtStart = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* This third delay should just time out again. */
|
||||||
|
xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime );
|
||||||
|
if( xReturn != pdFALSE )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime )
|
||||||
|
{
|
||||||
|
TickType_t xTimeNow, xActualBlockTime;
|
||||||
|
|
||||||
|
xTimeNow = xTaskGetTickCount();
|
||||||
|
xActualBlockTime = xTimeNow - xStartTime;
|
||||||
|
|
||||||
|
/* The actual block time should not be less than the expected block time. */
|
||||||
|
if( xActualBlockTime < xExpectedBlockTime )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The actual block time can be greater than the expected block time, as it
|
||||||
|
depends on the priority of the other tasks, but it should be within an
|
||||||
|
acceptable margin. */
|
||||||
|
if( xActualBlockTime > ( xExpectedBlockTime + xAllowableMargin ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreAbortDelayTestTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static BaseType_t xLastControllingCycleCount = 0, xLastBlockingCycleCount = 0;
|
||||||
|
BaseType_t xReturn = pdPASS;
|
||||||
|
|
||||||
|
/* Have both tasks performed at least one cycle since this function was
|
||||||
|
last called? */
|
||||||
|
if( xControllingCycles == xLastControllingCycleCount )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xBlockingCycles == xLastBlockingCycleCount )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xErrorOccurred == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xLastBlockingCycleCount = xBlockingCycles;
|
||||||
|
xLastControllingCycleCount = xControllingCycles;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* INCLUDE_xTaskAbortDelay == 1 */
|
|
@ -0,0 +1,332 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates six tasks that operate on three queues as follows:
|
||||||
|
*
|
||||||
|
* The first two tasks send and receive an incrementing number to/from a queue.
|
||||||
|
* One task acts as a producer and the other as the consumer. The consumer is a
|
||||||
|
* higher priority than the producer and is set to block on queue reads. The queue
|
||||||
|
* only has space for one item - as soon as the producer posts a message on the
|
||||||
|
* queue the consumer will unblock, pre-empt the producer, and remove the item.
|
||||||
|
*
|
||||||
|
* The second two tasks work the other way around. Again the queue used only has
|
||||||
|
* enough space for one item. This time the consumer has a lower priority than the
|
||||||
|
* producer. The producer will try to post on the queue blocking when the queue is
|
||||||
|
* full. When the consumer wakes it will remove the item from the queue, causing
|
||||||
|
* the producer to unblock, pre-empt the consumer, and immediately re-fill the
|
||||||
|
* queue.
|
||||||
|
*
|
||||||
|
* The last two tasks use the same queue producer and consumer functions. This time the queue has
|
||||||
|
* enough space for lots of items and the tasks operate at the same priority. The
|
||||||
|
* producer will execute, placing items into the queue. The consumer will start
|
||||||
|
* executing when either the queue becomes full (causing the producer to block) or
|
||||||
|
* a context switch occurs (tasks of the same priority will time slice).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "BlockQ.h"
|
||||||
|
|
||||||
|
#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define blckqNUM_TASK_SETS ( 3 )
|
||||||
|
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
|
||||||
|
#error This example cannot be used if dynamic allocation is not allowed.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to the blocking queue tasks. */
|
||||||
|
typedef struct BLOCKING_QUEUE_PARAMETERS
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue; /*< The queue to be used by the task. */
|
||||||
|
TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */
|
||||||
|
volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */
|
||||||
|
} xBlockingQueueParameters;
|
||||||
|
|
||||||
|
/* Task function that creates an incrementing number and posts it on a queue. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters );
|
||||||
|
|
||||||
|
/* Task function that removes the incrementing number from a queue and checks that
|
||||||
|
it is the expected number. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters );
|
||||||
|
|
||||||
|
/* Variables which are incremented each time an item is removed from a queue, and
|
||||||
|
found to be the expected value.
|
||||||
|
These are used to check that the tasks are still running. */
|
||||||
|
static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
|
||||||
|
|
||||||
|
/* Variable which are incremented each time an item is posted on a queue. These
|
||||||
|
are used to check that the tasks are still running. */
|
||||||
|
static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartBlockingQueueTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;
|
||||||
|
const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5;
|
||||||
|
const TickType_t xBlockTime = pdMS_TO_TICKS( ( TickType_t ) 1000 );
|
||||||
|
const TickType_t xDontBlock = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Create the first two tasks as described at the top of the file. */
|
||||||
|
|
||||||
|
/* First create the structure used to pass parameters to the consumer tasks. */
|
||||||
|
pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
|
||||||
|
/* Create the queue used by the first two tasks to pass the incrementing number.
|
||||||
|
Pass a pointer to the queue in the parameter structure. */
|
||||||
|
pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) );
|
||||||
|
|
||||||
|
/* The consumer is created first so gets a block time as described above. */
|
||||||
|
pxQueueParameters1->xBlockTime = xBlockTime;
|
||||||
|
|
||||||
|
/* Pass in the variable that this task is going to increment so we can check it
|
||||||
|
is still running. */
|
||||||
|
pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] );
|
||||||
|
|
||||||
|
/* Create the structure used to pass parameters to the producer task. */
|
||||||
|
pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
|
||||||
|
/* Pass the queue to this task also, using the parameter structure. */
|
||||||
|
pxQueueParameters2->xQueue = pxQueueParameters1->xQueue;
|
||||||
|
|
||||||
|
/* The producer is not going to block - as soon as it posts the consumer will
|
||||||
|
wake and remove the item so the producer should always have room to post. */
|
||||||
|
pxQueueParameters2->xBlockTime = xDontBlock;
|
||||||
|
|
||||||
|
/* Pass in the variable that this task is going to increment so we can check
|
||||||
|
it is still running. */
|
||||||
|
pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] );
|
||||||
|
|
||||||
|
|
||||||
|
/* Note the producer has a lower priority than the consumer when the tasks are
|
||||||
|
spawned. */
|
||||||
|
xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );
|
||||||
|
xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the second two tasks as described at the top of the file. This uses
|
||||||
|
the same mechanism but reverses the task priorities. */
|
||||||
|
|
||||||
|
pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) );
|
||||||
|
pxQueueParameters3->xBlockTime = xDontBlock;
|
||||||
|
pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] );
|
||||||
|
|
||||||
|
pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters4->xQueue = pxQueueParameters3->xQueue;
|
||||||
|
pxQueueParameters4->xBlockTime = xBlockTime;
|
||||||
|
pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] );
|
||||||
|
|
||||||
|
xTaskCreate( vBlockingQueueConsumer, "QConsB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vBlockingQueueProducer, "QProdB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create the last two tasks as described above. The mechanism is again just
|
||||||
|
the same. This time both parameter structures are given a block time. */
|
||||||
|
pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( UBaseType_t ) sizeof( uint16_t ) );
|
||||||
|
pxQueueParameters5->xBlockTime = xBlockTime;
|
||||||
|
pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] );
|
||||||
|
|
||||||
|
pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );
|
||||||
|
pxQueueParameters6->xQueue = pxQueueParameters5->xQueue;
|
||||||
|
pxQueueParameters6->xBlockTime = xBlockTime;
|
||||||
|
pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] );
|
||||||
|
|
||||||
|
xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )
|
||||||
|
{
|
||||||
|
uint16_t usValue = 0;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters;
|
||||||
|
short sErrorEverOccurred = pdFALSE;
|
||||||
|
|
||||||
|
pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )
|
||||||
|
{
|
||||||
|
sErrorEverOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have successfully posted a message, so increment the variable
|
||||||
|
used to check we are still running. */
|
||||||
|
if( sErrorEverOccurred == pdFALSE )
|
||||||
|
{
|
||||||
|
( *pxQueueParameters->psCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the variable we are going to post next time round. The
|
||||||
|
consumer will expect the numbers to follow in numerical order. */
|
||||||
|
++usValue;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters )
|
||||||
|
{
|
||||||
|
uint16_t usData, usExpectedValue = 0;
|
||||||
|
xBlockingQueueParameters *pxQueueParameters;
|
||||||
|
short sErrorEverOccurred = pdFALSE;
|
||||||
|
|
||||||
|
pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )
|
||||||
|
{
|
||||||
|
if( usData != usExpectedValue )
|
||||||
|
{
|
||||||
|
/* Catch-up. */
|
||||||
|
usExpectedValue = usData;
|
||||||
|
|
||||||
|
sErrorEverOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We have successfully received a message, so increment the
|
||||||
|
variable used to check we are still running. */
|
||||||
|
if( sErrorEverOccurred == pdFALSE )
|
||||||
|
{
|
||||||
|
( *pxQueueParameters->psCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the value we expect to remove from the queue next time
|
||||||
|
round. */
|
||||||
|
++usExpectedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
{
|
||||||
|
if( pxQueueParameters->xBlockTime == 0 )
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreBlockingQueuesStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
|
||||||
|
static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 };
|
||||||
|
BaseType_t xReturn = pdPASS, xTasks;
|
||||||
|
|
||||||
|
/* Not too worried about mutual exclusion on these variables as they are 16
|
||||||
|
bits and we are only reading them. We also only care to see if they have
|
||||||
|
changed or not.
|
||||||
|
|
||||||
|
Loop through each check variable to and return pdFALSE if any are found not
|
||||||
|
to have changed since the last call. */
|
||||||
|
|
||||||
|
for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ )
|
||||||
|
{
|
||||||
|
if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ];
|
||||||
|
|
||||||
|
|
||||||
|
if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,788 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 -
|
||||||
|
* including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and
|
||||||
|
* mutex behaviour.
|
||||||
|
*
|
||||||
|
* See the comments above the prvSendFrontAndBackTest() and
|
||||||
|
* prvLowPriorityMutexTask() prototypes below for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "GenQTest.h"
|
||||||
|
|
||||||
|
#define genqQUEUE_LENGTH ( 5 )
|
||||||
|
#define intsemNO_BLOCK ( 0 )
|
||||||
|
|
||||||
|
#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()
|
||||||
|
* macros by using both to fill a queue, then reading from the queue to
|
||||||
|
* check the resultant queue order is as expected. Queue data is also
|
||||||
|
* peeked.
|
||||||
|
*/
|
||||||
|
static void prvSendFrontAndBackTest( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following three tasks are used to demonstrate the mutex behaviour.
|
||||||
|
* Each task is given a different priority to demonstrate the priority
|
||||||
|
* inheritance mechanism.
|
||||||
|
*
|
||||||
|
* The low priority task obtains a mutex. After this a high priority task
|
||||||
|
* attempts to obtain the same mutex, causing its priority to be inherited
|
||||||
|
* by the low priority task. The task with the inherited high priority then
|
||||||
|
* resumes a medium priority task to ensure it is not blocked by the medium
|
||||||
|
* priority task while it holds the inherited high priority. Once the mutex
|
||||||
|
* is returned the task with the inherited priority returns to its original
|
||||||
|
* low priority, and is therefore immediately preempted by first the high
|
||||||
|
* priority task and then the medium priority task before it can continue.
|
||||||
|
*/
|
||||||
|
static void prvLowPriorityMutexTask( void *pvParameters );
|
||||||
|
static void prvMediumPriorityMutexTask( void *pvParameters );
|
||||||
|
static void prvHighPriorityMutexTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
|
||||||
|
detected in any of the tasks. */
|
||||||
|
static volatile BaseType_t xErrorDetected = pdFALSE;
|
||||||
|
|
||||||
|
/* Counters that are incremented on each cycle of a test. This is used to
|
||||||
|
detect a stalled task - a test that is no longer running. */
|
||||||
|
static volatile uint32_t ulLoopCounter = 0;
|
||||||
|
static volatile uint32_t ulLoopCounter2 = 0;
|
||||||
|
|
||||||
|
/* The variable that is guarded by the mutex in the mutex demo tasks. */
|
||||||
|
static volatile uint32_t ulGuardedVariable = 0;
|
||||||
|
|
||||||
|
/* Handles used in the mutex test to suspend and resume the high and medium
|
||||||
|
priority mutex test tasks. */
|
||||||
|
static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartGenericQueueTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue;
|
||||||
|
SemaphoreHandle_t xMutex;
|
||||||
|
|
||||||
|
/* Create the queue that we are going to use for the
|
||||||
|
prvSendFrontAndBackTest demo. */
|
||||||
|
xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||||
|
|
||||||
|
if( xQueue != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the queue to the queue registry, if one
|
||||||
|
is in use. The queue registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||||
|
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||||
|
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||||
|
defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( xQueue, "Gen_Queue_Test" );
|
||||||
|
|
||||||
|
/* Create the demo task and pass it the queue just created. We are
|
||||||
|
passing the queue handle by value so it does not matter that it is
|
||||||
|
declared on the stack here. */
|
||||||
|
xTaskCreate( prvSendFrontAndBackTest, "GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the mutex used by the prvMutexTest task. */
|
||||||
|
xMutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
if( xMutex != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
|
||||||
|
in use. The registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate mutexes and has no purpose if a kernel aware
|
||||||
|
debugger is not being used. The call to vQueueAddToRegistry() will be
|
||||||
|
removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||||
|
defined or is defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Gen_Queue_Mutex" );
|
||||||
|
|
||||||
|
/* Create the mutex demo tasks and pass it the mutex just created. We
|
||||||
|
are passing the mutex handle by value so it does not matter that it is
|
||||||
|
declared on the stack here. */
|
||||||
|
xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
|
||||||
|
xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSendFrontAndBackTest( void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulData, ulData2;
|
||||||
|
QueueHandle_t xQueue;
|
||||||
|
|
||||||
|
#ifdef USE_STDIO
|
||||||
|
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
|
||||||
|
|
||||||
|
const char * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xQueue = ( QueueHandle_t ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* The queue is empty, so sending an item to the back of the queue
|
||||||
|
should have the same efect as sending it to the front of the queue.
|
||||||
|
|
||||||
|
First send to the front and check everything is as expected. */
|
||||||
|
xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, intsemNO_BLOCK );
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The data we sent to the queue should equal the data we just received
|
||||||
|
from the queue. */
|
||||||
|
if( ulLoopCounter != ulData )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then do the same, sending the data to the back, checking everything
|
||||||
|
is as expected. */
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, intsemNO_BLOCK );
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The data we sent to the queue should equal the data we just received
|
||||||
|
from the queue. */
|
||||||
|
if( ulLoopCounter != ulData )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Place 2, 3, 4 into the queue, adding items to the back of the queue. */
|
||||||
|
for( ulData = 2; ulData < 5; ulData++ )
|
||||||
|
{
|
||||||
|
xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now the order in the queue should be 2, 3, 4, with 2 being the first
|
||||||
|
thing to be read out. Now add 1 then 0 to the front of the queue. */
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 3 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
ulData = 1;
|
||||||
|
xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK );
|
||||||
|
ulData = 0;
|
||||||
|
xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK );
|
||||||
|
|
||||||
|
/* Now the queue should be full, and when we read the data out we
|
||||||
|
should receive 0, 1, 2, 3, 4. */
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 5 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check the data we read out is in the expected order. */
|
||||||
|
for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )
|
||||||
|
{
|
||||||
|
/* Try peeking the data first. */
|
||||||
|
if( xQueuePeek( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulData != ulData2 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now try receiving the data for real. The value should be the
|
||||||
|
same. Clobber the value first so we know we really received it. */
|
||||||
|
ulData2 = ~ulData2;
|
||||||
|
if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulData != ulData2 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The queue should now be empty again. */
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Our queue is empty once more, add 10, 11 to the back. */
|
||||||
|
ulData = 10;
|
||||||
|
if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
ulData = 11;
|
||||||
|
if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 2 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the
|
||||||
|
front. */
|
||||||
|
for( ulData = 9; ulData >= 7; ulData-- )
|
||||||
|
{
|
||||||
|
if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now check that the queue is full, and that receiving data provides
|
||||||
|
the expected sequence of 7, 8, 9, 10, 11. */
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 5 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check the data we read out is in the expected order. */
|
||||||
|
for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulData != ulData2 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLoopCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
|
||||||
|
{
|
||||||
|
/* Take the mutex. It should be available now. */
|
||||||
|
if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the guarded variable to a known start value. */
|
||||||
|
ulGuardedVariable = 0;
|
||||||
|
|
||||||
|
/* This task's priority should be as per that assigned when the task was
|
||||||
|
created. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now unsuspend the high priority task. This will attempt to take the
|
||||||
|
mutex, and block when it finds it cannot obtain it. */
|
||||||
|
vTaskResume( xHighPriorityMutexTask );
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ensure the task is reporting its priority as blocked and not
|
||||||
|
suspended (as it would have done in versions up to V7.5.3). */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* The priority of the high priority task should now have been inherited
|
||||||
|
as by now it will have attempted to get the mutex. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to set the priority of this task to the test priority -
|
||||||
|
between the idle priority and the medium/high test priorities, but the
|
||||||
|
actual priority should remain at the high priority. */
|
||||||
|
vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now unsuspend the medium priority task. This should not run as the
|
||||||
|
inherited priority of this task is above that of the medium priority
|
||||||
|
task. */
|
||||||
|
vTaskResume( xMediumPriorityMutexTask );
|
||||||
|
|
||||||
|
/* If the medium priority task did run then it will have incremented the
|
||||||
|
guarded variable. */
|
||||||
|
if( ulGuardedVariable != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take the local mutex too, so two mutexes are now held. */
|
||||||
|
if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When the semaphore is given back the priority of this task should not
|
||||||
|
yet be disinherited because the local mutex is still held. This is a
|
||||||
|
simplification to allow FreeRTOS to be integrated with middleware that
|
||||||
|
attempts to hold multiple mutexes without bloating the code with complex
|
||||||
|
algorithms. It is possible that the high priority mutex task will
|
||||||
|
execute as it shares a priority with this task. */
|
||||||
|
if( xSemaphoreGive( xMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The guarded variable is only incremented by the medium priority task,
|
||||||
|
which still should not have executed as this task should remain at the
|
||||||
|
higher priority, ensure this is the case. */
|
||||||
|
if( ulGuardedVariable != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now also give back the local mutex, taking the held count back to 0.
|
||||||
|
This time the priority of this task should be disinherited back to the
|
||||||
|
priority to which it was set while the mutex was held. This means
|
||||||
|
the medium priority task should execute and increment the guarded
|
||||||
|
variable. When this task next runs both the high and medium priority
|
||||||
|
tasks will have been suspended again. */
|
||||||
|
if( xSemaphoreGive( xLocalMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check the guarded variable did indeed increment... */
|
||||||
|
if( ulGuardedVariable != 1 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... and that the priority of this task has been disinherited to
|
||||||
|
genqMUTEX_TEST_PRIORITY. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the priority of this task back to its original value, ready for
|
||||||
|
the next loop around this test. */
|
||||||
|
vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
|
||||||
|
{
|
||||||
|
/* Take the mutex. It should be available now. */
|
||||||
|
if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the guarded variable to a known start value. */
|
||||||
|
ulGuardedVariable = 0;
|
||||||
|
|
||||||
|
/* This task's priority should be as per that assigned when the task was
|
||||||
|
created. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now unsuspend the high priority task. This will attempt to take the
|
||||||
|
mutex, and block when it finds it cannot obtain it. */
|
||||||
|
vTaskResume( xHighPriorityMutexTask );
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ensure the task is reporting its priority as blocked and not
|
||||||
|
suspended (as it would have done in versions up to V7.5.3). */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* The priority of the high priority task should now have been inherited
|
||||||
|
as by now it will have attempted to get the mutex. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now unsuspend the medium priority task. This should not run as the
|
||||||
|
inherited priority of this task is above that of the medium priority
|
||||||
|
task. */
|
||||||
|
vTaskResume( xMediumPriorityMutexTask );
|
||||||
|
|
||||||
|
/* If the medium priority task did run then it will have incremented the
|
||||||
|
guarded variable. */
|
||||||
|
if( ulGuardedVariable != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take the local mutex too, so two mutexes are now held. */
|
||||||
|
if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When the local semaphore is given back the priority of this task should
|
||||||
|
not yet be disinherited because the shared mutex is still held. This is a
|
||||||
|
simplification to allow FreeRTOS to be integrated with middleware that
|
||||||
|
attempts to hold multiple mutexes without bloating the code with complex
|
||||||
|
algorithms. It is possible that the high priority mutex task will
|
||||||
|
execute as it shares a priority with this task. */
|
||||||
|
if( xSemaphoreGive( xLocalMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The guarded variable is only incremented by the medium priority task,
|
||||||
|
which still should not have executed as this task should remain at the
|
||||||
|
higher priority, ensure this is the case. */
|
||||||
|
if( ulGuardedVariable != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now also give back the shared mutex, taking the held count back to 0.
|
||||||
|
This time the priority of this task should be disinherited back to the
|
||||||
|
priority at which it was created. This means the medium priority task
|
||||||
|
should execute and increment the guarded variable. When this task next runs
|
||||||
|
both the high and medium priority tasks will have been suspended again. */
|
||||||
|
if( xSemaphoreGive( xMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check the guarded variable did indeed increment... */
|
||||||
|
if( ulGuardedVariable != 1 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ... and that the priority of this task has been disinherited to
|
||||||
|
genqMUTEX_LOW_PRIORITY. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLowPriorityMutexTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex;
|
||||||
|
|
||||||
|
#ifdef USE_STDIO
|
||||||
|
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
|
||||||
|
|
||||||
|
const char * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The local mutex is used to check the 'mutexs held' count. */
|
||||||
|
xLocalMutex = xSemaphoreCreateMutex();
|
||||||
|
configASSERT( xLocalMutex );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* The first tests exercise the priority inheritance when two mutexes
|
||||||
|
are taken then returned in a different order to which they were
|
||||||
|
taken. */
|
||||||
|
prvTakeTwoMutexesReturnInDifferentOrder( xMutex, xLocalMutex );
|
||||||
|
|
||||||
|
/* Just to show this task is still running. */
|
||||||
|
ulLoopCounter2++;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The second tests exercise the priority inheritance when two mutexes
|
||||||
|
are taken then returned in the same order in which they were taken. */
|
||||||
|
prvTakeTwoMutexesReturnInSameOrder( xMutex, xLocalMutex );
|
||||||
|
|
||||||
|
/* Just to show this task is still running. */
|
||||||
|
ulLoopCounter2++;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvMediumPriorityMutexTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* The medium priority task starts by suspending itself. The low
|
||||||
|
priority task will unsuspend this task when required. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
/* When this task unsuspends all it does is increment the guarded
|
||||||
|
variable, this is so the low priority task knows that it has
|
||||||
|
executed. */
|
||||||
|
ulGuardedVariable++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHighPriorityMutexTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* The high priority task starts by suspending itself. The low
|
||||||
|
priority task will unsuspend this task when required. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
/* When this task unsuspends all it does is attempt to obtain
|
||||||
|
the mutex. It should find the mutex is not available so a
|
||||||
|
block time is specified. */
|
||||||
|
if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When the mutex is eventually obtained it is just given back before
|
||||||
|
returning to suspend ready for the next cycle. */
|
||||||
|
if( xSemaphoreGive( xMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreGenericQueueTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
|
||||||
|
|
||||||
|
/* If the demo task is still running then we expect the loop counters to
|
||||||
|
have incremented since this function was last called. */
|
||||||
|
if( ulLastLoopCounter == ulLoopCounter )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulLastLoopCounter2 == ulLoopCounter2 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastLoopCounter = ulLoopCounter;
|
||||||
|
ulLastLoopCounter2 = ulLoopCounter2;
|
||||||
|
|
||||||
|
/* Errors detected in the task itself will have latched xErrorDetected
|
||||||
|
to true. */
|
||||||
|
|
||||||
|
return ( BaseType_t ) !xErrorDetected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,769 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file defines one of the more complex set of demo/test tasks. They are
|
||||||
|
* designed to stress test the queue implementation though pseudo simultaneous
|
||||||
|
* multiple reads and multiple writes from both tasks of varying priority and
|
||||||
|
* interrupts. The interrupts are prioritised such to ensure that nesting
|
||||||
|
* occurs (for those ports that support it).
|
||||||
|
*
|
||||||
|
* The test ensures that, while being accessed from three tasks and two
|
||||||
|
* interrupts, all the data sent to the queues is also received from
|
||||||
|
* the same queue, and that no duplicate items are either sent or received.
|
||||||
|
* The tests also ensure that a low priority task is never able to successfully
|
||||||
|
* read from or write to a queue when a task of higher priority is attempting
|
||||||
|
* the same operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* SafeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo app includes. */
|
||||||
|
#include "IntQueue.h"
|
||||||
|
#include "IntQueueTimer.h"
|
||||||
|
|
||||||
|
#if( INCLUDE_eTaskGetState != 1 )
|
||||||
|
#error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Priorities used by test tasks. */
|
||||||
|
#ifndef intqHIGHER_PRIORITY
|
||||||
|
#define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 2 )
|
||||||
|
#endif
|
||||||
|
#define intqLOWER_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
|
||||||
|
/* The number of values to send/receive before checking that all values were
|
||||||
|
processed as expected. */
|
||||||
|
#define intqNUM_VALUES_TO_LOG ( 200 )
|
||||||
|
#define intqSHORT_DELAY ( 140 )
|
||||||
|
|
||||||
|
/* The value by which the value being sent to or received from a queue should
|
||||||
|
increment past intqNUM_VALUES_TO_LOG before we check that all values have been
|
||||||
|
sent/received correctly. This is done to ensure that all tasks and interrupts
|
||||||
|
accessing the queue have completed their accesses with the
|
||||||
|
intqNUM_VALUES_TO_LOG range. */
|
||||||
|
#define intqVALUE_OVERRUN ( 50 )
|
||||||
|
|
||||||
|
/* The delay used by the polling task. A short delay is used for code
|
||||||
|
coverage. */
|
||||||
|
#define intqONE_TICK_DELAY ( 1 )
|
||||||
|
|
||||||
|
/* Each task and interrupt is given a unique identifier. This value is used to
|
||||||
|
identify which task sent or received each value. The identifier is also used
|
||||||
|
to distinguish between two tasks that are running the same task function. */
|
||||||
|
#define intqHIGH_PRIORITY_TASK1 ( ( UBaseType_t ) 1 )
|
||||||
|
#define intqHIGH_PRIORITY_TASK2 ( ( UBaseType_t ) 2 )
|
||||||
|
#define intqLOW_PRIORITY_TASK ( ( UBaseType_t ) 3 )
|
||||||
|
#define intqFIRST_INTERRUPT ( ( UBaseType_t ) 4 )
|
||||||
|
#define intqSECOND_INTERRUPT ( ( UBaseType_t ) 5 )
|
||||||
|
#define intqQUEUE_LENGTH ( ( UBaseType_t ) 10 )
|
||||||
|
|
||||||
|
/* At least intqMIN_ACCEPTABLE_TASK_COUNT values should be sent to/received
|
||||||
|
from each queue by each task, otherwise an error is detected. */
|
||||||
|
#define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 )
|
||||||
|
|
||||||
|
/* Send the next value to the queue that is normally empty. This is called
|
||||||
|
from within the interrupts. */
|
||||||
|
#define timerNORMALLY_EMPTY_TX() \
|
||||||
|
if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \
|
||||||
|
{ \
|
||||||
|
UBaseType_t uxSavedInterruptStatus; \
|
||||||
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \
|
||||||
|
{ \
|
||||||
|
uxValueForNormallyEmptyQueue++; \
|
||||||
|
if( xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \
|
||||||
|
{ \
|
||||||
|
uxValueForNormallyEmptyQueue--; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
/* Send the next value to the queue that is normally full. This is called
|
||||||
|
from within the interrupts. */
|
||||||
|
#define timerNORMALLY_FULL_TX() \
|
||||||
|
if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \
|
||||||
|
{ \
|
||||||
|
UBaseType_t uxSavedInterruptStatus; \
|
||||||
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \
|
||||||
|
{ \
|
||||||
|
uxValueForNormallyFullQueue++; \
|
||||||
|
if( xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \
|
||||||
|
{ \
|
||||||
|
uxValueForNormallyFullQueue--; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
/* Receive a value from the normally empty queue. This is called from within
|
||||||
|
an interrupt. */
|
||||||
|
#define timerNORMALLY_EMPTY_RX() \
|
||||||
|
if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \
|
||||||
|
{ \
|
||||||
|
prvQueueAccessLogError( __LINE__ ); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive a value from the normally full queue. This is called from within
|
||||||
|
an interrupt. */
|
||||||
|
#define timerNORMALLY_FULL_RX() \
|
||||||
|
if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \
|
||||||
|
{ \
|
||||||
|
prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT ); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The two queues used by the test. */
|
||||||
|
static QueueHandle_t xNormallyEmptyQueue, xNormallyFullQueue;
|
||||||
|
|
||||||
|
/* Variables used to detect a stall in one of the tasks. */
|
||||||
|
static volatile UBaseType_t uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0;
|
||||||
|
|
||||||
|
/* Any unexpected behaviour sets xErrorStatus to fail and log the line that
|
||||||
|
caused the error in xErrorLine. */
|
||||||
|
static BaseType_t xErrorStatus = pdPASS;
|
||||||
|
static volatile UBaseType_t xErrorLine = ( UBaseType_t ) 0;
|
||||||
|
|
||||||
|
/* Used for sequencing between tasks. */
|
||||||
|
static BaseType_t xWasSuspended = pdFALSE;
|
||||||
|
|
||||||
|
/* The values that are sent to the queues. An incremented value is sent each
|
||||||
|
time to each queue. */
|
||||||
|
static volatile UBaseType_t uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0;
|
||||||
|
|
||||||
|
/* A handle to some of the tasks is required so they can be suspended/resumed. */
|
||||||
|
TaskHandle_t xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2;
|
||||||
|
|
||||||
|
/* When a value is received in a queue the value is ticked off in the array
|
||||||
|
the array position of the value is set to a the identifier of the task or
|
||||||
|
interrupt that accessed the queue. This way missing or duplicate values can be
|
||||||
|
detected. */
|
||||||
|
static uint8_t ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };
|
||||||
|
static uint8_t ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 };
|
||||||
|
|
||||||
|
/* The test tasks themselves. */
|
||||||
|
static void prvLowerPriorityNormallyEmptyTask( void *pvParameters );
|
||||||
|
static void prvLowerPriorityNormallyFullTask( void *pvParameters );
|
||||||
|
static void prvHigherPriorityNormallyEmptyTask( void *pvParameters );
|
||||||
|
static void prv1stHigherPriorityNormallyFullTask( void *pvParameters );
|
||||||
|
static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* Used to mark the positions within the ucNormallyEmptyReceivedValues and
|
||||||
|
ucNormallyFullReceivedValues arrays, while checking for duplicates. */
|
||||||
|
static void prvRecordValue_NormallyEmpty( UBaseType_t uxValue, UBaseType_t uxSource );
|
||||||
|
static void prvRecordValue_NormallyFull( UBaseType_t uxValue, UBaseType_t uxSource );
|
||||||
|
|
||||||
|
/* Logs the line on which an error occurred. */
|
||||||
|
static void prvQueueAccessLogError( UBaseType_t uxLine );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartInterruptQueueTasks( void )
|
||||||
|
{
|
||||||
|
/* Start the test tasks. */
|
||||||
|
xTaskCreate( prvHigherPriorityNormallyEmptyTask, "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 );
|
||||||
|
xTaskCreate( prvHigherPriorityNormallyEmptyTask, "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 );
|
||||||
|
xTaskCreate( prvLowerPriorityNormallyEmptyTask, "L1QRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prv1stHigherPriorityNormallyFullTask, "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 );
|
||||||
|
xTaskCreate( prv2ndHigherPriorityNormallyFullTask, "H2QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 );
|
||||||
|
xTaskCreate( prvLowerPriorityNormallyFullTask, "L2QRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Create the queues that are accessed by multiple tasks and multiple
|
||||||
|
interrupts. */
|
||||||
|
xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( UBaseType_t ) sizeof( UBaseType_t ) );
|
||||||
|
xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( UBaseType_t ) sizeof( UBaseType_t ) );
|
||||||
|
|
||||||
|
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||||
|
in use. The queue registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||||
|
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||||
|
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||||
|
defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( xNormallyFullQueue, "NormallyFull" );
|
||||||
|
vQueueAddToRegistry( xNormallyEmptyQueue, "NormallyEmpty" );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRecordValue_NormallyFull( UBaseType_t uxValue, UBaseType_t uxSource )
|
||||||
|
{
|
||||||
|
if( uxValue < intqNUM_VALUES_TO_LOG )
|
||||||
|
{
|
||||||
|
/* We don't expect to receive the same value twice, so if the value
|
||||||
|
has already been marked as received an error has occurred. */
|
||||||
|
if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log that this value has been received. */
|
||||||
|
ucNormallyFullReceivedValues[ uxValue ] = ( uint8_t ) uxSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRecordValue_NormallyEmpty( UBaseType_t uxValue, UBaseType_t uxSource )
|
||||||
|
{
|
||||||
|
if( uxValue < intqNUM_VALUES_TO_LOG )
|
||||||
|
{
|
||||||
|
/* We don't expect to receive the same value twice, so if the value
|
||||||
|
has already been marked as received an error has occurred. */
|
||||||
|
if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log that this value has been received. */
|
||||||
|
ucNormallyEmptyReceivedValues[ uxValue ] = ( uint8_t ) uxSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueAccessLogError( UBaseType_t uxLine )
|
||||||
|
{
|
||||||
|
/* Latch the line number that caused the error. */
|
||||||
|
xErrorLine = uxLine;
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHigherPriorityNormallyEmptyTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
UBaseType_t uxRxed, ux, uxTask1, uxTask2, uxInterrupts, uxErrorCount1 = 0, uxErrorCount2 = 0;
|
||||||
|
|
||||||
|
/* The timer should not be started until after the scheduler has started.
|
||||||
|
More than one task is running this code so we check the parameter value
|
||||||
|
to determine which task should start the timer. */
|
||||||
|
if( ( UBaseType_t ) pvParameters == intqHIGH_PRIORITY_TASK1 )
|
||||||
|
{
|
||||||
|
vInitialiseTimerForIntQueueTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Block waiting to receive a value from the normally empty queue.
|
||||||
|
Interrupts will write to the queue so we should receive a value. */
|
||||||
|
if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Note which value was received so we can check all expected
|
||||||
|
values are received and no values are duplicated. */
|
||||||
|
prvRecordValue_NormallyEmpty( uxRxed, ( UBaseType_t ) pvParameters );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the other task running this code gets a chance to execute. */
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
if( ( UBaseType_t ) pvParameters == intqHIGH_PRIORITY_TASK1 )
|
||||||
|
{
|
||||||
|
/* Have we received all the expected values? */
|
||||||
|
if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) )
|
||||||
|
{
|
||||||
|
vTaskSuspend( xHighPriorityNormallyEmptyTask2 );
|
||||||
|
|
||||||
|
uxTask1 = 0;
|
||||||
|
uxTask2 = 0;
|
||||||
|
uxInterrupts = 0;
|
||||||
|
|
||||||
|
/* Loop through the array, checking that both tasks have
|
||||||
|
placed values into the array, and that no values are missing.
|
||||||
|
Start at 1 as we expect position 0 to be unused. */
|
||||||
|
for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ )
|
||||||
|
{
|
||||||
|
if( ucNormallyEmptyReceivedValues[ ux ] == 0 )
|
||||||
|
{
|
||||||
|
/* A value is missing. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK1 )
|
||||||
|
{
|
||||||
|
/* Value was placed into the array by task 1. */
|
||||||
|
uxTask1++;
|
||||||
|
}
|
||||||
|
else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK2 )
|
||||||
|
{
|
||||||
|
/* Value was placed into the array by task 2. */
|
||||||
|
uxTask2++;
|
||||||
|
}
|
||||||
|
else if( ucNormallyEmptyReceivedValues[ ux ] == intqSECOND_INTERRUPT )
|
||||||
|
{
|
||||||
|
uxInterrupts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT )
|
||||||
|
{
|
||||||
|
/* Only task 2 seemed to log any values. */
|
||||||
|
uxErrorCount1++;
|
||||||
|
if( uxErrorCount1 > 2 )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxErrorCount1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT )
|
||||||
|
{
|
||||||
|
/* Only task 1 seemed to log any values. */
|
||||||
|
uxErrorCount2++;
|
||||||
|
if( uxErrorCount2 > 2 )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxErrorCount2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxInterrupts == 0 )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the array again, ready to start a new cycle. */
|
||||||
|
memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) );
|
||||||
|
|
||||||
|
uxHighPriorityLoops1++;
|
||||||
|
uxValueForNormallyEmptyQueue = 0;
|
||||||
|
|
||||||
|
/* Suspend ourselves, allowing the lower priority task to
|
||||||
|
actually receive something from the queue. Until now it
|
||||||
|
will have been prevented from doing so by the higher
|
||||||
|
priority tasks. The lower priority task will resume us
|
||||||
|
if it receives something. We will then resume the other
|
||||||
|
higher priority task. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
vTaskResume( xHighPriorityNormallyEmptyTask2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLowerPriorityNormallyEmptyTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
UBaseType_t uxValue, uxRxed;
|
||||||
|
|
||||||
|
/* The parameters are not being used so avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
|
/* A value should only be obtained when the high priority task is
|
||||||
|
suspended. */
|
||||||
|
if( eTaskGetState( xHighPriorityNormallyEmptyTask1 ) != eSuspended )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIORITY_TASK );
|
||||||
|
|
||||||
|
/* Wake the higher priority task again. */
|
||||||
|
vTaskResume( xHighPriorityNormallyEmptyTask1 );
|
||||||
|
uxLowPriorityLoops1++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Raise our priority while we send so we can preempt the higher
|
||||||
|
priority task, and ensure we get the Tx value into the queue. */
|
||||||
|
vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );
|
||||||
|
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxValueForNormallyEmptyQueue++;
|
||||||
|
uxValue = uxValueForNormallyEmptyQueue;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskPrioritySet( NULL, intqLOWER_PRIORITY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prv1stHigherPriorityNormallyFullTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
UBaseType_t uxValueToTx, ux, uxInterrupts;
|
||||||
|
|
||||||
|
/* The parameters are not being used so avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Make sure the queue starts full or near full. >> 1 as there are two
|
||||||
|
high priority tasks. */
|
||||||
|
for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxValueForNormallyFullQueue++;
|
||||||
|
uxValueToTx = uxValueForNormallyFullQueue;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxValueForNormallyFullQueue++;
|
||||||
|
uxValueToTx = uxValueForNormallyFullQueue;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* intqHIGH_PRIORITY_TASK2 is never suspended so we would not
|
||||||
|
expect it to ever time out. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow the other task running this code to run. */
|
||||||
|
taskYIELD();
|
||||||
|
|
||||||
|
/* Have all the expected values been sent to the queue? */
|
||||||
|
if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) )
|
||||||
|
{
|
||||||
|
/* Make sure the other high priority task completes its send of
|
||||||
|
any values below intqNUM_VALUE_TO_LOG. */
|
||||||
|
vTaskDelay( intqSHORT_DELAY );
|
||||||
|
|
||||||
|
vTaskSuspend( xHighPriorityNormallyFullTask2 );
|
||||||
|
|
||||||
|
if( xWasSuspended == pdTRUE )
|
||||||
|
{
|
||||||
|
/* We would have expected the other high priority task to have
|
||||||
|
set this back to false by now. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the suspended flag so an error is not logged if the other
|
||||||
|
task recognises a time out when it is unsuspended. */
|
||||||
|
xWasSuspended = pdTRUE;
|
||||||
|
|
||||||
|
/* Check interrupts are also sending. */
|
||||||
|
uxInterrupts = 0U;
|
||||||
|
|
||||||
|
/* Start at 1 as we expect position 0 to be unused. */
|
||||||
|
for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ )
|
||||||
|
{
|
||||||
|
if( ucNormallyFullReceivedValues[ ux ] == 0 )
|
||||||
|
{
|
||||||
|
/* A value was missing. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
else if( ucNormallyFullReceivedValues[ ux ] == intqSECOND_INTERRUPT )
|
||||||
|
{
|
||||||
|
uxInterrupts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxInterrupts == 0 )
|
||||||
|
{
|
||||||
|
/* No writes from interrupts were found. Are interrupts
|
||||||
|
actually running? */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the array ready for the next cycle. */
|
||||||
|
memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) );
|
||||||
|
|
||||||
|
uxHighPriorityLoops2++;
|
||||||
|
uxValueForNormallyFullQueue = 0;
|
||||||
|
|
||||||
|
/* Suspend ourselves, allowing the lower priority task to
|
||||||
|
actually receive something from the queue. Until now it
|
||||||
|
will have been prevented from doing so by the higher
|
||||||
|
priority tasks. The lower priority task will resume us
|
||||||
|
if it receives something. We will then resume the other
|
||||||
|
higher priority task. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
vTaskResume( xHighPriorityNormallyFullTask2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
UBaseType_t uxValueToTx, ux;
|
||||||
|
|
||||||
|
/* The parameters are not being used so avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Make sure the queue starts full or near full. >> 1 as there are two
|
||||||
|
high priority tasks. */
|
||||||
|
for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ )
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxValueForNormallyFullQueue++;
|
||||||
|
uxValueToTx = uxValueForNormallyFullQueue;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxValueForNormallyFullQueue++;
|
||||||
|
uxValueToTx = uxValueForNormallyFullQueue;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
if( xWasSuspended != pdTRUE )
|
||||||
|
{
|
||||||
|
/* It is ok to time out if the task has been suspended. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xWasSuspended = pdFALSE;
|
||||||
|
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLowerPriorityNormallyFullTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
UBaseType_t uxValue, uxTxed = 9999;
|
||||||
|
|
||||||
|
/* The parameters are not being used so avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if( xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
/* Should only succeed when the higher priority task is suspended */
|
||||||
|
if( eTaskGetState( xHighPriorityNormallyFullTask1 ) != eSuspended )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskResume( xHighPriorityNormallyFullTask1 );
|
||||||
|
uxLowPriorityLoops2++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Raise our priority while we receive so we can preempt the higher
|
||||||
|
priority task, and ensure we get the value from the queue. */
|
||||||
|
vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 );
|
||||||
|
|
||||||
|
if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prvRecordValue_NormallyFull( uxValue, intqLOW_PRIORITY_TASK );
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskPrioritySet( NULL, intqLOWER_PRIORITY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xFirstTimerHandler( void )
|
||||||
|
{
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
UBaseType_t uxRxedValue;
|
||||||
|
static UBaseType_t uxNextOperation = 0;
|
||||||
|
|
||||||
|
/* Called from a timer interrupt. Perform various read and write
|
||||||
|
accesses on the queues. */
|
||||||
|
|
||||||
|
uxNextOperation++;
|
||||||
|
|
||||||
|
if( uxNextOperation & ( UBaseType_t ) 0x01 )
|
||||||
|
{
|
||||||
|
timerNORMALLY_EMPTY_TX();
|
||||||
|
timerNORMALLY_EMPTY_TX();
|
||||||
|
timerNORMALLY_EMPTY_TX();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timerNORMALLY_FULL_RX();
|
||||||
|
timerNORMALLY_FULL_RX();
|
||||||
|
timerNORMALLY_FULL_RX();
|
||||||
|
}
|
||||||
|
|
||||||
|
return xHigherPriorityTaskWoken;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xSecondTimerHandler( void )
|
||||||
|
{
|
||||||
|
UBaseType_t uxRxedValue;
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
static UBaseType_t uxNextOperation = 0;
|
||||||
|
|
||||||
|
/* Called from a timer interrupt. Perform various read and write
|
||||||
|
accesses on the queues. */
|
||||||
|
|
||||||
|
uxNextOperation++;
|
||||||
|
|
||||||
|
if( uxNextOperation & ( UBaseType_t ) 0x01 )
|
||||||
|
{
|
||||||
|
timerNORMALLY_EMPTY_TX();
|
||||||
|
timerNORMALLY_EMPTY_TX();
|
||||||
|
|
||||||
|
timerNORMALLY_EMPTY_RX();
|
||||||
|
timerNORMALLY_EMPTY_RX();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timerNORMALLY_FULL_RX();
|
||||||
|
timerNORMALLY_FULL_TX();
|
||||||
|
timerNORMALLY_FULL_TX();
|
||||||
|
timerNORMALLY_FULL_TX();
|
||||||
|
}
|
||||||
|
|
||||||
|
return xHigherPriorityTaskWoken;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
BaseType_t xAreIntQueueTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static UBaseType_t uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0;
|
||||||
|
|
||||||
|
/* xErrorStatus can be set outside of this function. This function just
|
||||||
|
checks that all the tasks are still cycling. */
|
||||||
|
|
||||||
|
if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 )
|
||||||
|
{
|
||||||
|
/* The high priority 1 task has stalled. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
uxLastHighPriorityLoops1 = uxHighPriorityLoops1;
|
||||||
|
|
||||||
|
if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 )
|
||||||
|
{
|
||||||
|
/* The high priority 2 task has stalled. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
uxLastHighPriorityLoops2 = uxHighPriorityLoops2;
|
||||||
|
|
||||||
|
if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 )
|
||||||
|
{
|
||||||
|
/* The low priority 1 task has stalled. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
uxLastLowPriorityLoops1 = uxLowPriorityLoops1;
|
||||||
|
|
||||||
|
if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 )
|
||||||
|
{
|
||||||
|
/* The low priority 2 task has stalled. */
|
||||||
|
prvQueueAccessLogError( __LINE__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
uxLastLowPriorityLoops2 = uxLowPriorityLoops2;
|
||||||
|
|
||||||
|
return xErrorStatus;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,567 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Demonstrates and tests mutexes being used from an interrupt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "IntSemTest.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The priorities of the test tasks. */
|
||||||
|
#define intsemMASTER_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define intsemSLAVE_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
|
||||||
|
/* The rate at which the tick hook will give the mutex. */
|
||||||
|
#define intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ( 100 )
|
||||||
|
|
||||||
|
/* A block time of 0 means 'don't block'. */
|
||||||
|
#define intsemNO_BLOCK 0
|
||||||
|
|
||||||
|
/* The maximum count value for the counting semaphore given from an
|
||||||
|
interrupt. */
|
||||||
|
#define intsemMAX_COUNT 3
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The master is a task that receives a mutex that is given from an interrupt -
|
||||||
|
* although generally mutexes should not be used given in interrupts (and
|
||||||
|
* definitely never taken in an interrupt) there are some circumstances when it
|
||||||
|
* may be desirable.
|
||||||
|
*
|
||||||
|
* The slave task is just used by the master task to force priority inheritance
|
||||||
|
* on a mutex that is shared between the master and the slave - which is a
|
||||||
|
* separate mutex to that given by the interrupt.
|
||||||
|
*/
|
||||||
|
static void vInterruptMutexSlaveTask( void *pvParameters );
|
||||||
|
static void vInterruptMutexMasterTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A test whereby the master takes the shared and interrupt mutexes in that
|
||||||
|
* order, then gives them back in the same order, ensuring the priority
|
||||||
|
* inheritance is behaving as expected at each step.
|
||||||
|
*/
|
||||||
|
static void prvTakeAndGiveInTheSameOrder( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A test whereby the master takes the shared and interrupt mutexes in that
|
||||||
|
* order, then gives them back in the opposite order to which they were taken,
|
||||||
|
* ensuring the priority inheritance is behaving as expected at each step.
|
||||||
|
*/
|
||||||
|
static void prvTakeAndGiveInTheOppositeOrder( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A simple task that interacts with an interrupt using a counting semaphore,
|
||||||
|
* primarily for code coverage purposes.
|
||||||
|
*/
|
||||||
|
static void vInterruptCountingSemaphoreTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
|
||||||
|
detected in any of the tasks. */
|
||||||
|
static volatile BaseType_t xErrorDetected = pdFALSE;
|
||||||
|
|
||||||
|
/* Counters that are incremented on each cycle of a test. This is used to
|
||||||
|
detect a stalled task - a test that is no longer running. */
|
||||||
|
static volatile uint32_t ulMasterLoops = 0, ulCountingSemaphoreLoops = 0;
|
||||||
|
|
||||||
|
/* Handles of the test tasks that must be accessed from other test tasks. */
|
||||||
|
static TaskHandle_t xSlaveHandle;
|
||||||
|
|
||||||
|
/* A mutex which is given from an interrupt - although generally mutexes should
|
||||||
|
not be used given in interrupts (and definitely never taken in an interrupt)
|
||||||
|
there are some circumstances when it may be desirable. */
|
||||||
|
static SemaphoreHandle_t xISRMutex = NULL;
|
||||||
|
|
||||||
|
/* A counting semaphore which is given from an interrupt. */
|
||||||
|
static SemaphoreHandle_t xISRCountingSemaphore = NULL;
|
||||||
|
|
||||||
|
/* A mutex which is shared between the master and slave tasks - the master
|
||||||
|
does both sharing of this mutex with the slave and receiving a mutex from the
|
||||||
|
interrupt. */
|
||||||
|
static SemaphoreHandle_t xMasterSlaveMutex = NULL;
|
||||||
|
|
||||||
|
/* Flag that allows the master task to control when the interrupt gives or does
|
||||||
|
not give the mutex. There is no mutual exclusion on this variable, but this is
|
||||||
|
only test code and it should be fine in the 32=bit test environment. */
|
||||||
|
static BaseType_t xOkToGiveMutex = pdFALSE, xOkToGiveCountingSemaphore = pdFALSE;
|
||||||
|
|
||||||
|
/* Used to coordinate timing between tasks and the interrupt. */
|
||||||
|
const TickType_t xInterruptGivePeriod = pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartInterruptSemaphoreTasks( void )
|
||||||
|
{
|
||||||
|
/* Create the semaphores that are given from an interrupt. */
|
||||||
|
xISRMutex = xSemaphoreCreateMutex();
|
||||||
|
configASSERT( xISRMutex );
|
||||||
|
xISRCountingSemaphore = xSemaphoreCreateCounting( intsemMAX_COUNT, 0 );
|
||||||
|
configASSERT( xISRCountingSemaphore );
|
||||||
|
|
||||||
|
/* Create the mutex that is shared between the master and slave tasks (the
|
||||||
|
master receives a mutex from an interrupt and shares a mutex with the
|
||||||
|
slave. */
|
||||||
|
xMasterSlaveMutex = xSemaphoreCreateMutex();
|
||||||
|
configASSERT( xMasterSlaveMutex );
|
||||||
|
|
||||||
|
/* Create the tasks that share mutexes between then and with interrupts. */
|
||||||
|
xTaskCreate( vInterruptMutexSlaveTask, "IntMuS", configMINIMAL_STACK_SIZE, NULL, intsemSLAVE_PRIORITY, &xSlaveHandle );
|
||||||
|
xTaskCreate( vInterruptMutexMasterTask, "IntMuM", configMINIMAL_STACK_SIZE, NULL, intsemMASTER_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Create the task that blocks on the counting semaphore. */
|
||||||
|
xTaskCreate( vInterruptCountingSemaphoreTask, "IntCnt", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vInterruptMutexMasterTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Just to avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
prvTakeAndGiveInTheSameOrder();
|
||||||
|
|
||||||
|
/* Ensure not to starve out other tests. */
|
||||||
|
ulMasterLoops++;
|
||||||
|
vTaskDelay( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS );
|
||||||
|
|
||||||
|
prvTakeAndGiveInTheOppositeOrder();
|
||||||
|
|
||||||
|
/* Ensure not to starve out other tests. */
|
||||||
|
ulMasterLoops++;
|
||||||
|
vTaskDelay( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTakeAndGiveInTheSameOrder( void )
|
||||||
|
{
|
||||||
|
/* Ensure the slave is suspended, and that this task is running at the
|
||||||
|
lower priority as expected as the start conditions. */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take the semaphore that is shared with the slave. */
|
||||||
|
if( xSemaphoreTake( xMasterSlaveMutex, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This task now has the mutex. Unsuspend the slave so it too
|
||||||
|
attempts to take the mutex. */
|
||||||
|
vTaskResume( xSlaveHandle );
|
||||||
|
|
||||||
|
/* The slave has the higher priority so should now have executed and
|
||||||
|
blocked on the semaphore. */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xSlaveHandle ) == eBlocked );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* This task should now have inherited the priority of the slave
|
||||||
|
task. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now wait a little longer than the time between ISR gives to also
|
||||||
|
obtain the ISR mutex. */
|
||||||
|
xOkToGiveMutex = pdTRUE;
|
||||||
|
if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
xOkToGiveMutex = pdFALSE;
|
||||||
|
|
||||||
|
/* Attempting to take again immediately should fail as the mutex is
|
||||||
|
already held. */
|
||||||
|
if( xSemaphoreTake( xISRMutex, intsemNO_BLOCK ) != pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should still be at the priority of the slave task. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give back the ISR semaphore to ensure the priority is not
|
||||||
|
disinherited as the shared mutex (which the higher priority task is
|
||||||
|
attempting to obtain) is still held. */
|
||||||
|
if( xSemaphoreGive( xISRMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally give back the shared mutex. This time the higher priority
|
||||||
|
task should run before this task runs again - so this task should have
|
||||||
|
disinherited the priority and the higher priority task should be in the
|
||||||
|
suspended state again. */
|
||||||
|
if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* Reset the mutex ready for the next round. */
|
||||||
|
xQueueReset( xISRMutex );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTakeAndGiveInTheOppositeOrder( void )
|
||||||
|
{
|
||||||
|
/* Ensure the slave is suspended, and that this task is running at the
|
||||||
|
lower priority as expected as the start conditions. */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Take the semaphore that is shared with the slave. */
|
||||||
|
if( xSemaphoreTake( xMasterSlaveMutex, intsemNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This task now has the mutex. Unsuspend the slave so it too
|
||||||
|
attempts to take the mutex. */
|
||||||
|
vTaskResume( xSlaveHandle );
|
||||||
|
|
||||||
|
/* The slave has the higher priority so should now have executed and
|
||||||
|
blocked on the semaphore. */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xSlaveHandle ) == eBlocked );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* This task should now have inherited the priority of the slave
|
||||||
|
task. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now wait a little longer than the time between ISR gives to also
|
||||||
|
obtain the ISR mutex. */
|
||||||
|
xOkToGiveMutex = pdTRUE;
|
||||||
|
if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
xOkToGiveMutex = pdFALSE;
|
||||||
|
|
||||||
|
/* Attempting to take again immediately should fail as the mutex is
|
||||||
|
already held. */
|
||||||
|
if( xSemaphoreTake( xISRMutex, intsemNO_BLOCK ) != pdFAIL )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should still be at the priority of the slave task. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give back the shared semaphore to ensure the priority is not disinherited
|
||||||
|
as the ISR mutex is still held. The higher priority slave task should run
|
||||||
|
before this task runs again. */
|
||||||
|
if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should still be at the priority of the slave task as this task still
|
||||||
|
holds one semaphore (this is a simplification in the priority inheritance
|
||||||
|
mechanism. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give back the ISR semaphore, which should result in the priority being
|
||||||
|
disinherited as it was the last mutex held. */
|
||||||
|
if( xSemaphoreGive( xISRMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the mutex ready for the next round. */
|
||||||
|
xQueueReset( xISRMutex );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vInterruptMutexSlaveTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Just to avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* This task starts by suspending itself so when it executes can be
|
||||||
|
controlled by the master task. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
/* This task will execute when the master task already holds the mutex.
|
||||||
|
Attempting to take the mutex will place this task in the Blocked
|
||||||
|
state. */
|
||||||
|
if( xSemaphoreTake( xMasterSlaveMutex, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vInterruptCountingSemaphoreTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
BaseType_t xCount;
|
||||||
|
const TickType_t xDelay = pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ) * ( intsemMAX_COUNT + 1 );
|
||||||
|
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Expect to start with the counting semaphore empty. */
|
||||||
|
if( uxQueueMessagesWaiting( ( QueueHandle_t ) xISRCountingSemaphore ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait until it is expected that the interrupt will have filled the
|
||||||
|
counting semaphore. */
|
||||||
|
xOkToGiveCountingSemaphore = pdTRUE;
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
xOkToGiveCountingSemaphore = pdFALSE;
|
||||||
|
|
||||||
|
/* Now it is expected that the counting semaphore is full. */
|
||||||
|
if( uxQueueMessagesWaiting( ( QueueHandle_t ) xISRCountingSemaphore ) != intsemMAX_COUNT )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueSpacesAvailable( ( QueueHandle_t ) xISRCountingSemaphore ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulCountingSemaphoreLoops++;
|
||||||
|
|
||||||
|
/* Expect to be able to take the counting semaphore intsemMAX_COUNT
|
||||||
|
times. A block time of 0 is used as the semaphore should already be
|
||||||
|
there. */
|
||||||
|
xCount = 0;
|
||||||
|
while( xSemaphoreTake( xISRCountingSemaphore, 0 ) == pdPASS )
|
||||||
|
{
|
||||||
|
xCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xCount != intsemMAX_COUNT )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now raise the priority of this task so it runs immediately that the
|
||||||
|
semaphore is given from the interrupt. */
|
||||||
|
vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );
|
||||||
|
|
||||||
|
/* Block to wait for the semaphore to be given from the interrupt. */
|
||||||
|
xOkToGiveCountingSemaphore = pdTRUE;
|
||||||
|
xSemaphoreTake( xISRCountingSemaphore, portMAX_DELAY );
|
||||||
|
xSemaphoreTake( xISRCountingSemaphore, portMAX_DELAY );
|
||||||
|
xOkToGiveCountingSemaphore = pdFALSE;
|
||||||
|
|
||||||
|
/* Reset the priority so as not to disturbe other tests too much. */
|
||||||
|
vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
|
||||||
|
|
||||||
|
ulCountingSemaphoreLoops++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vInterruptSemaphorePeriodicTest( void )
|
||||||
|
{
|
||||||
|
static TickType_t xLastGiveTime = 0;
|
||||||
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
TickType_t xTimeNow;
|
||||||
|
|
||||||
|
/* No mutual exclusion on xOkToGiveMutex, but this is only test code (and
|
||||||
|
only executed on a 32-bit architecture) so ignore that in this case. */
|
||||||
|
xTimeNow = xTaskGetTickCountFromISR();
|
||||||
|
if( ( ( TickType_t ) ( xTimeNow - xLastGiveTime ) ) >= pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ) )
|
||||||
|
{
|
||||||
|
configASSERT( xISRMutex );
|
||||||
|
if( xOkToGiveMutex != pdFALSE )
|
||||||
|
{
|
||||||
|
/* Null is used as the second parameter in this give, and non-NULL
|
||||||
|
in the other gives for code coverage reasons. */
|
||||||
|
xSemaphoreGiveFromISR( xISRMutex, NULL );
|
||||||
|
|
||||||
|
/* Second give attempt should fail. */
|
||||||
|
configASSERT( xSemaphoreGiveFromISR( xISRMutex, &xHigherPriorityTaskWoken ) == pdFAIL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xOkToGiveCountingSemaphore != pdFALSE )
|
||||||
|
{
|
||||||
|
xSemaphoreGiveFromISR( xISRCountingSemaphore, &xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
xLastGiveTime = xTimeNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove compiler warnings about the value being set but not used. */
|
||||||
|
( void ) xHigherPriorityTaskWoken;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreInterruptSemaphoreTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastMasterLoopCounter = 0, ulLastCountingSemaphoreLoops = 0;
|
||||||
|
|
||||||
|
/* If the demo tasks are running then it is expected that the loop counters
|
||||||
|
will have changed since this function was last called. */
|
||||||
|
if( ulLastMasterLoopCounter == ulMasterLoops )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastMasterLoopCounter = ulMasterLoops;
|
||||||
|
|
||||||
|
if( ulLastCountingSemaphoreLoops == ulCountingSemaphoreLoops )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastCountingSemaphoreLoops = ulCountingSemaphoreLoops++;
|
||||||
|
|
||||||
|
/* Errors detected in the task itself will have latched xErrorDetected
|
||||||
|
to true. */
|
||||||
|
|
||||||
|
return ( BaseType_t ) !xErrorDetected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This version of PollQ. c is for use on systems that have limited stack
|
||||||
|
* space and no display facilities. The complete version can be found in
|
||||||
|
* the Demo/Common/Full directory.
|
||||||
|
*
|
||||||
|
* Creates two tasks that communicate over a single queue. One task acts as a
|
||||||
|
* producer, the other a consumer.
|
||||||
|
*
|
||||||
|
* The producer loops for three iteration, posting an incrementing number onto the
|
||||||
|
* queue each cycle. It then delays for a fixed period before doing exactly the
|
||||||
|
* same again.
|
||||||
|
*
|
||||||
|
* The consumer loops emptying the queue. Each item removed from the queue is
|
||||||
|
* checked to ensure it contains the expected value. When the queue is empty it
|
||||||
|
* blocks for a fixed period, then does the same again.
|
||||||
|
*
|
||||||
|
* All queue access is performed without blocking. The consumer completely empties
|
||||||
|
* the queue each time it runs so the producer should never find the queue full.
|
||||||
|
*
|
||||||
|
* An error is flagged if the consumer obtains an unexpected value or the producer
|
||||||
|
* find the queue is full.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Changes from V2.0.0
|
||||||
|
|
||||||
|
+ Delay periods are now specified using variables and constants of
|
||||||
|
TickType_t rather than uint32_t.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "PollQ.h"
|
||||||
|
|
||||||
|
#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define pollqQUEUE_SIZE ( 10 )
|
||||||
|
#define pollqPRODUCER_DELAY ( pdMS_TO_TICKS( ( TickType_t ) 200 ) )
|
||||||
|
#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) )
|
||||||
|
#define pollqNO_DELAY ( ( TickType_t ) 0 )
|
||||||
|
#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 )
|
||||||
|
#define pollqINITIAL_VALUE ( ( BaseType_t ) 0 )
|
||||||
|
|
||||||
|
/* The task that posts the incrementing number onto the queue. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters );
|
||||||
|
|
||||||
|
/* The task that empties the queue. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters );
|
||||||
|
|
||||||
|
/* Variables that are used to check that the tasks are still running with no
|
||||||
|
errors. */
|
||||||
|
static volatile BaseType_t xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartPolledQueueTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
static QueueHandle_t xPolledQueue;
|
||||||
|
|
||||||
|
/* Create the queue used by the producer and consumer. */
|
||||||
|
xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( UBaseType_t ) sizeof( uint16_t ) );
|
||||||
|
|
||||||
|
if( xPolledQueue != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||||
|
in use. The queue registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||||
|
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||||
|
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||||
|
defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( xPolledQueue, "Poll_Test_Queue" );
|
||||||
|
|
||||||
|
/* Spawn the producer and consumer. */
|
||||||
|
xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )
|
||||||
|
{
|
||||||
|
uint16_t usValue = ( uint16_t ) 0;
|
||||||
|
BaseType_t xError = pdFALSE, xLoop;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )
|
||||||
|
{
|
||||||
|
/* Send an incrementing number on the queue without blocking. */
|
||||||
|
if( xQueueSend( *( ( QueueHandle_t * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We should never find the queue full so if we get here there
|
||||||
|
has been an error. */
|
||||||
|
xError = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If an error has ever been recorded we stop incrementing the
|
||||||
|
check variable. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
xPollingProducerCount++;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the value we are going to post next time around. */
|
||||||
|
usValue++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait before we start posting again to ensure the consumer runs and
|
||||||
|
empties the queue. */
|
||||||
|
vTaskDelay( pollqPRODUCER_DELAY );
|
||||||
|
}
|
||||||
|
} /*lint !e818 Function prototype must conform to API. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters )
|
||||||
|
{
|
||||||
|
uint16_t usData, usExpectedValue = ( uint16_t ) 0;
|
||||||
|
BaseType_t xError = pdFALSE;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Loop until the queue is empty. */
|
||||||
|
while( uxQueueMessagesWaiting( *( ( QueueHandle_t * ) pvParameters ) ) )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( *( ( QueueHandle_t * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS )
|
||||||
|
{
|
||||||
|
if( usData != usExpectedValue )
|
||||||
|
{
|
||||||
|
/* This is not what we expected to receive so an error has
|
||||||
|
occurred. */
|
||||||
|
xError = pdTRUE;
|
||||||
|
|
||||||
|
/* Catch-up to the value we received so our next expected
|
||||||
|
value should again be correct. */
|
||||||
|
usExpectedValue = usData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Only increment the check variable if no errors have
|
||||||
|
occurred. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
xPollingConsumerCount++;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next time round we would expect the number to be one higher. */
|
||||||
|
usExpectedValue++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now the queue is empty we block, allowing the producer to place more
|
||||||
|
items in the queue. */
|
||||||
|
vTaskDelay( pollqCONSUMER_DELAY );
|
||||||
|
}
|
||||||
|
} /*lint !e818 Function prototype must conform to API. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running with no errors. */
|
||||||
|
BaseType_t xArePollingQueuesStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* Check both the consumer and producer poll count to check they have both
|
||||||
|
been changed since out last trip round. We do not need a critical section
|
||||||
|
around the check variables as this is called from a higher priority than
|
||||||
|
the other tasks that access the same variables. */
|
||||||
|
if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) ||
|
||||||
|
( xPollingProducerCount == pollqINITIAL_VALUE )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the check variables back down so we know if they have been
|
||||||
|
incremented the next time around. */
|
||||||
|
xPollingConsumerCount = pollqINITIAL_VALUE;
|
||||||
|
xPollingProducerCount = pollqINITIAL_VALUE;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
|
@ -0,0 +1,481 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the behaviour when data is peeked from a queue when there are
|
||||||
|
* multiple tasks blocked on the queue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "QPeek.h"
|
||||||
|
|
||||||
|
#define qpeekQUEUE_LENGTH ( 5 )
|
||||||
|
#define qpeekNO_BLOCK ( 0 )
|
||||||
|
#define qpeekSHORT_DELAY ( 10 )
|
||||||
|
|
||||||
|
#define qpeekLOW_PRIORITY ( tskIDLE_PRIORITY + 0 )
|
||||||
|
#define qpeekMEDIUM_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define qpeekHIGH_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#define qpeekHIGHEST_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following three tasks are used to demonstrate the peeking behaviour.
|
||||||
|
* Each task is given a different priority to demonstrate the order in which
|
||||||
|
* tasks are woken as data is peeked from a queue.
|
||||||
|
*/
|
||||||
|
static void prvLowPriorityPeekTask( void *pvParameters );
|
||||||
|
static void prvMediumPriorityPeekTask( void *pvParameters );
|
||||||
|
static void prvHighPriorityPeekTask( void *pvParameters );
|
||||||
|
static void prvHighestPriorityPeekTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
|
||||||
|
detected in any of the tasks. */
|
||||||
|
static volatile BaseType_t xErrorDetected = pdFALSE;
|
||||||
|
|
||||||
|
/* Counter that is incremented on each cycle of a test. This is used to
|
||||||
|
detect a stalled task - a test that is no longer running. */
|
||||||
|
static volatile uint32_t ulLoopCounter = 0;
|
||||||
|
|
||||||
|
/* Handles to the test tasks. */
|
||||||
|
TaskHandle_t xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartQueuePeekTasks( void )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue;
|
||||||
|
|
||||||
|
/* Create the queue that we are going to use for the test/demo. */
|
||||||
|
xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||||
|
|
||||||
|
if( xQueue != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||||
|
in use. The queue registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||||
|
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||||
|
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||||
|
defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( xQueue, "QPeek_Test_Queue" );
|
||||||
|
|
||||||
|
/* Create the demo tasks and pass it the queue just created. We are
|
||||||
|
passing the queue handle by value so it does not matter that it is declared
|
||||||
|
on the stack here. */
|
||||||
|
xTaskCreate( prvLowPriorityPeekTask, "PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvMediumPriorityPeekTask, "PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask );
|
||||||
|
xTaskCreate( prvHighPriorityPeekTask, "PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask );
|
||||||
|
xTaskCreate( prvHighestPriorityPeekTask, "PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHighestPriorityPeekTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters;
|
||||||
|
uint32_t ulValue;
|
||||||
|
|
||||||
|
#ifdef USE_STDIO
|
||||||
|
{
|
||||||
|
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
|
||||||
|
|
||||||
|
const char * const pcTaskStartMsg = "Queue peek test started.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Try peeking from the queue. The queue should be empty so we will
|
||||||
|
block, allowing the high priority task to execute. */
|
||||||
|
if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to have received something by the time we unblock. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we reach here the high and medium priority tasks should still
|
||||||
|
be blocked on the queue. We unblocked because the low priority task
|
||||||
|
wrote a value to the queue, which we should have peeked. Peeking the
|
||||||
|
data (rather than receiving it) will leave the data on the queue, so
|
||||||
|
the high priority task should then have also been unblocked, but not
|
||||||
|
yet executed. */
|
||||||
|
if( ulValue != 0x11223344 )
|
||||||
|
{
|
||||||
|
/* We did not receive the expected value. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||||
|
{
|
||||||
|
/* The message should have been left on the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we are going to actually receive the data, so when the high
|
||||||
|
priority task runs it will find the queue empty and return to the
|
||||||
|
blocked state. */
|
||||||
|
ulValue = 0;
|
||||||
|
if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to receive the value. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulValue != 0x11223344 )
|
||||||
|
{
|
||||||
|
/* We did not receive the expected value - which should have been
|
||||||
|
the same value as was peeked. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we will block again as the queue is once more empty. The low
|
||||||
|
priority task can then execute again. */
|
||||||
|
if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to have received something by the time we unblock. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we get here the low priority task should have again written to the
|
||||||
|
queue. */
|
||||||
|
if( ulValue != 0x01234567 )
|
||||||
|
{
|
||||||
|
/* We did not receive the expected value. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||||
|
{
|
||||||
|
/* The message should have been left on the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only peeked the data, so suspending ourselves now should enable
|
||||||
|
the high priority task to also peek the data. The high priority task
|
||||||
|
will have been unblocked when we peeked the data as we left the data
|
||||||
|
in the queue. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* This time we are going to do the same as the above test, but the
|
||||||
|
high priority task is going to receive the data, rather than peek it.
|
||||||
|
This means that the medium priority task should never peek the value. */
|
||||||
|
if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulValue != 0xaabbaabb )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHighPriorityPeekTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters;
|
||||||
|
uint32_t ulValue;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Try peeking from the queue. The queue should be empty so we will
|
||||||
|
block, allowing the medium priority task to execute. Both the high
|
||||||
|
and highest priority tasks will then be blocked on the queue. */
|
||||||
|
if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to have received something by the time we unblock. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we get here the highest priority task should have peeked the data
|
||||||
|
(unblocking this task) then suspended (allowing this task to also peek
|
||||||
|
the data). */
|
||||||
|
if( ulValue != 0x01234567 )
|
||||||
|
{
|
||||||
|
/* We did not receive the expected value. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||||
|
{
|
||||||
|
/* The message should have been left on the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only peeked the data, so suspending ourselves now should enable
|
||||||
|
the medium priority task to also peek the data. The medium priority task
|
||||||
|
will have been unblocked when we peeked the data as we left the data
|
||||||
|
in the queue. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
|
||||||
|
/* This time we are going actually receive the value, so the medium
|
||||||
|
priority task will never peek the data - we removed it from the queue. */
|
||||||
|
if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulValue != 0xaabbaabb )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvMediumPriorityPeekTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters;
|
||||||
|
uint32_t ulValue;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Try peeking from the queue. The queue should be empty so we will
|
||||||
|
block, allowing the low priority task to execute. The highest, high
|
||||||
|
and medium priority tasks will then all be blocked on the queue. */
|
||||||
|
if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to have received something by the time we unblock. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When we get here the high priority task should have peeked the data
|
||||||
|
(unblocking this task) then suspended (allowing this task to also peek
|
||||||
|
the data). */
|
||||||
|
if( ulValue != 0x01234567 )
|
||||||
|
{
|
||||||
|
/* We did not receive the expected value. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 1 )
|
||||||
|
{
|
||||||
|
/* The message should have been left on the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just so we know the test is still running. */
|
||||||
|
ulLoopCounter++;
|
||||||
|
|
||||||
|
/* Now we can suspend ourselves so the low priority task can execute
|
||||||
|
again. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLowPriorityPeekTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters;
|
||||||
|
uint32_t ulValue;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Write some data to the queue. This should unblock the highest
|
||||||
|
priority task that is waiting to peek data from the queue. */
|
||||||
|
ulValue = 0x11223344;
|
||||||
|
if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We were expecting the queue to be empty so we should not of
|
||||||
|
had a problem writing to the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* By the time we get here the data should have been removed from
|
||||||
|
the queue. */
|
||||||
|
if( uxQueueMessagesWaiting( xQueue ) != 0 )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write another value to the queue, again waking the highest priority
|
||||||
|
task that is blocked on the queue. */
|
||||||
|
ulValue = 0x01234567;
|
||||||
|
if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We were expecting the queue to be empty so we should not of
|
||||||
|
had a problem writing to the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All the other tasks should now have successfully peeked the data.
|
||||||
|
The data is still in the queue so we should be able to receive it. */
|
||||||
|
ulValue = 0;
|
||||||
|
if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to receive the data. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulValue != 0x01234567 )
|
||||||
|
{
|
||||||
|
/* We did not receive the expected value. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lets just delay a while as this is an intensive test as we don't
|
||||||
|
want to starve other tests of processing time. */
|
||||||
|
vTaskDelay( qpeekSHORT_DELAY );
|
||||||
|
|
||||||
|
/* Unsuspend the other tasks so we can repeat the test - this time
|
||||||
|
however not all the other tasks will peek the data as the high
|
||||||
|
priority task is actually going to remove it from the queue. Send
|
||||||
|
to front is used just to be different. As the queue is empty it
|
||||||
|
makes no difference to the result. */
|
||||||
|
vTaskResume( xMediumPriorityTask );
|
||||||
|
vTaskResume( xHighPriorityTask );
|
||||||
|
vTaskResume( xHighestPriorityTask );
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ulValue = 0xaabbaabb;
|
||||||
|
if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We were expecting the queue to be empty so we should not of
|
||||||
|
had a problem writing to the queue. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This time we should find that the queue is empty. The high priority
|
||||||
|
task actually removed the data rather than just peeking it. */
|
||||||
|
if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
|
/* We expected to receive the data. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unsuspend the highest and high priority tasks so we can go back
|
||||||
|
and repeat the whole thing. The medium priority task should not be
|
||||||
|
suspended as it was not able to peek the data in this last case. */
|
||||||
|
vTaskResume( xHighPriorityTask );
|
||||||
|
vTaskResume( xHighestPriorityTask );
|
||||||
|
|
||||||
|
/* Lets just delay a while as this is an intensive test as we don't
|
||||||
|
want to starve other tests of processing time. */
|
||||||
|
vTaskDelay( qpeekSHORT_DELAY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreQueuePeekTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastLoopCounter = 0;
|
||||||
|
|
||||||
|
/* If the demo task is still running then we expect the loopcounter to
|
||||||
|
have incremented since this function was last called. */
|
||||||
|
if( ulLastLoopCounter == ulLoopCounter )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastLoopCounter = ulLoopCounter;
|
||||||
|
|
||||||
|
/* Errors detected in the task itself will have latched xErrorDetected
|
||||||
|
to true. */
|
||||||
|
|
||||||
|
return ( BaseType_t ) !xErrorDetected;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,272 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic task to demonstrate the xQueueOverwrite() function. See the comments
|
||||||
|
* in the function itself.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "QueueOverwrite.h"
|
||||||
|
|
||||||
|
/* A block time of 0 just means "don't block". */
|
||||||
|
#define qoDONT_BLOCK 0
|
||||||
|
|
||||||
|
/* Number of times to overwrite the value in the queue. */
|
||||||
|
#define qoLOOPS 5
|
||||||
|
|
||||||
|
/* The task that uses the queue. */
|
||||||
|
static void prvQueueOverwriteTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* Variable that is incremented on each loop of prvQueueOverwriteTask() provided
|
||||||
|
prvQueueOverwriteTask() has not found any errors. */
|
||||||
|
static uint32_t ulLoopCounter = 0;
|
||||||
|
|
||||||
|
/* Set to pdFALSE if an error is discovered by the
|
||||||
|
vQueueOverwritePeriodicISRDemo() function. */
|
||||||
|
static BaseType_t xISRTestStatus = pdPASS;
|
||||||
|
|
||||||
|
/* The queue that is accessed from the ISR. The queue accessed by the task is
|
||||||
|
created inside the task itself. */
|
||||||
|
static QueueHandle_t xISRQueue = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartQueueOverwriteTask( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
const UBaseType_t uxQueueLength = 1;
|
||||||
|
|
||||||
|
/* Create the queue used by the ISR. xQueueOverwriteFromISR() should only
|
||||||
|
be used on queues that have a length of 1. */
|
||||||
|
xISRQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) );
|
||||||
|
|
||||||
|
/* Create the test task. The queue used by the test task is created inside
|
||||||
|
the task itself. */
|
||||||
|
xTaskCreate( prvQueueOverwriteTask, "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueOverwriteTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
QueueHandle_t xTaskQueue;
|
||||||
|
const UBaseType_t uxQueueLength = 1;
|
||||||
|
uint32_t ulValue, ulStatus = pdPASS, x;
|
||||||
|
|
||||||
|
/* The parameter is not used. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Create the queue. xQueueOverwrite() should only be used on queues that
|
||||||
|
have a length of 1. */
|
||||||
|
xTaskQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) );
|
||||||
|
configASSERT( xTaskQueue );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* The queue is empty. Writing to the queue then reading from the queue
|
||||||
|
should return the item written. */
|
||||||
|
ulValue = 10;
|
||||||
|
xQueueOverwrite( xTaskQueue, &ulValue );
|
||||||
|
|
||||||
|
ulValue = 0;
|
||||||
|
xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );
|
||||||
|
|
||||||
|
if( ulValue != 10 )
|
||||||
|
{
|
||||||
|
ulStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now try writing to the queue several times. Each time the value
|
||||||
|
in the queue should get overwritten. */
|
||||||
|
for( x = 0; x < qoLOOPS; x++ )
|
||||||
|
{
|
||||||
|
/* Write to the queue. */
|
||||||
|
xQueueOverwrite( xTaskQueue, &x );
|
||||||
|
|
||||||
|
/* Check the value in the queue is that written, even though the
|
||||||
|
queue was not necessarily empty. */
|
||||||
|
xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK );
|
||||||
|
if( ulValue != x )
|
||||||
|
{
|
||||||
|
ulStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There should always be one item in the queue. */
|
||||||
|
if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength )
|
||||||
|
{
|
||||||
|
ulStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty the queue again. */
|
||||||
|
xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );
|
||||||
|
|
||||||
|
if( uxQueueMessagesWaiting( xTaskQueue ) != 0 )
|
||||||
|
{
|
||||||
|
ulStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulStatus != pdFAIL )
|
||||||
|
{
|
||||||
|
/* Increment a counter to show this task is still running without
|
||||||
|
error. */
|
||||||
|
ulLoopCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsQueueOverwriteTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
if( xISRTestStatus != pdPASS )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( ulLoopCounter > 0 )
|
||||||
|
{
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task has either stalled of discovered an error. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLoopCounter = 0;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vQueueOverwritePeriodicISRDemo( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulCallCount = 0;
|
||||||
|
const uint32_t ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL;
|
||||||
|
uint32_t ulRx;
|
||||||
|
|
||||||
|
/* This function should be called from an interrupt, such as the tick hook
|
||||||
|
function vApplicationTickHook(). */
|
||||||
|
|
||||||
|
configASSERT( xISRQueue );
|
||||||
|
|
||||||
|
switch( ulCallCount )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* The queue is empty. Write ulTx1 to the queue. In this demo the
|
||||||
|
last parameter is not used because there are no tasks blocked on
|
||||||
|
this queue. */
|
||||||
|
xQueueOverwriteFromISR( xISRQueue, &ulTx1, NULL );
|
||||||
|
|
||||||
|
/* Peek the queue to check it holds the expected value. */
|
||||||
|
xQueuePeekFromISR( xISRQueue, &ulRx );
|
||||||
|
if( ulRx != ulTx1 )
|
||||||
|
{
|
||||||
|
xISRTestStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
/* The queue already holds ulTx1. Overwrite the value in the queue
|
||||||
|
with ulTx2. */
|
||||||
|
xQueueOverwriteFromISR( xISRQueue, &ulTx2, NULL );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
/* Read from the queue to empty the queue again. The value read
|
||||||
|
should be ulTx2. */
|
||||||
|
xQueueReceiveFromISR( xISRQueue, &ulRx, NULL );
|
||||||
|
|
||||||
|
if( ulRx != ulTx2 )
|
||||||
|
{
|
||||||
|
xISRTestStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the next case in the switch statement above next time this function
|
||||||
|
is called. */
|
||||||
|
ulCallCount++;
|
||||||
|
|
||||||
|
if( ulCallCount >= ulNumberOfSwitchCases )
|
||||||
|
{
|
||||||
|
/* Go back to the start. */
|
||||||
|
ulCallCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,738 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the use of queue sets.
|
||||||
|
*
|
||||||
|
* A receive task creates a number of queues and adds them to a queue set before
|
||||||
|
* blocking on the queue set receive. A transmit task and (optionally) an
|
||||||
|
* interrupt repeatedly unblocks the receive task by sending messages to the
|
||||||
|
* queues in a pseudo random order. The receive task removes the messages from
|
||||||
|
* the queues and flags an error if the received message does not match that
|
||||||
|
* expected. The task sends values in the range 0 to
|
||||||
|
* queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range
|
||||||
|
* queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo includes. */
|
||||||
|
#include "QueueSet.h"
|
||||||
|
|
||||||
|
/* The number of queues that are created and added to the queue set. */
|
||||||
|
#define queuesetNUM_QUEUES_IN_SET 3
|
||||||
|
|
||||||
|
/* The length of each created queue. */
|
||||||
|
#define queuesetQUEUE_LENGTH 3
|
||||||
|
|
||||||
|
/* Block times used in this demo. A block time or 0 means "don't block". */
|
||||||
|
#define queuesetSHORT_DELAY 200
|
||||||
|
#define queuesetDONT_BLOCK 0
|
||||||
|
|
||||||
|
/* Messages are sent in incrementing order from both a task and an interrupt.
|
||||||
|
The task sends values in the range 0 to 0xfffe, and the interrupt sends values
|
||||||
|
in the range of 0xffff to ULONG_MAX. */
|
||||||
|
#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL
|
||||||
|
|
||||||
|
/* The priorities used in this demo. */
|
||||||
|
#define queuesetLOW_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define queuesetMEDIUM_PRIORITY ( queuesetLOW_PRIORITY + 1 )
|
||||||
|
|
||||||
|
/* For test purposes the priority of the sending task is changed after every
|
||||||
|
queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */
|
||||||
|
#define queuesetPRIORITY_CHANGE_LOOPS ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 2 )
|
||||||
|
|
||||||
|
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */
|
||||||
|
#define queuesetISR_TX_PERIOD ( 100UL )
|
||||||
|
|
||||||
|
/* A delay inserted when the Tx task changes its priority to be above the idle
|
||||||
|
task priority to ensure the idle priority tasks get some CPU time before the
|
||||||
|
next iteration of the queue set Tx task. */
|
||||||
|
#define queuesetTX_LOOP_DELAY pdMS_TO_TICKS( ( TickType_t ) 200 )
|
||||||
|
|
||||||
|
/* The allowable maximum deviation between a received value and the expected
|
||||||
|
received value. A deviation will occur when data is received from a queue
|
||||||
|
inside an ISR in between a task receiving from a queue and the task checking
|
||||||
|
the received value. */
|
||||||
|
#define queuesetALLOWABLE_RX_DEVIATION 3
|
||||||
|
|
||||||
|
/* Ignore values that are at the boundaries of allowable values to make the
|
||||||
|
testing of limits easier (don't have to deal with wrapping values). */
|
||||||
|
#define queuesetIGNORED_BOUNDARY ( queuesetALLOWABLE_RX_DEVIATION * 2 )
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eEqualPriority = 0, /* Tx and Rx tasks have the same priority. */
|
||||||
|
eTxHigherPriority, /* The priority of the Tx task is above that of the Rx task. */
|
||||||
|
eTxLowerPriority /* The priority of the Tx task is below that of the Rx task. */
|
||||||
|
} eRelativePriorities;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The task that periodically sends to the queue set.
|
||||||
|
*/
|
||||||
|
static void prvQueueSetSendingTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The task that reads from the queue set.
|
||||||
|
*/
|
||||||
|
static void prvQueueSetReceivingTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the value received from a queue is the expected value. Some values
|
||||||
|
* originate from the send task, some values originate from the ISR, with the
|
||||||
|
* range of the value being used to distinguish between the two message
|
||||||
|
* sources.
|
||||||
|
*/
|
||||||
|
static void prvCheckReceivedValue( uint32_t ulReceived );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For purposes of test coverage, functions that read from and write to a
|
||||||
|
* queue set from an ISR respectively.
|
||||||
|
*/
|
||||||
|
static void prvReceiveFromQueueInSetFromISR( void );
|
||||||
|
static void prvSendToQueueInSetFromISR( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the queues and add them to a queue set before resuming the Tx
|
||||||
|
* task.
|
||||||
|
*/
|
||||||
|
static void prvSetupTest( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks a value received from a queue falls within the range of expected
|
||||||
|
* values.
|
||||||
|
*/
|
||||||
|
static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived, uint32_t ulExpectedReceived );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increase test coverage by occasionally change the priorities of the two tasks
|
||||||
|
* relative to each other. */
|
||||||
|
static void prvChangeRelativePriorities( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local pseudo random number seed and return functions. Used to avoid calls
|
||||||
|
* to the standard library.
|
||||||
|
*/
|
||||||
|
static size_t prvRand( void );
|
||||||
|
static void prvSRand( size_t uxSeed );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queues that are added to the set. */
|
||||||
|
static QueueHandle_t xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
|
||||||
|
/* Counts how many times each queue in the set is used to ensure all the
|
||||||
|
queues are used. */
|
||||||
|
static uint32_t ulQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
|
||||||
|
/* The handle of the queue set to which the queues are added. */
|
||||||
|
static QueueSetHandle_t xQueueSet;
|
||||||
|
|
||||||
|
/* If the prvQueueSetReceivingTask() task has not detected any errors then
|
||||||
|
it increments ulCycleCounter on each iteration.
|
||||||
|
xAreQueueSetTasksStillRunning() returns pdPASS if the value of
|
||||||
|
ulCycleCounter has changed between consecutive calls, and pdFALSE if
|
||||||
|
ulCycleCounter has stopped incrementing (indicating an error condition). */
|
||||||
|
static volatile uint32_t ulCycleCounter = 0UL;
|
||||||
|
|
||||||
|
/* Set to pdFAIL if an error is detected by any queue set task.
|
||||||
|
ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */
|
||||||
|
static volatile BaseType_t xQueueSetTasksStatus = pdPASS;
|
||||||
|
|
||||||
|
/* Just a flag to let the function that writes to a queue from an ISR know that
|
||||||
|
the queues are setup and can be used. */
|
||||||
|
static volatile BaseType_t xSetupComplete = pdFALSE;
|
||||||
|
|
||||||
|
/* The value sent to the queue from the ISR is file scope so the
|
||||||
|
xAreQueeuSetTasksStillRunning() function can check it is incrementing as
|
||||||
|
expected. */
|
||||||
|
static volatile uint32_t ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
|
||||||
|
/* Used by the pseudo random number generator. */
|
||||||
|
static size_t uxNextRand = 0;
|
||||||
|
|
||||||
|
/* The task handles are stored so their priorities can be changed. */
|
||||||
|
TaskHandle_t xQueueSetSendingTask, xQueueSetReceivingTask;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartQueueSetTasks( void )
|
||||||
|
{
|
||||||
|
/* Create the tasks. */
|
||||||
|
xTaskCreate( prvQueueSetSendingTask, "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );
|
||||||
|
|
||||||
|
if( xQueueSetSendingTask != NULL )
|
||||||
|
{
|
||||||
|
xTaskCreate( prvQueueSetReceivingTask, "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask );
|
||||||
|
|
||||||
|
/* It is important that the sending task does not attempt to write to a
|
||||||
|
queue before the queue has been created. It is therefore placed into
|
||||||
|
the suspended state before the scheduler has started. It is resumed by
|
||||||
|
the receiving task after the receiving task has created the queues and
|
||||||
|
added the queues to the queue set. */
|
||||||
|
vTaskSuspend( xQueueSetSendingTask );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreQueueSetTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastCycleCounter, ulLastISRTxValue = 0;
|
||||||
|
static uint32_t ulLastQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
BaseType_t xReturn = pdPASS, x;
|
||||||
|
|
||||||
|
if( ulLastCycleCounter == ulCycleCounter )
|
||||||
|
{
|
||||||
|
/* The cycle counter is no longer being incremented. Either one of the
|
||||||
|
tasks is stalled or an error has been detected. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastCycleCounter = ulCycleCounter;
|
||||||
|
|
||||||
|
/* Ensure that all the queues in the set have been used. This ensures the
|
||||||
|
test is working as intended and guards against the rand() in the Tx task
|
||||||
|
missing some values. */
|
||||||
|
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
||||||
|
{
|
||||||
|
if( ulLastQueueUsedCounter[ x ] == ulQueueUsedCounter[ x ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastQueueUsedCounter[ x ] = ulQueueUsedCounter[ x ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the global status flag. */
|
||||||
|
if( xQueueSetTasksStatus != pdPASS )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the ISR is still sending values to the queues too. */
|
||||||
|
if( ulISRTxValue == ulLastISRTxValue )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulLastISRTxValue = ulISRTxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueSetSendingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulTaskTxValue = 0;
|
||||||
|
size_t uxQueueToWriteTo;
|
||||||
|
QueueHandle_t xQueueInUse;
|
||||||
|
|
||||||
|
/* Remove compiler warning about the unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Seed mini pseudo random number generator. */
|
||||||
|
prvSRand( ( size_t ) &ulTaskTxValue );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Generate the index for the queue to which a value is to be sent. */
|
||||||
|
uxQueueToWriteTo = prvRand() % queuesetNUM_QUEUES_IN_SET;
|
||||||
|
xQueueInUse = xQueues[ uxQueueToWriteTo ];
|
||||||
|
|
||||||
|
/* Note which index is being written to to ensure all the queues are
|
||||||
|
used. */
|
||||||
|
( ulQueueUsedCounter[ uxQueueToWriteTo ] )++;
|
||||||
|
|
||||||
|
/* Send to the queue to unblock the task that is waiting for data to
|
||||||
|
arrive on a queue within the queue set to which this queue belongs. */
|
||||||
|
if( xQueueSendToBack( xQueueInUse, &ulTaskTxValue, portMAX_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* The send should always pass as an infinite block time was
|
||||||
|
used. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ulTaskTxValue++;
|
||||||
|
|
||||||
|
/* If the Tx value has reached the range used by the ISR then set it
|
||||||
|
back to 0. */
|
||||||
|
if( ulTaskTxValue == queuesetINITIAL_ISR_TX_VALUE )
|
||||||
|
{
|
||||||
|
ulTaskTxValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase test coverage by occasionally change the priorities of the
|
||||||
|
two tasks relative to each other. */
|
||||||
|
prvChangeRelativePriorities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvChangeRelativePriorities( void )
|
||||||
|
{
|
||||||
|
static UBaseType_t ulLoops = 0;
|
||||||
|
static eRelativePriorities ePriorities = eEqualPriority;
|
||||||
|
|
||||||
|
/* Occasionally change the task priority relative to the priority of
|
||||||
|
the receiving task. */
|
||||||
|
ulLoops++;
|
||||||
|
if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS )
|
||||||
|
{
|
||||||
|
ulLoops = 0;
|
||||||
|
|
||||||
|
switch( ePriorities )
|
||||||
|
{
|
||||||
|
case eEqualPriority:
|
||||||
|
/* Both tasks are running with medium priority. Now lower the
|
||||||
|
priority of the receiving task so the Tx task has the higher
|
||||||
|
relative priority. */
|
||||||
|
vTaskPrioritySet( xQueueSetReceivingTask, queuesetLOW_PRIORITY );
|
||||||
|
ePriorities = eTxHigherPriority;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eTxHigherPriority:
|
||||||
|
/* The Tx task is running with a higher priority than the Rx
|
||||||
|
task. Switch the priorities around so the Rx task has the
|
||||||
|
higher relative priority. */
|
||||||
|
vTaskPrioritySet( xQueueSetReceivingTask, queuesetMEDIUM_PRIORITY );
|
||||||
|
vTaskPrioritySet( xQueueSetSendingTask, queuesetLOW_PRIORITY );
|
||||||
|
ePriorities = eTxLowerPriority;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eTxLowerPriority:
|
||||||
|
/* The Tx task is running with a lower priority than the Rx
|
||||||
|
task. Make the priorities equal again. */
|
||||||
|
vTaskPrioritySet( xQueueSetSendingTask, queuesetMEDIUM_PRIORITY );
|
||||||
|
ePriorities = eEqualPriority;
|
||||||
|
|
||||||
|
/* When both tasks are using a non-idle priority the queue set
|
||||||
|
tasks will starve idle priority tasks of execution time - so
|
||||||
|
relax a bit before the next iteration to minimise the impact. */
|
||||||
|
vTaskDelay( queuesetTX_LOOP_DELAY );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueSetReceivingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulReceived;
|
||||||
|
QueueHandle_t xActivatedQueue;
|
||||||
|
TickType_t xBlockTime;
|
||||||
|
|
||||||
|
/* Remove compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Create the queues and add them to the queue set before resuming the Tx
|
||||||
|
task. */
|
||||||
|
prvSetupTest();
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* For test coverage reasons, the block time is dependent on the
|
||||||
|
priority of this task - which changes during the test. When the task
|
||||||
|
is at the idle priority it polls the queue set. */
|
||||||
|
if( uxTaskPriorityGet( NULL ) == tskIDLE_PRIORITY )
|
||||||
|
{
|
||||||
|
xBlockTime = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xBlockTime = portMAX_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for a message to arrive on one of the queues in the set. */
|
||||||
|
xActivatedQueue = xQueueSelectFromSet( xQueueSet, portMAX_DELAY );
|
||||||
|
|
||||||
|
if( xActivatedQueue == NULL )
|
||||||
|
{
|
||||||
|
if( xBlockTime != 0 )
|
||||||
|
{
|
||||||
|
/* This should not happen as an infinite delay was used. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reading from the queue should pass with a zero block time as
|
||||||
|
this task will only run when something has been posted to a task
|
||||||
|
in the queue set. */
|
||||||
|
if( xQueueReceive( xActivatedQueue, &ulReceived, queuesetDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the value received was the value expected. This function
|
||||||
|
manipulates file scope data and is also called from an ISR, hence
|
||||||
|
the critical section. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
prvCheckReceivedValue( ulReceived );
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
if( xQueueSetTasksStatus == pdPASS )
|
||||||
|
{
|
||||||
|
ulCycleCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vQueueSetAccessQueueSetFromISR( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulCallCount = 0;
|
||||||
|
|
||||||
|
/* xSetupComplete is set to pdTRUE when the queues have been created and
|
||||||
|
are available for use. */
|
||||||
|
if( xSetupComplete == pdTRUE )
|
||||||
|
{
|
||||||
|
/* It is intended that this function is called from the tick hook
|
||||||
|
function, so each call is one tick period apart. */
|
||||||
|
ulCallCount++;
|
||||||
|
if( ulCallCount > queuesetISR_TX_PERIOD )
|
||||||
|
{
|
||||||
|
ulCallCount = 0;
|
||||||
|
|
||||||
|
/* First attempt to read from the queue set. */
|
||||||
|
prvReceiveFromQueueInSetFromISR();
|
||||||
|
|
||||||
|
/* Then write to the queue set. */
|
||||||
|
prvSendToQueueInSetFromISR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckReceivedValue( uint32_t ulReceived )
|
||||||
|
{
|
||||||
|
static uint32_t ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
|
||||||
|
/* Values are received in tasks and interrupts. It is likely that the
|
||||||
|
receiving task will sometimes get preempted by the receiving interrupt
|
||||||
|
between reading a value from the queue and calling this function. When
|
||||||
|
that happens, if the receiving interrupt calls this function the values
|
||||||
|
will get passed into this function slightly out of order. For that
|
||||||
|
reason the value passed in is tested against a small range of expected
|
||||||
|
values, rather than a single absolute value. To make the range testing
|
||||||
|
easier values in the range limits are ignored. */
|
||||||
|
|
||||||
|
/* If the received value is equal to or greater than
|
||||||
|
queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */
|
||||||
|
if( ulReceived >= queuesetINITIAL_ISR_TX_VALUE )
|
||||||
|
{
|
||||||
|
/* The value was sent from the ISR. */
|
||||||
|
if( ( ulReceived - queuesetINITIAL_ISR_TX_VALUE ) < queuesetIGNORED_BOUNDARY )
|
||||||
|
{
|
||||||
|
/* The value received is at the lower limit of the expected range.
|
||||||
|
Don't test it and expect to receive one higher next time. */
|
||||||
|
}
|
||||||
|
else if( ( ULONG_MAX - ulReceived ) <= queuesetIGNORED_BOUNDARY )
|
||||||
|
{
|
||||||
|
/* The value received is at the higher limit of the expected range.
|
||||||
|
Don't test it and expect to wrap soon. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check the value against its expected value range. */
|
||||||
|
if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromISR ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( xQueueSetTasksStatus );
|
||||||
|
|
||||||
|
/* It is expected to receive an incrementing number. */
|
||||||
|
ulExpectedReceivedFromISR++;
|
||||||
|
if( ulExpectedReceivedFromISR == 0 )
|
||||||
|
{
|
||||||
|
ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The value was sent from the Tx task. */
|
||||||
|
if( ulReceived < queuesetIGNORED_BOUNDARY )
|
||||||
|
{
|
||||||
|
/* The value received is at the lower limit of the expected range.
|
||||||
|
Don't test it, and expect to receive one higher next time. */
|
||||||
|
}
|
||||||
|
else if( ( ( queuesetINITIAL_ISR_TX_VALUE - 1 ) - ulReceived ) <= queuesetIGNORED_BOUNDARY )
|
||||||
|
{
|
||||||
|
/* The value received is at the higher limit of the expected range.
|
||||||
|
Don't test it and expect to wrap soon. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check the value against its expected value range. */
|
||||||
|
if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromTask ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( xQueueSetTasksStatus );
|
||||||
|
|
||||||
|
/* It is expected to receive an incrementing number. */
|
||||||
|
ulExpectedReceivedFromTask++;
|
||||||
|
if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE )
|
||||||
|
{
|
||||||
|
ulExpectedReceivedFromTask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived, uint32_t ulExpectedReceived )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn = pdPASS;
|
||||||
|
|
||||||
|
if( ulReceived > ulExpectedReceived )
|
||||||
|
{
|
||||||
|
configASSERT( ( ulReceived - ulExpectedReceived ) <= queuesetALLOWABLE_RX_DEVIATION );
|
||||||
|
if( ( ulReceived - ulExpectedReceived ) > queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configASSERT( ( ulExpectedReceived - ulReceived ) <= queuesetALLOWABLE_RX_DEVIATION );
|
||||||
|
if( ( ulExpectedReceived - ulReceived ) > queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvReceiveFromQueueInSetFromISR( void )
|
||||||
|
{
|
||||||
|
QueueSetMemberHandle_t xActivatedQueue;
|
||||||
|
uint32_t ulReceived;
|
||||||
|
|
||||||
|
/* See if any of the queues in the set contain data. */
|
||||||
|
xActivatedQueue = xQueueSelectFromSetFromISR( xQueueSet );
|
||||||
|
|
||||||
|
if( xActivatedQueue != NULL )
|
||||||
|
{
|
||||||
|
/* Reading from the queue for test purposes only. */
|
||||||
|
if( xQueueReceiveFromISR( xActivatedQueue, &ulReceived, NULL ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* Data should have been available as the handle was returned from
|
||||||
|
xQueueSelectFromSetFromISR(). */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the value received was the value expected. */
|
||||||
|
prvCheckReceivedValue( ulReceived );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSendToQueueInSetFromISR( void )
|
||||||
|
{
|
||||||
|
static BaseType_t xQueueToWriteTo = 0;
|
||||||
|
|
||||||
|
if( xQueueSendFromISR( xQueues[ xQueueToWriteTo ], ( void * ) &ulISRTxValue, NULL ) == pdPASS )
|
||||||
|
{
|
||||||
|
ulISRTxValue++;
|
||||||
|
|
||||||
|
/* If the Tx value has wrapped then set it back to its initial value. */
|
||||||
|
if( ulISRTxValue == 0UL )
|
||||||
|
{
|
||||||
|
ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use a different queue next time. */
|
||||||
|
xQueueToWriteTo++;
|
||||||
|
if( xQueueToWriteTo >= queuesetNUM_QUEUES_IN_SET )
|
||||||
|
{
|
||||||
|
xQueueToWriteTo = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTest( void )
|
||||||
|
{
|
||||||
|
BaseType_t x;
|
||||||
|
uint32_t ulValueToSend = 0;
|
||||||
|
|
||||||
|
/* Ensure the queues are created and the queue set configured before the
|
||||||
|
sending task is unsuspended.
|
||||||
|
|
||||||
|
First Create the queue set such that it will be able to hold a message for
|
||||||
|
every space in every queue in the set. */
|
||||||
|
xQueueSet = xQueueCreateSet( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH );
|
||||||
|
|
||||||
|
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
||||||
|
{
|
||||||
|
/* Create the queue and add it to the set. The queue is just holding
|
||||||
|
uint32_t value. */
|
||||||
|
xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||||
|
configASSERT( xQueues[ x ] );
|
||||||
|
if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The queue has now been added to the queue set and cannot be added to
|
||||||
|
another. */
|
||||||
|
if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdFAIL )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to remove a queue from a queue set it does not belong
|
||||||
|
to (NULL being passed as the queue set in this case). */
|
||||||
|
if( xQueueRemoveFromSet( xQueues[ 0 ], NULL ) != pdFAIL )
|
||||||
|
{
|
||||||
|
/* It is not possible to successfully remove a queue from a queue
|
||||||
|
set it does not belong to. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to remove a queue from the queue set it does belong to. */
|
||||||
|
if( xQueueRemoveFromSet( xQueues[ 0 ], xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* It should be possible to remove the queue from the queue set it
|
||||||
|
does belong to. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add an item to the queue before attempting to add it back into the
|
||||||
|
set. */
|
||||||
|
xQueueSend( xQueues[ 0 ], ( void * ) &ulValueToSend, 0 );
|
||||||
|
if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdFAIL )
|
||||||
|
{
|
||||||
|
/* Should not be able to add a non-empty queue to a set. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the item from the queue before adding the queue back into the
|
||||||
|
set so the dynamic tests can begin. */
|
||||||
|
xQueueReceive( xQueues[ 0 ], &ulValueToSend, 0 );
|
||||||
|
if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* If the queue was successfully removed from the queue set then it
|
||||||
|
should be possible to add it back in again. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task that sends to the queues is not running yet, so attempting to
|
||||||
|
read from the queue set should fail. */
|
||||||
|
if( xQueueSelectFromSet( xQueueSet, queuesetSHORT_DELAY ) != NULL )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resume the task that writes to the queues. */
|
||||||
|
vTaskResume( xQueueSetSendingTask );
|
||||||
|
|
||||||
|
/* Let the ISR access the queues also. */
|
||||||
|
xSetupComplete = pdTRUE;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static size_t prvRand( void )
|
||||||
|
{
|
||||||
|
uxNextRand = ( uxNextRand * ( size_t ) 1103515245 ) + ( size_t ) 12345;
|
||||||
|
return ( uxNextRand / ( size_t ) 65536 ) % ( size_t ) 32768;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSRand( size_t uxSeed )
|
||||||
|
{
|
||||||
|
uxNextRand = uxSeed;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the use of queue sets.
|
||||||
|
*
|
||||||
|
* A receive task creates a number of queues and adds them to a queue set before
|
||||||
|
* blocking on the queue set receive. A transmit task and (optionally) an
|
||||||
|
* interrupt repeatedly unblocks the receive task by sending messages to the
|
||||||
|
* queues in a pseudo random order. The receive task removes the messages from
|
||||||
|
* the queues and flags an error if the received message does not match that
|
||||||
|
* expected. The task sends values in the range 0 to
|
||||||
|
* queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range
|
||||||
|
* queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo includes. */
|
||||||
|
#include "QueueSetPolling.h"
|
||||||
|
|
||||||
|
/* The length of each created queue. */
|
||||||
|
#define setpollQUEUE_LENGTH 10
|
||||||
|
|
||||||
|
/* Block times used in this demo. A block time or 0 means "don't block". */
|
||||||
|
#define setpollDONT_BLOCK 0
|
||||||
|
|
||||||
|
/* The ISR sends to the queue every setpollISR_TX_PERIOD ticks. */
|
||||||
|
#define queuesetISR_TX_PERIOD ( 50UL )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The task that reads from the queue set.
|
||||||
|
*/
|
||||||
|
static void prvQueueSetReceivingTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue that is added to the set. */
|
||||||
|
static QueueHandle_t xQueue = NULL;
|
||||||
|
|
||||||
|
/* The handle of the queue set to which the queue is added. */
|
||||||
|
static QueueSetHandle_t xQueueSet = NULL;
|
||||||
|
|
||||||
|
/* Set to pdFAIL if an error is detected by any queue set task.
|
||||||
|
ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */
|
||||||
|
static volatile BaseType_t xQueueSetPollStatus = pdPASS;
|
||||||
|
|
||||||
|
/* Counter used to ensure the task is still running. */
|
||||||
|
static uint32_t ulCycleCounter = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartQueueSetPollingTask( void )
|
||||||
|
{
|
||||||
|
/* Create the queue that is added to the set, the set, and add the queue to
|
||||||
|
the set. */
|
||||||
|
xQueue = xQueueCreate( setpollQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||||
|
xQueueSet = xQueueCreateSet( setpollQUEUE_LENGTH );
|
||||||
|
|
||||||
|
if( ( xQueue != NULL ) && ( xQueueSet != NULL ) )
|
||||||
|
{
|
||||||
|
xQueueAddToSet( xQueue, xQueueSet );
|
||||||
|
|
||||||
|
/* Create the task. */
|
||||||
|
xTaskCreate( prvQueueSetReceivingTask, "SetPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueSetReceivingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulReceived, ulExpected = 0;
|
||||||
|
QueueHandle_t xActivatedQueue;
|
||||||
|
|
||||||
|
/* Remove compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Is a message waiting? A block time is not used to ensure the queue
|
||||||
|
set is polled while it is being written to from an interrupt. */
|
||||||
|
xActivatedQueue = xQueueSelectFromSet( xQueueSet, setpollDONT_BLOCK );
|
||||||
|
|
||||||
|
if( xActivatedQueue != NULL )
|
||||||
|
{
|
||||||
|
/* Reading from the queue should pass with a zero block time as
|
||||||
|
this task will only run when something has been posted to a task
|
||||||
|
in the queue set. */
|
||||||
|
if( xQueueReceive( xActivatedQueue, &ulReceived, setpollDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetPollStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulReceived == ulExpected )
|
||||||
|
{
|
||||||
|
ulExpected++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xQueueSetPollStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xQueueSetPollStatus == pdPASS )
|
||||||
|
{
|
||||||
|
ulCycleCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vQueueSetPollingInterruptAccess( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulCallCount = 0, ulValueToSend = 0;
|
||||||
|
|
||||||
|
/* It is intended that this function is called from the tick hook
|
||||||
|
function, so each call is one tick period apart. */
|
||||||
|
ulCallCount++;
|
||||||
|
if( ulCallCount > queuesetISR_TX_PERIOD )
|
||||||
|
{
|
||||||
|
ulCallCount = 0;
|
||||||
|
|
||||||
|
if( xQueueSendFromISR( xQueue, ( void * ) &ulValueToSend, NULL ) == pdPASS )
|
||||||
|
{
|
||||||
|
/* Send the next value next time. */
|
||||||
|
ulValueToSend++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreQueueSetPollTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastCycleCounter = 0;
|
||||||
|
|
||||||
|
if( ulLastCycleCounter == ulCycleCounter )
|
||||||
|
{
|
||||||
|
xQueueSetPollStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulLastCycleCounter = ulCycleCounter;
|
||||||
|
|
||||||
|
return xQueueSetPollStatus;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,603 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the behaviour of direct task notifications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
|
||||||
|
#define notifyTASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||||
|
#define notifyUINT32_MAX ( ( uint32_t ) 0xffffffff )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of the task that gets notified.
|
||||||
|
*/
|
||||||
|
static void prvNotifiedTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Performs a few initial tests that can be done prior to creating the second
|
||||||
|
* task.
|
||||||
|
*/
|
||||||
|
static void prvSingleTaskTests( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Software timer callback function from which xTaskNotify() is called.
|
||||||
|
*/
|
||||||
|
static void prvNotifyingTimer( TimerHandle_t xTimer );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility function to create pseudo random numbers.
|
||||||
|
*/
|
||||||
|
static UBaseType_t prvRand( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Used to latch errors during the test's execution. */
|
||||||
|
static BaseType_t xErrorStatus = pdPASS;
|
||||||
|
|
||||||
|
/* Used to ensure the task has not stalled. */
|
||||||
|
static volatile uint32_t ulNotifyCycleCount = 0;
|
||||||
|
|
||||||
|
/* The handle of the task that receives the notifications. */
|
||||||
|
static TaskHandle_t xTaskToNotify = NULL;
|
||||||
|
|
||||||
|
/* Used to count the notifications sent to the task from a software timer and
|
||||||
|
the number of notifications received by the task from the software timer. The
|
||||||
|
two should stay synchronised. */
|
||||||
|
static uint32_t ulTimerNotificationsReceived = 0UL, ulTimerNotificationsSent = 0UL;
|
||||||
|
|
||||||
|
/* The timer used to notify the task. */
|
||||||
|
static TimerHandle_t xTimer = NULL;
|
||||||
|
|
||||||
|
/* Used by the pseudo random number generating function. */
|
||||||
|
static size_t uxNextRand = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartTaskNotifyTask( void )
|
||||||
|
{
|
||||||
|
/* Create the task that performs some tests by itself, then loops around
|
||||||
|
being notified by both a software timer and an interrupt. */
|
||||||
|
xTaskCreate( prvNotifiedTask, "Notified", configMINIMAL_STACK_SIZE, NULL, notifyTASK_PRIORITY, &xTaskToNotify );
|
||||||
|
|
||||||
|
/* Pseudo seed the random number generator. */
|
||||||
|
uxNextRand = ( size_t ) prvRand;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSingleTaskTests( void )
|
||||||
|
{
|
||||||
|
const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );
|
||||||
|
BaseType_t xReturned;
|
||||||
|
uint32_t ulNotifiedValue, ulLoop, ulNotifyingValue, ulPreviousValue, ulExpectedValue;
|
||||||
|
TickType_t xTimeOnEntering;
|
||||||
|
const uint32_t ulFirstNotifiedConst = 100001UL, ulSecondNotifiedValueConst = 5555UL, ulMaxLoops = 5UL;
|
||||||
|
const uint32_t ulBit0 = 0x01UL, ulBit1 = 0x02UL;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
Check blocking when there are no notifications. */
|
||||||
|
xTimeOnEntering = xTaskGetTickCount();
|
||||||
|
xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, xTicksToWait );
|
||||||
|
|
||||||
|
/* Should have blocked for the entire block time. */
|
||||||
|
if( ( xTaskGetTickCount() - xTimeOnEntering ) < xTicksToWait )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
configASSERT( ulNotifiedValue == 0UL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
Check no blocking when notifications are pending. First notify itself -
|
||||||
|
this would not be a normal thing to do and is done here for test purposes
|
||||||
|
only. */
|
||||||
|
xReturned = xTaskNotifyAndQuery( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite, &ulPreviousValue );
|
||||||
|
|
||||||
|
/* Even through the 'without overwrite' action was used the update should
|
||||||
|
have been successful. */
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
|
||||||
|
/* No bits should have been pending previously. */
|
||||||
|
configASSERT( ulPreviousValue == 0 );
|
||||||
|
|
||||||
|
/* The task should now have a notification pending, and so not time out. */
|
||||||
|
xTimeOnEntering = xTaskGetTickCount();
|
||||||
|
xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, xTicksToWait );
|
||||||
|
|
||||||
|
if( ( xTaskGetTickCount() - xTimeOnEntering ) >= xTicksToWait )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task should have been notified, and the notified value should
|
||||||
|
be equal to ulFirstNotifiedConst. */
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ulFirstNotifiedConst );
|
||||||
|
|
||||||
|
/* Incremented to show the task is still running. */
|
||||||
|
ulNotifyCycleCount++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check the non-overwriting functionality. The notification is done twice
|
||||||
|
using two different notification values. The action says don't overwrite so
|
||||||
|
only the first notification should pass and the value read back should also
|
||||||
|
be that used with the first notification. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithoutOverwrite );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
|
||||||
|
/* Waiting for the notification should now return immediately so a block
|
||||||
|
time of zero is used. */
|
||||||
|
xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ulFirstNotifiedConst );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Do the same again, only this time use the overwriting version. This time
|
||||||
|
both notifications should pass, and the value written the second time should
|
||||||
|
overwrite the value written the first time, and so be the value that is read
|
||||||
|
back. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithOverwrite );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithOverwrite );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check notifications with no action pass without updating the value. Even
|
||||||
|
though ulFirstNotifiedConst is used as the value the value read back should
|
||||||
|
remain at ulSecondNotifiedConst. */
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eNoAction );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check incrementing values. Send ulMaxLoop increment notifications, then
|
||||||
|
ensure the received value is as expected - which should be
|
||||||
|
ulSecondNotificationValueConst plus how ever many times to loop iterated. */
|
||||||
|
for( ulLoop = 0; ulLoop < ulMaxLoops; ulLoop++ )
|
||||||
|
{
|
||||||
|
xReturned = xTaskNotify( xTaskToNotify, 0, eIncrement );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
}
|
||||||
|
|
||||||
|
xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ( ulSecondNotifiedValueConst + ulMaxLoops ) );
|
||||||
|
|
||||||
|
/* Should not be any notifications pending now. */
|
||||||
|
xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check all bits can be set by notifying the task with one additional bit set
|
||||||
|
on each notification, and exiting the loop when all the bits are found to be
|
||||||
|
set. As there are 32-bits the loop should execute 32 times before all the
|
||||||
|
bits are found to be set. */
|
||||||
|
ulNotifyingValue = 0x01;
|
||||||
|
ulLoop = 0;
|
||||||
|
|
||||||
|
/* Start with all bits clear. */
|
||||||
|
xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Set the next bit in the task's notified value. */
|
||||||
|
xTaskNotify( xTaskToNotify, ulNotifyingValue, eSetBits );
|
||||||
|
|
||||||
|
/* Wait for the notified value - which of course will already be
|
||||||
|
available. Don't clear the bits on entry or exit as this loop is exited
|
||||||
|
when all the bits are set. */
|
||||||
|
xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
|
||||||
|
ulLoop++;
|
||||||
|
|
||||||
|
/* Use the next bit on the next iteration around this loop. */
|
||||||
|
ulNotifyingValue <<= 1UL;
|
||||||
|
|
||||||
|
} while ( ulNotifiedValue != notifyUINT32_MAX );
|
||||||
|
|
||||||
|
/* As a 32-bit value was used the loop should have executed 32 times before
|
||||||
|
all the bits were set. */
|
||||||
|
configASSERT( ulLoop == 32 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Check bits are cleared on entry but not on exit when a notification fails
|
||||||
|
to arrive before timing out - both with and without a timeout value. Wait
|
||||||
|
for the notification again - but this time it is not given by anything and
|
||||||
|
should return pdFAIL. The parameters are set to clear bit zero on entry and
|
||||||
|
bit one on exit. As no notification was received only the bit cleared on
|
||||||
|
entry should actually get cleared. */
|
||||||
|
xReturned = xTaskNotifyWait( ulBit0, ulBit1, &ulNotifiedValue, xTicksToWait );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
|
||||||
|
/* Notify the task with no action so as not to update the bits even though
|
||||||
|
notifyUINT32_MAX is used as the notification value. */
|
||||||
|
xTaskNotify( xTaskToNotify, notifyUINT32_MAX, eNoAction );
|
||||||
|
|
||||||
|
/* Reading back the value should should find bit 0 is clear, as this was
|
||||||
|
cleared on entry, but bit 1 is not clear as it will not have been cleared on
|
||||||
|
exit as no notification was received. */
|
||||||
|
xReturned = xTaskNotifyWait( 0x00UL, 0x00UL, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdPASS );
|
||||||
|
configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~ulBit0 ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Now try clearing the bit on exit. For that to happen a notification must be
|
||||||
|
received, so the task is notified first. */
|
||||||
|
xTaskNotify( xTaskToNotify, 0, eNoAction );
|
||||||
|
xTaskNotifyWait( 0x00, ulBit1, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
/* However as the bit is cleared on exit, after the returned notification
|
||||||
|
value is set, the returned notification value should not have the bit
|
||||||
|
cleared... */
|
||||||
|
configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~ulBit0 ) );
|
||||||
|
|
||||||
|
/* ...but reading the value back again should find that the bit was indeed
|
||||||
|
cleared internally. The returned value should be pdFAIL however as nothing
|
||||||
|
has notified the task in the mean time. */
|
||||||
|
xReturned = xTaskNotifyWait( 0x00, 0x00, &ulNotifiedValue, 0 );
|
||||||
|
configASSERT( xReturned == pdFAIL );
|
||||||
|
configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~( ulBit0 | ulBit1 ) ) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Now try querying the previus value while notifying a task. */
|
||||||
|
xTaskNotifyAndQuery( xTaskToNotify, 0x00, eSetBits, &ulPreviousValue );
|
||||||
|
configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~( ulBit0 | ulBit1 ) ) );
|
||||||
|
|
||||||
|
/* Clear all bits. */
|
||||||
|
xTaskNotifyWait( 0x00, notifyUINT32_MAX, &ulNotifiedValue, 0 );
|
||||||
|
xTaskNotifyAndQuery( xTaskToNotify, 0x00, eSetBits, &ulPreviousValue );
|
||||||
|
configASSERT( ulPreviousValue == 0 );
|
||||||
|
|
||||||
|
ulExpectedValue = 0;
|
||||||
|
for( ulLoop = 0x01; ulLoop < 0x80UL; ulLoop <<= 1UL )
|
||||||
|
{
|
||||||
|
/* Set the next bit up, and expect to receive the last bits set (so
|
||||||
|
the previous value will not yet have the bit being set this time
|
||||||
|
around). */
|
||||||
|
xTaskNotifyAndQuery( xTaskToNotify, ulLoop, eSetBits, &ulPreviousValue );
|
||||||
|
configASSERT( ulExpectedValue == ulPreviousValue );
|
||||||
|
ulExpectedValue |= ulLoop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
Clear the previous notifications. */
|
||||||
|
xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 );
|
||||||
|
|
||||||
|
/* The task should not have any notifications pending, so an attempt to clear
|
||||||
|
the notification state should fail. */
|
||||||
|
configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE );
|
||||||
|
|
||||||
|
/* Get the task to notify itself. This is not a normal thing to do, and is
|
||||||
|
only done here for test purposes. */
|
||||||
|
xTaskNotifyAndQuery( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite, &ulPreviousValue );
|
||||||
|
|
||||||
|
/* Now the notification state should be eNotified, so it should now be
|
||||||
|
possible to clear the notification state. */
|
||||||
|
configASSERT( xTaskNotifyStateClear( NULL ) == pdTRUE );
|
||||||
|
configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Incremented to show the task is still running. */
|
||||||
|
ulNotifyCycleCount++;
|
||||||
|
|
||||||
|
/* Leave all bits cleared. */
|
||||||
|
xTaskNotifyWait( notifyUINT32_MAX, 0, NULL, 0 );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvNotifyingTimer( TimerHandle_t xNotUsed )
|
||||||
|
{
|
||||||
|
( void ) xNotUsed;
|
||||||
|
|
||||||
|
xTaskNotifyGive( xTaskToNotify );
|
||||||
|
|
||||||
|
/* This value is also incremented from an interrupt. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
ulTimerNotificationsSent++;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvNotifiedTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
const TickType_t xMaxPeriod = pdMS_TO_TICKS( 90 ), xMinPeriod = pdMS_TO_TICKS( 10 ), xDontBlock = 0;
|
||||||
|
TickType_t xPeriod;
|
||||||
|
const uint32_t ulCyclesToRaisePriority = 50UL;
|
||||||
|
|
||||||
|
/* Remove compiler warnings about unused parameters. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Run a few tests that can be done from a single task before entering the
|
||||||
|
main loop. */
|
||||||
|
prvSingleTaskTests();
|
||||||
|
|
||||||
|
/* Create the software timer that is used to send notifications to this
|
||||||
|
task. Notifications are also received from an interrupt. */
|
||||||
|
xTimer = xTimerCreate( "Notifier", xMaxPeriod, pdFALSE, NULL, prvNotifyingTimer );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Start the timer again with a different period. Sometimes the period
|
||||||
|
will be higher than the tasks block time, sometimes it will be lower
|
||||||
|
than the tasks block time. */
|
||||||
|
xPeriod = prvRand() % xMaxPeriod;
|
||||||
|
if( xPeriod < xMinPeriod )
|
||||||
|
{
|
||||||
|
xPeriod = xMinPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the timer period and start the timer. */
|
||||||
|
xTimerChangePeriod( xTimer, xPeriod, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* Block waiting for the notification again with a different period.
|
||||||
|
Sometimes the period will be higher than the tasks block time, sometimes
|
||||||
|
it will be lower than the tasks block time. */
|
||||||
|
xPeriod = prvRand() % xMaxPeriod;
|
||||||
|
if( xPeriod < xMinPeriod )
|
||||||
|
{
|
||||||
|
xPeriod = xMinPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Block to wait for a notification but without clearing the
|
||||||
|
notification count, so only add one to the count of received
|
||||||
|
notifications as any other notifications will remain pending. */
|
||||||
|
if( ulTaskNotifyTake( pdFALSE, xPeriod ) != 0 )
|
||||||
|
{
|
||||||
|
ulTimerNotificationsReceived++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take a notification without clearing again, but this time without a
|
||||||
|
block time specified. */
|
||||||
|
if( ulTaskNotifyTake( pdFALSE, xDontBlock ) != 0 )
|
||||||
|
{
|
||||||
|
ulTimerNotificationsReceived++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the next notification from the timer, clearing all
|
||||||
|
notifications if one is received, so this time adding the total number
|
||||||
|
of notifications that were pending as none will be left pending after
|
||||||
|
the function call. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, xPeriod );
|
||||||
|
|
||||||
|
/* Occasionally raise the priority of the task being notified to test
|
||||||
|
the path where the task is notified from an ISR and becomes the highest
|
||||||
|
priority ready state task, but the pxHigherPriorityTaskWoken parameter
|
||||||
|
is NULL (which it is in the tick hook that sends notifications to this
|
||||||
|
task. */
|
||||||
|
if( ( ulNotifyCycleCount % ulCyclesToRaisePriority ) == 0 )
|
||||||
|
{
|
||||||
|
vTaskPrioritySet( xTaskToNotify, configMAX_PRIORITIES - 1 );
|
||||||
|
|
||||||
|
/* Wait for the next notification again, clearing all notifications if
|
||||||
|
one is received, but this time blocking indefinitely. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* Reset the priority. */
|
||||||
|
vTaskPrioritySet( xTaskToNotify, notifyTASK_PRIORITY );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Wait for the next notification again, clearing all notifications if
|
||||||
|
one is received, but this time blocking indefinitely. */
|
||||||
|
ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Incremented to show the task is still running. */
|
||||||
|
ulNotifyCycleCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void xNotifyTaskFromISR( void )
|
||||||
|
{
|
||||||
|
static BaseType_t xCallCount = 0, xAPIToUse = 0;
|
||||||
|
const BaseType_t xCallInterval = pdMS_TO_TICKS( 50 );
|
||||||
|
uint32_t ulPreviousValue;
|
||||||
|
const uint32_t ulUnexpectedValue = 0xff;
|
||||||
|
|
||||||
|
/* The task performs some tests before starting the timer that gives the
|
||||||
|
notification from this interrupt. If the timer has not been created yet
|
||||||
|
then the initial tests have not yet completed and the notification should
|
||||||
|
not be sent. */
|
||||||
|
if( xTimer != NULL )
|
||||||
|
{
|
||||||
|
xCallCount++;
|
||||||
|
|
||||||
|
if( xCallCount >= xCallInterval )
|
||||||
|
{
|
||||||
|
/* It is time to 'give' the notification again. */
|
||||||
|
xCallCount = 0;
|
||||||
|
|
||||||
|
/* Test using both vTaskNotifyGiveFromISR(), xTaskNotifyFromISR()
|
||||||
|
and xTaskNotifyAndQueryFromISR(). */
|
||||||
|
switch( xAPIToUse )
|
||||||
|
{
|
||||||
|
case 0: vTaskNotifyGiveFromISR( xTaskToNotify, NULL );
|
||||||
|
xAPIToUse++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: xTaskNotifyFromISR( xTaskToNotify, 0, eIncrement, NULL );
|
||||||
|
xAPIToUse++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: ulPreviousValue = ulUnexpectedValue;
|
||||||
|
xTaskNotifyAndQueryFromISR( xTaskToNotify, 0, eIncrement, &ulPreviousValue, NULL );
|
||||||
|
configASSERT( ulPreviousValue != ulUnexpectedValue );
|
||||||
|
xAPIToUse = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:/* Should never get here!. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulTimerNotificationsSent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check the created tasks are still running and have not
|
||||||
|
detected any errors. */
|
||||||
|
BaseType_t xAreTaskNotificationTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint32_t ulLastNotifyCycleCount = 0;
|
||||||
|
const uint32_t ulMaxSendReceiveDeviation = 5UL;
|
||||||
|
|
||||||
|
/* Check the cycle count is still incrementing to ensure the task is still
|
||||||
|
actually running. */
|
||||||
|
if( ulLastNotifyCycleCount == ulNotifyCycleCount )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulLastNotifyCycleCount = ulNotifyCycleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the count of 'takes' from the software timer is keeping track with
|
||||||
|
the amount of 'gives'. */
|
||||||
|
if( ulTimerNotificationsSent > ulTimerNotificationsReceived )
|
||||||
|
{
|
||||||
|
if( ( ulTimerNotificationsSent - ulTimerNotificationsReceived ) > ulMaxSendReceiveDeviation )
|
||||||
|
{
|
||||||
|
xErrorStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xErrorStatus;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static UBaseType_t prvRand( void )
|
||||||
|
{
|
||||||
|
const size_t uxMultiplier = ( size_t ) 0x015a4e35, uxIncrement = ( size_t ) 1;
|
||||||
|
|
||||||
|
/* Utility function to generate a pseudo random number. */
|
||||||
|
uxNextRand = ( uxMultiplier * uxNextRand ) + uxIncrement;
|
||||||
|
return( ( uxNextRand >> 16 ) & ( ( size_t ) 0x7fff ) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains some test scenarios that ensure tasks do not exit queue
|
||||||
|
* send or receive functions prematurely. A description of the tests is
|
||||||
|
* included within the code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo includes. */
|
||||||
|
#include "blocktim.h"
|
||||||
|
|
||||||
|
/* Task priorities. Allow these to be overridden. */
|
||||||
|
#ifndef bktPRIMARY_PRIORITY
|
||||||
|
#define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef bktSECONDARY_PRIORITY
|
||||||
|
#define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Task behaviour. */
|
||||||
|
#define bktQUEUE_LENGTH ( 5 )
|
||||||
|
#define bktSHORT_WAIT pdMS_TO_TICKS( ( TickType_t ) 20 )
|
||||||
|
#define bktPRIMARY_BLOCK_TIME ( 10 )
|
||||||
|
#define bktALLOWABLE_MARGIN ( 15 )
|
||||||
|
#define bktTIME_TO_BLOCK ( 175 )
|
||||||
|
#define bktDONT_BLOCK ( ( TickType_t ) 0 )
|
||||||
|
#define bktRUN_INDICATOR ( ( UBaseType_t ) 0x55 )
|
||||||
|
|
||||||
|
/* In case the demo does not have software timers enabled, as this file uses
|
||||||
|
the configTIMER_TASK_PRIORITY setting. */
|
||||||
|
#ifndef configTIMER_TASK_PRIORITY
|
||||||
|
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The two test tasks. Their behaviour is commented within the functions.
|
||||||
|
*/
|
||||||
|
static void vPrimaryBlockTimeTestTask( void *pvParameters );
|
||||||
|
static void vSecondaryBlockTimeTestTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Very basic tests to verify the block times are as expected.
|
||||||
|
*/
|
||||||
|
static void prvBasicDelayTests( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue on which the tasks block. */
|
||||||
|
static QueueHandle_t xTestQueue;
|
||||||
|
|
||||||
|
/* Handle to the secondary task is required by the primary task for calls
|
||||||
|
to vTaskSuspend/Resume(). */
|
||||||
|
static TaskHandle_t xSecondary;
|
||||||
|
|
||||||
|
/* Used to ensure that tasks are still executing without error. */
|
||||||
|
static volatile BaseType_t xPrimaryCycles = 0, xSecondaryCycles = 0;
|
||||||
|
static volatile BaseType_t xErrorOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Provides a simple mechanism for the primary task to know when the
|
||||||
|
secondary task has executed. */
|
||||||
|
static volatile UBaseType_t xRunIndicator;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCreateBlockTimeTasks( void )
|
||||||
|
{
|
||||||
|
/* Create the queue on which the two tasks block. */
|
||||||
|
xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) );
|
||||||
|
|
||||||
|
if( xTestQueue != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the queue to the queue registry, if one
|
||||||
|
is in use. The queue registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate queues and has no purpose if a kernel aware
|
||||||
|
debugger is not being used. The call to vQueueAddToRegistry() will be
|
||||||
|
removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||||
|
defined or is defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" );
|
||||||
|
|
||||||
|
/* Create the two test tasks. */
|
||||||
|
xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vPrimaryBlockTimeTestTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
BaseType_t xItem, xData;
|
||||||
|
TickType_t xTimeWhenBlocking;
|
||||||
|
TickType_t xTimeToBlock, xBlockedTime;
|
||||||
|
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/*********************************************************************
|
||||||
|
Test 0
|
||||||
|
|
||||||
|
Basic vTaskDelay() and vTaskDelayUntil() tests. */
|
||||||
|
prvBasicDelayTests();
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Test 1
|
||||||
|
|
||||||
|
Simple block time wakeup test on queue receives. */
|
||||||
|
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
|
||||||
|
{
|
||||||
|
/* The queue is empty. Attempt to read from the queue using a block
|
||||||
|
time. When we wake, ensure the delta in time is as expected. */
|
||||||
|
xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );
|
||||||
|
|
||||||
|
xTimeWhenBlocking = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* We should unblock after xTimeToBlock having not received
|
||||||
|
anything on the queue. */
|
||||||
|
if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* How long were we blocked for? */
|
||||||
|
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
|
||||||
|
|
||||||
|
if( xBlockedTime < xTimeToBlock )
|
||||||
|
{
|
||||||
|
/* Should not have blocked for less than we requested. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
|
||||||
|
{
|
||||||
|
/* Should not have blocked for longer than we requested,
|
||||||
|
although we would not necessarily run as soon as we were
|
||||||
|
unblocked so a margin is allowed. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Test 2
|
||||||
|
|
||||||
|
Simple block time wakeup test on queue sends.
|
||||||
|
|
||||||
|
First fill the queue. It should be empty so all sends should pass. */
|
||||||
|
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
|
||||||
|
{
|
||||||
|
if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
|
||||||
|
{
|
||||||
|
/* The queue is full. Attempt to write to the queue using a block
|
||||||
|
time. When we wake, ensure the delta in time is as expected. */
|
||||||
|
xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem );
|
||||||
|
|
||||||
|
xTimeWhenBlocking = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* We should unblock after xTimeToBlock having not received
|
||||||
|
anything on the queue. */
|
||||||
|
if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* How long were we blocked for? */
|
||||||
|
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
|
||||||
|
|
||||||
|
if( xBlockedTime < xTimeToBlock )
|
||||||
|
{
|
||||||
|
/* Should not have blocked for less than we requested. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )
|
||||||
|
{
|
||||||
|
/* Should not have blocked for longer than we requested,
|
||||||
|
although we would not necessarily run as soon as we were
|
||||||
|
unblocked so a margin is allowed. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Test 3
|
||||||
|
|
||||||
|
Wake the other task, it will block attempting to post to the queue.
|
||||||
|
When we read from the queue the other task will wake, but before it
|
||||||
|
can run we will post to the queue again. When the other task runs it
|
||||||
|
will find the queue still full, even though it was woken. It should
|
||||||
|
recognise that its block time has not expired and return to block for
|
||||||
|
the remains of its block time.
|
||||||
|
|
||||||
|
Wake the other task so it blocks attempting to post to the already
|
||||||
|
full queue. */
|
||||||
|
xRunIndicator = 0;
|
||||||
|
vTaskResume( xSecondary );
|
||||||
|
|
||||||
|
/* We need to wait a little to ensure the other task executes. */
|
||||||
|
while( xRunIndicator != bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
/* The other task has not yet executed. */
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
}
|
||||||
|
/* Make sure the other task is blocked on the queue. */
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
xRunIndicator = 0;
|
||||||
|
|
||||||
|
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
|
||||||
|
{
|
||||||
|
/* Now when we make space on the queue the other task should wake
|
||||||
|
but not execute as this task has higher priority. */
|
||||||
|
if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now fill the queue again before the other task gets a chance to
|
||||||
|
execute. If the other task had executed we would find the queue
|
||||||
|
full ourselves, and the other task have set xRunIndicator. */
|
||||||
|
if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xRunIndicator == bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
/* The other task should not have executed. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise the priority of the other task so it executes and blocks
|
||||||
|
on the queue again. */
|
||||||
|
vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );
|
||||||
|
|
||||||
|
/* The other task should now have re-blocked without exiting the
|
||||||
|
queue function. */
|
||||||
|
if( xRunIndicator == bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
/* The other task should not have executed outside of the
|
||||||
|
queue function. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the priority back down. */
|
||||||
|
vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let the other task timeout. When it unblockes it will check that it
|
||||||
|
unblocked at the correct time, then suspend itself. */
|
||||||
|
while( xRunIndicator != bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
}
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
xRunIndicator = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Test 4
|
||||||
|
|
||||||
|
As per test 3 - but with the send and receive the other way around.
|
||||||
|
The other task blocks attempting to read from the queue.
|
||||||
|
|
||||||
|
Empty the queue. We should find that it is full. */
|
||||||
|
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
|
||||||
|
{
|
||||||
|
if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake the other task so it blocks attempting to read from the
|
||||||
|
already empty queue. */
|
||||||
|
vTaskResume( xSecondary );
|
||||||
|
|
||||||
|
/* We need to wait a little to ensure the other task executes. */
|
||||||
|
while( xRunIndicator != bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
}
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
xRunIndicator = 0;
|
||||||
|
|
||||||
|
for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )
|
||||||
|
{
|
||||||
|
/* Now when we place an item on the queue the other task should
|
||||||
|
wake but not execute as this task has higher priority. */
|
||||||
|
if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now empty the queue again before the other task gets a chance to
|
||||||
|
execute. If the other task had executed we would find the queue
|
||||||
|
empty ourselves, and the other task would be suspended. */
|
||||||
|
if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xRunIndicator == bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
/* The other task should not have executed. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise the priority of the other task so it executes and blocks
|
||||||
|
on the queue again. */
|
||||||
|
vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );
|
||||||
|
|
||||||
|
/* The other task should now have re-blocked without exiting the
|
||||||
|
queue function. */
|
||||||
|
if( xRunIndicator == bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
/* The other task should not have executed outside of the
|
||||||
|
queue function. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let the other task timeout. When it unblockes it will check that it
|
||||||
|
unblocked at the correct time, then suspend itself. */
|
||||||
|
while( xRunIndicator != bktRUN_INDICATOR )
|
||||||
|
{
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
}
|
||||||
|
vTaskDelay( bktSHORT_WAIT );
|
||||||
|
|
||||||
|
xPrimaryCycles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vSecondaryBlockTimeTestTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
TickType_t xTimeWhenBlocking, xBlockedTime;
|
||||||
|
BaseType_t xData;
|
||||||
|
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/*********************************************************************
|
||||||
|
Test 0, 1 and 2
|
||||||
|
|
||||||
|
This task does not participate in these tests. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Test 3
|
||||||
|
|
||||||
|
The first thing we do is attempt to read from the queue. It should be
|
||||||
|
full so we block. Note the time before we block so we can check the
|
||||||
|
wake time is as per that expected. */
|
||||||
|
xTimeWhenBlocking = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* We should unblock after bktTIME_TO_BLOCK having not sent anything to
|
||||||
|
the queue. */
|
||||||
|
xData = 0;
|
||||||
|
xRunIndicator = bktRUN_INDICATOR;
|
||||||
|
if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* How long were we inside the send function? */
|
||||||
|
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
|
||||||
|
|
||||||
|
/* We should not have blocked for less time than bktTIME_TO_BLOCK. */
|
||||||
|
if( xBlockedTime < bktTIME_TO_BLOCK )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should of not blocked for much longer than bktALLOWABLE_MARGIN
|
||||||
|
either. A margin is permitted as we would not necessarily run as
|
||||||
|
soon as we unblocked. */
|
||||||
|
if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Suspend ready for test 3. */
|
||||||
|
xRunIndicator = bktRUN_INDICATOR;
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
Test 4
|
||||||
|
|
||||||
|
As per test three, but with the send and receive reversed. */
|
||||||
|
xTimeWhenBlocking = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* We should unblock after bktTIME_TO_BLOCK having not received
|
||||||
|
anything on the queue. */
|
||||||
|
xRunIndicator = bktRUN_INDICATOR;
|
||||||
|
if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;
|
||||||
|
|
||||||
|
/* We should not have blocked for less time than bktTIME_TO_BLOCK. */
|
||||||
|
if( xBlockedTime < bktTIME_TO_BLOCK )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should of not blocked for much longer than bktALLOWABLE_MARGIN
|
||||||
|
either. A margin is permitted as we would not necessarily run as soon
|
||||||
|
as we unblocked. */
|
||||||
|
if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xRunIndicator = bktRUN_INDICATOR;
|
||||||
|
|
||||||
|
xSecondaryCycles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvBasicDelayTests( void )
|
||||||
|
{
|
||||||
|
TickType_t xPreTime, xPostTime, x, xLastUnblockTime, xExpectedUnblockTime;
|
||||||
|
const TickType_t xPeriod = 75, xCycles = 5, xAllowableMargin = ( bktALLOWABLE_MARGIN >> 1 );
|
||||||
|
|
||||||
|
/* Temporarily increase priority so the timing is more accurate, but not so
|
||||||
|
high as to disrupt the timer tests. */
|
||||||
|
vTaskPrioritySet( NULL, configTIMER_TASK_PRIORITY - 1 );
|
||||||
|
|
||||||
|
/* Crude check to too that vTaskDelay() blocks for the expected period. */
|
||||||
|
xPreTime = xTaskGetTickCount();
|
||||||
|
vTaskDelay( bktTIME_TO_BLOCK );
|
||||||
|
xPostTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* The priority is higher, so the allowable margin is halved when compared
|
||||||
|
to the other tests in this file. */
|
||||||
|
if( ( xPostTime - xPreTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now crude tests to check the vTaskDelayUntil() functionality. */
|
||||||
|
xPostTime = xTaskGetTickCount();
|
||||||
|
xLastUnblockTime = xPostTime;
|
||||||
|
|
||||||
|
for( x = 0; x < xCycles; x++ )
|
||||||
|
{
|
||||||
|
/* Calculate the next expected unblock time from the time taken before
|
||||||
|
this loop was entered. */
|
||||||
|
xExpectedUnblockTime = xPostTime + ( x * xPeriod );
|
||||||
|
|
||||||
|
vTaskDelayUntil( &xLastUnblockTime, xPeriod );
|
||||||
|
|
||||||
|
if( ( xTaskGetTickCount() - xExpectedUnblockTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xPrimaryCycles++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset to the original task priority ready for the other tests. */
|
||||||
|
vTaskPrioritySet( NULL, bktPRIMARY_PRIORITY );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreBlockTimeTestTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;
|
||||||
|
BaseType_t xReturn = pdPASS;
|
||||||
|
|
||||||
|
/* Have both tasks performed at least one cycle since this function was
|
||||||
|
last called? */
|
||||||
|
if( xPrimaryCycles == xLastPrimaryCycleCount )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSecondaryCycles == xLastSecondaryCycleCount )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xErrorOccurred == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xLastSecondaryCycleCount = xSecondaryCycles;
|
||||||
|
xLastPrimaryCycleCount = xPrimaryCycles;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
|
@ -0,0 +1,307 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This version of comtest. c is for use on systems that have limited stack
|
||||||
|
* space and no display facilities. The complete version can be found in
|
||||||
|
* the Demo/Common/Full directory.
|
||||||
|
*
|
||||||
|
* Creates two tasks that operate on an interrupt driven serial port. A
|
||||||
|
* loopback connector should be used so that everything that is transmitted is
|
||||||
|
* also received. The serial port does not use any flow control. On a
|
||||||
|
* standard 9way 'D' connector pins two and three should be connected together.
|
||||||
|
*
|
||||||
|
* The first task posts a sequence of characters to the Tx queue, toggling an
|
||||||
|
* LED on each successful post. At the end of the sequence it sleeps for a
|
||||||
|
* pseudo-random period before resending the same sequence.
|
||||||
|
*
|
||||||
|
* The UART Tx end interrupt is enabled whenever data is available in the Tx
|
||||||
|
* queue. The Tx end ISR removes a single character from the Tx queue and
|
||||||
|
* passes it to the UART for transmission.
|
||||||
|
*
|
||||||
|
* The second task blocks on the Rx queue waiting for a character to become
|
||||||
|
* available. When the UART Rx end interrupt receives a character it places
|
||||||
|
* it in the Rx queue, waking the second task. The second task checks that the
|
||||||
|
* characters removed from the Rx queue form the same sequence as those posted
|
||||||
|
* to the Tx queue, and toggles an LED for each correct character.
|
||||||
|
*
|
||||||
|
* The receiving task is spawned with a higher priority than the transmitting
|
||||||
|
* task. The receiver will therefore wake every time a character is
|
||||||
|
* transmitted so neither the Tx or Rx queue should ever hold more than a few
|
||||||
|
* characters.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "serial.h"
|
||||||
|
#include "comtest.h"
|
||||||
|
#include "partest.h"
|
||||||
|
|
||||||
|
#define comSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define comTX_LED_OFFSET ( 0 )
|
||||||
|
#define comRX_LED_OFFSET ( 1 )
|
||||||
|
#define comTOTAL_PERMISSIBLE_ERRORS ( 2 )
|
||||||
|
|
||||||
|
/* The Tx task will transmit the sequence of characters at a pseudo random
|
||||||
|
interval. This is the maximum and minimum block time between sends. */
|
||||||
|
#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x96 )
|
||||||
|
#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0x32 )
|
||||||
|
#define comOFFSET_TIME ( ( TickType_t ) 3 )
|
||||||
|
|
||||||
|
/* We should find that each character can be queued for Tx immediately and we
|
||||||
|
don't have to block to send. */
|
||||||
|
#define comNO_BLOCK ( ( TickType_t ) 0 )
|
||||||
|
|
||||||
|
/* The Rx task will block on the Rx queue for a long period. */
|
||||||
|
#define comRX_BLOCK_TIME ( ( TickType_t ) 0xffff )
|
||||||
|
|
||||||
|
/* The sequence transmitted is from comFIRST_BYTE to and including comLAST_BYTE. */
|
||||||
|
#define comFIRST_BYTE ( 'A' )
|
||||||
|
#define comLAST_BYTE ( 'X' )
|
||||||
|
|
||||||
|
#define comBUFFER_LEN ( ( UBaseType_t ) ( comLAST_BYTE - comFIRST_BYTE ) + ( UBaseType_t ) 1 )
|
||||||
|
#define comINITIAL_RX_COUNT_VALUE ( 0 )
|
||||||
|
|
||||||
|
/* Handle to the com port used by both tasks. */
|
||||||
|
static xComPortHandle xPort = NULL;
|
||||||
|
|
||||||
|
/* The transmit task as described at the top of the file. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vComTxTask, pvParameters );
|
||||||
|
|
||||||
|
/* The receive task as described at the top of the file. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vComRxTask, pvParameters );
|
||||||
|
|
||||||
|
/* The LED that should be toggled by the Rx and Tx tasks. The Rx task will
|
||||||
|
toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task will toggle LED
|
||||||
|
( uxBaseLED + comTX_LED_OFFSET ). */
|
||||||
|
static UBaseType_t uxBaseLED = 0;
|
||||||
|
|
||||||
|
/* Check variable used to ensure no error have occurred. The Rx task will
|
||||||
|
increment this variable after every successfully received sequence. If at any
|
||||||
|
time the sequence is incorrect the the variable will stop being incremented. */
|
||||||
|
static volatile UBaseType_t uxRxLoops = comINITIAL_RX_COUNT_VALUE;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED )
|
||||||
|
{
|
||||||
|
/* Initialise the com port then spawn the Rx and Tx tasks. */
|
||||||
|
uxBaseLED = uxLED;
|
||||||
|
xSerialPortInitMinimal( ulBaudRate, comBUFFER_LEN );
|
||||||
|
|
||||||
|
/* The Tx task is spawned with a lower priority than the Rx task. */
|
||||||
|
xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority - 1, ( TaskHandle_t * ) NULL );
|
||||||
|
xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vComTxTask, pvParameters )
|
||||||
|
{
|
||||||
|
char cByteToSend;
|
||||||
|
TickType_t xTimeToWait;
|
||||||
|
|
||||||
|
/* Just to stop compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Simply transmit a sequence of characters from comFIRST_BYTE to
|
||||||
|
comLAST_BYTE. */
|
||||||
|
for( cByteToSend = comFIRST_BYTE; cByteToSend <= comLAST_BYTE; cByteToSend++ )
|
||||||
|
{
|
||||||
|
if( xSerialPutChar( xPort, cByteToSend, comNO_BLOCK ) == pdPASS )
|
||||||
|
{
|
||||||
|
vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn the LED off while we are not doing anything. */
|
||||||
|
vParTestSetLED( uxBaseLED + comTX_LED_OFFSET, pdFALSE );
|
||||||
|
|
||||||
|
/* We have posted all the characters in the string - wait before
|
||||||
|
re-sending. Wait a pseudo-random time as this will provide a better
|
||||||
|
test. */
|
||||||
|
xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME;
|
||||||
|
|
||||||
|
/* Make sure we don't wait too long... */
|
||||||
|
xTimeToWait %= comTX_MAX_BLOCK_TIME;
|
||||||
|
|
||||||
|
/* ...but we do want to wait. */
|
||||||
|
if( xTimeToWait < comTX_MIN_BLOCK_TIME )
|
||||||
|
{
|
||||||
|
xTimeToWait = comTX_MIN_BLOCK_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay( xTimeToWait );
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vComRxTask, pvParameters )
|
||||||
|
{
|
||||||
|
signed char cExpectedByte, cByteRxed;
|
||||||
|
BaseType_t xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Just to stop compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* We expect to receive the characters from comFIRST_BYTE to
|
||||||
|
comLAST_BYTE in an incrementing order. Loop to receive each byte. */
|
||||||
|
for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ )
|
||||||
|
{
|
||||||
|
/* Block on the queue that contains received bytes until a byte is
|
||||||
|
available. */
|
||||||
|
if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) )
|
||||||
|
{
|
||||||
|
/* Was this the byte we were expecting? If so, toggle the LED,
|
||||||
|
otherwise we are out on sync and should break out of the loop
|
||||||
|
until the expected character sequence is about to restart. */
|
||||||
|
if( cByteRxed == cExpectedByte )
|
||||||
|
{
|
||||||
|
vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xResyncRequired = pdTRUE;
|
||||||
|
break; /*lint !e960 Non-switch break allowed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn the LED off while we are not doing anything. */
|
||||||
|
vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE );
|
||||||
|
|
||||||
|
/* Did we break out of the loop because the characters were received in
|
||||||
|
an unexpected order? If so wait here until the character sequence is
|
||||||
|
about to restart. */
|
||||||
|
if( xResyncRequired == pdTRUE )
|
||||||
|
{
|
||||||
|
while( cByteRxed != comLAST_BYTE )
|
||||||
|
{
|
||||||
|
/* Block until the next char is available. */
|
||||||
|
xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that an error occurred which caused us to have to resync.
|
||||||
|
We use this to stop incrementing the loop counter so
|
||||||
|
sAreComTestTasksStillRunning() will return false - indicating an
|
||||||
|
error. */
|
||||||
|
xErrorOccurred++;
|
||||||
|
|
||||||
|
/* We have now resynced with the Tx task and can continue. */
|
||||||
|
xResyncRequired = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS )
|
||||||
|
{
|
||||||
|
/* Increment the count of successful loops. As error
|
||||||
|
occurring (i.e. an unexpected character being received) will
|
||||||
|
prevent this counter being incremented for the rest of the
|
||||||
|
execution. Don't worry about mutual exclusion on this
|
||||||
|
variable - it doesn't really matter as we just want it
|
||||||
|
to change. */
|
||||||
|
uxRxLoops++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreComTestTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* If the count of successful reception loops has not changed than at
|
||||||
|
some time an error occurred (i.e. a character was received out of sequence)
|
||||||
|
and we will return false. */
|
||||||
|
if( uxRxLoops == comINITIAL_RX_COUNT_VALUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the count of successful Rx loops. When this function is called
|
||||||
|
again we expect this to have been incremented. */
|
||||||
|
uxRxLoops = comINITIAL_RX_COUNT_VALUE;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,353 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a task and a timer that operate on an interrupt driven serial port.
|
||||||
|
* This demo assumes that the characters transmitted on a port will also be
|
||||||
|
* received on the same port. Therefore, the UART must either be connected to
|
||||||
|
* an echo server, or the uart connector must have a loopback connector fitted.
|
||||||
|
* See http://www.serialporttool.com/CommEcho.htm for a suitable echo server
|
||||||
|
* for Windows hosts.
|
||||||
|
*
|
||||||
|
* The timer sends a string to the UART, toggles an LED, then resets itself by
|
||||||
|
* changing its own period. The period is calculated as a pseudo random number
|
||||||
|
* between comTX_MAX_BLOCK_TIME and comTX_MIN_BLOCK_TIME.
|
||||||
|
*
|
||||||
|
* The task blocks on an Rx queue waiting for a character to become available.
|
||||||
|
* Received characters are checked to ensure they match those transmitted by the
|
||||||
|
* Tx timer. An error is latched if characters are missing, incorrect, or
|
||||||
|
* arrive too slowly.
|
||||||
|
*
|
||||||
|
* How characters are actually transmitted and received is port specific. Demos
|
||||||
|
* that include this test/demo file will provide example drivers. The Tx timer
|
||||||
|
* executes in the context of the timer service (daemon) task, and must
|
||||||
|
* therefore never attempt to block.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
#ifndef configUSE_TIMERS
|
||||||
|
#error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configUSE_TIMERS != 1
|
||||||
|
#error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "serial.h"
|
||||||
|
#include "comtest_strings.h"
|
||||||
|
#include "partest.h"
|
||||||
|
|
||||||
|
/* The size of the stack given to the Rx task. */
|
||||||
|
#define comSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* See the comment above the declaraction of the uxBaseLED variable. */
|
||||||
|
#define comTX_LED_OFFSET ( 0 )
|
||||||
|
#define comRX_LED_OFFSET ( 1 )
|
||||||
|
|
||||||
|
/* The Tx timer transmits the sequence of characters at a pseudo random
|
||||||
|
interval that is capped between comTX_MAX_BLOCK_TIME and
|
||||||
|
comTX_MIN_BLOCK_TIME. */
|
||||||
|
#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x96 )
|
||||||
|
#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0x32 )
|
||||||
|
#define comOFFSET_TIME ( ( TickType_t ) 3 )
|
||||||
|
|
||||||
|
/* States for the simple state machine implemented in the Rx task. */
|
||||||
|
#define comtstWAITING_START_OF_STRING 0
|
||||||
|
#define comtstWAITING_END_OF_STRING 1
|
||||||
|
|
||||||
|
/* A short delay in ticks - this delay is used to allow the Rx queue to fill up
|
||||||
|
a bit so more than one character can be processed at a time. This is relative
|
||||||
|
to comTX_MIN_BLOCK_TIME to ensure it is never longer than the shortest gap
|
||||||
|
between transmissions. It could be worked out more scientifically from the
|
||||||
|
baud rate being used. */
|
||||||
|
#define comSHORT_DELAY ( comTX_MIN_BLOCK_TIME >> ( TickType_t ) 2 )
|
||||||
|
|
||||||
|
/* The string that is transmitted and received. */
|
||||||
|
#define comTRANSACTED_STRING "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||||
|
|
||||||
|
/* A block time of 0 simply means "don't block". */
|
||||||
|
#define comtstDONT_BLOCK ( TickType_t ) 0
|
||||||
|
|
||||||
|
/* Handle to the com port used by both tasks. */
|
||||||
|
static xComPortHandle xPort = NULL;
|
||||||
|
|
||||||
|
/* The callback function allocated to the transmit timer, as described in the
|
||||||
|
comments at the top of this file. */
|
||||||
|
static void prvComTxTimerCallback( TimerHandle_t xTimer );
|
||||||
|
|
||||||
|
/* The receive task as described in the comments at the top of this file. */
|
||||||
|
static void vComRxTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* The Rx task will toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task
|
||||||
|
will toggle LED ( uxBaseLED + comTX_LED_OFFSET ). */
|
||||||
|
static UBaseType_t uxBaseLED = 0;
|
||||||
|
|
||||||
|
/* The Rx task toggles uxRxLoops on each successful iteration of its defined
|
||||||
|
function - provided no errors have ever been latched. If this variable stops
|
||||||
|
incrementing, then an error has occurred. */
|
||||||
|
static volatile UBaseType_t uxRxLoops = 0UL;
|
||||||
|
|
||||||
|
/* The timer used to periodically transmit the string. This is the timer that
|
||||||
|
has prvComTxTimerCallback allocated to it as its callback function. */
|
||||||
|
static TimerHandle_t xTxTimer = NULL;
|
||||||
|
|
||||||
|
/* The string length is held at file scope so the Tx timer does not need to
|
||||||
|
calculate it each time it executes. */
|
||||||
|
static size_t xStringLength = 0U;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartComTestStringsTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED )
|
||||||
|
{
|
||||||
|
/* Store values that are used at run time. */
|
||||||
|
uxBaseLED = uxLED;
|
||||||
|
|
||||||
|
/* Calculate the string length here, rather than each time the Tx timer
|
||||||
|
executes. */
|
||||||
|
xStringLength = strlen( comTRANSACTED_STRING );
|
||||||
|
|
||||||
|
/* Include the null terminator in the string length as this is used to
|
||||||
|
detect the end of the string in the Rx task. */
|
||||||
|
xStringLength++;
|
||||||
|
|
||||||
|
/* Initialise the com port, then spawn the Rx task and create the Tx
|
||||||
|
timer. */
|
||||||
|
xSerialPortInitMinimal( ulBaudRate, ( xStringLength * 2U ) );
|
||||||
|
|
||||||
|
/* Create the Rx task and the Tx timer. The timer is started from the
|
||||||
|
Rx task. */
|
||||||
|
xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
xTxTimer = xTimerCreate( "TxTimer", comTX_MIN_BLOCK_TIME, pdFALSE, NULL, prvComTxTimerCallback );
|
||||||
|
configASSERT( xTxTimer );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvComTxTimerCallback( TimerHandle_t xTimer )
|
||||||
|
{
|
||||||
|
TickType_t xTimeToWait;
|
||||||
|
|
||||||
|
/* The parameter is not used in this case. */
|
||||||
|
( void ) xTimer;
|
||||||
|
|
||||||
|
/* Send the string. How this is actually performed depends on the
|
||||||
|
sample driver provided with this demo. However - as this is a timer,
|
||||||
|
it executes in the context of the timer task and therefore must not
|
||||||
|
block. */
|
||||||
|
vSerialPutString( xPort, comTRANSACTED_STRING, xStringLength );
|
||||||
|
|
||||||
|
/* Toggle an LED to give a visible indication that another transmission
|
||||||
|
has been performed. */
|
||||||
|
vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET );
|
||||||
|
|
||||||
|
/* Wait a pseudo random time before sending the string again. */
|
||||||
|
xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME;
|
||||||
|
|
||||||
|
/* Ensure the time to wait is not greater than comTX_MAX_BLOCK_TIME. */
|
||||||
|
xTimeToWait %= comTX_MAX_BLOCK_TIME;
|
||||||
|
|
||||||
|
/* Ensure the time to wait is not less than comTX_MIN_BLOCK_TIME. */
|
||||||
|
if( xTimeToWait < comTX_MIN_BLOCK_TIME )
|
||||||
|
{
|
||||||
|
xTimeToWait = comTX_MIN_BLOCK_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the timer to run again xTimeToWait ticks from now. This function
|
||||||
|
is called from the context of the timer task, so the block time must not
|
||||||
|
be anything other than zero. */
|
||||||
|
xTimerChangePeriod( xTxTimer, xTimeToWait, comtstDONT_BLOCK );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vComRxTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
BaseType_t xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE;
|
||||||
|
char *pcExpectedByte, cRxedChar;
|
||||||
|
const xComPortHandle xPort = NULL;
|
||||||
|
|
||||||
|
/* The parameter is not used in this example. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Start the Tx timer. This only needs to be started once, as it will
|
||||||
|
reset itself thereafter. */
|
||||||
|
xTimerStart( xTxTimer, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* The first expected Rx character is the first in the string that is
|
||||||
|
transmitted. */
|
||||||
|
pcExpectedByte = comTRANSACTED_STRING;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait for the next character. */
|
||||||
|
if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
/* A character definitely should have been received by now. As a
|
||||||
|
character was not received an error must have occurred (which might
|
||||||
|
just be that the loopback connector is not fitted). */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( xState )
|
||||||
|
{
|
||||||
|
case comtstWAITING_START_OF_STRING:
|
||||||
|
if( cRxedChar == *pcExpectedByte )
|
||||||
|
{
|
||||||
|
/* The received character was the first character of the
|
||||||
|
string. Move to the next state to check each character
|
||||||
|
as it comes in until the entire string has been received. */
|
||||||
|
xState = comtstWAITING_END_OF_STRING;
|
||||||
|
pcExpectedByte++;
|
||||||
|
|
||||||
|
/* Block for a short period. This just allows the Rx queue
|
||||||
|
to contain more than one character, and therefore prevent
|
||||||
|
thrashing reads to the queue, and repetitive context
|
||||||
|
switches as each character is received. */
|
||||||
|
vTaskDelay( comSHORT_DELAY );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case comtstWAITING_END_OF_STRING:
|
||||||
|
if( cRxedChar == *pcExpectedByte )
|
||||||
|
{
|
||||||
|
/* The received character was the expected character. Was
|
||||||
|
it the last character in the string - i.e. the null
|
||||||
|
terminator? */
|
||||||
|
if( cRxedChar == 0x00 )
|
||||||
|
{
|
||||||
|
/* The entire string has been received. If no errors
|
||||||
|
have been latched, then increment the loop counter to
|
||||||
|
show this task is still healthy. */
|
||||||
|
if( xErrorOccurred == pdFALSE )
|
||||||
|
{
|
||||||
|
uxRxLoops++;
|
||||||
|
|
||||||
|
/* Toggle an LED to give a visible sign that a
|
||||||
|
complete string has been received. */
|
||||||
|
vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go back to wait for the start of the next string. */
|
||||||
|
pcExpectedByte = comTRANSACTED_STRING;
|
||||||
|
xState = comtstWAITING_START_OF_STRING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Wait for the next character in the string. */
|
||||||
|
pcExpectedByte++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The character received was not that expected. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Should not get here. Stop the Rx loop counter from
|
||||||
|
incrementing to latch the error. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreComTestTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* If the count of successful reception loops has not changed than at
|
||||||
|
some time an error occurred (i.e. a character was received out of sequence)
|
||||||
|
and false is returned. */
|
||||||
|
if( uxRxLoops == 0UL )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the count of successful Rx loops. When this function is called
|
||||||
|
again it should have been incremented again. */
|
||||||
|
uxRxLoops = 0UL;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,330 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple demonstration of the usage of counting semaphore.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "countsem.h"
|
||||||
|
|
||||||
|
/* The maximum count value that the semaphore used for the demo can hold. */
|
||||||
|
#define countMAX_COUNT_VALUE ( 200 )
|
||||||
|
|
||||||
|
/* Constants used to indicate whether or not the semaphore should have been
|
||||||
|
created with its maximum count value, or its minimum count value. These
|
||||||
|
numbers are used to ensure that the pointers passed in as the task parameters
|
||||||
|
are valid. */
|
||||||
|
#define countSTART_AT_MAX_COUNT ( 0xaa )
|
||||||
|
#define countSTART_AT_ZERO ( 0x55 )
|
||||||
|
|
||||||
|
/* Two tasks are created for the test. One uses a semaphore created with its
|
||||||
|
count value set to the maximum, and one with the count value set to zero. */
|
||||||
|
#define countNUM_TEST_TASKS ( 2 )
|
||||||
|
#define countDONT_BLOCK ( 0 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
|
||||||
|
detected in any of the tasks. */
|
||||||
|
static volatile BaseType_t xErrorDetected = pdFALSE;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The demo task. This simply counts the semaphore up to its maximum value,
|
||||||
|
* the counts it back down again. The result of each semaphore 'give' and
|
||||||
|
* 'take' is inspected, with an error being flagged if it is found not to be
|
||||||
|
* the expected result.
|
||||||
|
*/
|
||||||
|
static void prvCountingSemaphoreTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility function to increment the semaphore count value up from zero to
|
||||||
|
* countMAX_COUNT_VALUE.
|
||||||
|
*/
|
||||||
|
static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility function to decrement the semaphore count value up from
|
||||||
|
* countMAX_COUNT_VALUE to zero.
|
||||||
|
*/
|
||||||
|
static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The structure that is passed into the task as the task parameter. */
|
||||||
|
typedef struct COUNT_SEM_STRUCT
|
||||||
|
{
|
||||||
|
/* The semaphore to be used for the demo. */
|
||||||
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
|
||||||
|
/* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with
|
||||||
|
its count value set to its max count value, or countSTART_AT_ZERO if it
|
||||||
|
should have been created with its count value set to 0. */
|
||||||
|
UBaseType_t uxExpectedStartCount;
|
||||||
|
|
||||||
|
/* Incremented on each cycle of the demo task. Used to detect a stalled
|
||||||
|
task. */
|
||||||
|
UBaseType_t uxLoopCounter;
|
||||||
|
} xCountSemStruct;
|
||||||
|
|
||||||
|
/* Two structures are defined, one is passed to each test task. */
|
||||||
|
static volatile xCountSemStruct xParameters[ countNUM_TEST_TASKS ];
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartCountingSemaphoreTasks( void )
|
||||||
|
{
|
||||||
|
/* Create the semaphores that we are going to use for the test/demo. The
|
||||||
|
first should be created such that it starts at its maximum count value,
|
||||||
|
the second should be created such that it starts with a count value of zero. */
|
||||||
|
xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE );
|
||||||
|
xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT;
|
||||||
|
xParameters[ 0 ].uxLoopCounter = 0;
|
||||||
|
|
||||||
|
xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 );
|
||||||
|
xParameters[ 1 ].uxExpectedStartCount = 0;
|
||||||
|
xParameters[ 1 ].uxLoopCounter = 0;
|
||||||
|
|
||||||
|
/* Were the semaphores created? */
|
||||||
|
if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the semaphore to the registry, if one is
|
||||||
|
in use. The registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate semaphores and has no purpose if a kernel aware
|
||||||
|
debugger is not being used. The call to vQueueAddToRegistry() will be
|
||||||
|
removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||||
|
defined or is defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 0 ].xSemaphore, "Counting_Sem_1" );
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 1 ].xSemaphore, "Counting_Sem_2" );
|
||||||
|
|
||||||
|
/* Create the demo tasks, passing in the semaphore to use as the parameter. */
|
||||||
|
xTaskCreate( prvCountingSemaphoreTask, "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter )
|
||||||
|
{
|
||||||
|
UBaseType_t ux;
|
||||||
|
|
||||||
|
/* If the semaphore count is at its maximum then we should not be able to
|
||||||
|
'give' the semaphore. */
|
||||||
|
if( xSemaphoreGive( xSemaphore ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */
|
||||||
|
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
|
||||||
|
{
|
||||||
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == ( countMAX_COUNT_VALUE - ux ) );
|
||||||
|
|
||||||
|
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to be able to take the semaphore. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
( *puxLoopCounter )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the semaphore count is zero then we should not be able to 'take'
|
||||||
|
the semaphore. */
|
||||||
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );
|
||||||
|
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter )
|
||||||
|
{
|
||||||
|
UBaseType_t ux;
|
||||||
|
|
||||||
|
/* If the semaphore count is zero then we should not be able to 'take'
|
||||||
|
the semaphore. */
|
||||||
|
if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */
|
||||||
|
for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ )
|
||||||
|
{
|
||||||
|
configASSERT( uxSemaphoreGetCount( xSemaphore ) == ux );
|
||||||
|
|
||||||
|
if( xSemaphoreGive( xSemaphore ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* We expected to be able to take the semaphore. */
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
( *puxLoopCounter )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the semaphore count is at its maximum then we should not be able to
|
||||||
|
'give' the semaphore. */
|
||||||
|
if( xSemaphoreGive( xSemaphore ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCountingSemaphoreTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
xCountSemStruct *pxParameter;
|
||||||
|
|
||||||
|
#ifdef USE_STDIO
|
||||||
|
void vPrintDisplayMessage( const char * const * ppcMessageToSend );
|
||||||
|
|
||||||
|
const char * const pcTaskStartMsg = "Counting semaphore demo started.\r\n";
|
||||||
|
|
||||||
|
/* Queue a message for printing to say the task has started. */
|
||||||
|
vPrintDisplayMessage( &pcTaskStartMsg );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The semaphore to be used was passed as the parameter. */
|
||||||
|
pxParameter = ( xCountSemStruct * ) pvParameters;
|
||||||
|
|
||||||
|
/* Did we expect to find the semaphore already at its max count value, or
|
||||||
|
at zero? */
|
||||||
|
if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT )
|
||||||
|
{
|
||||||
|
prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we expect the semaphore count to be 0, so this time there is an
|
||||||
|
error if we can take the semaphore. */
|
||||||
|
if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );
|
||||||
|
prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreCountingSemaphoreTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static UBaseType_t uxLastCount0 = 0, uxLastCount1 = 0;
|
||||||
|
BaseType_t xReturn = pdPASS;
|
||||||
|
|
||||||
|
/* Return fail if any 'give' or 'take' did not result in the expected
|
||||||
|
behaviour. */
|
||||||
|
if( xErrorDetected != pdFALSE )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return fail if either task is not still incrementing its loop counter. */
|
||||||
|
if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxLastCount0 = xParameters[ 0 ].uxLoopCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxLastCount1 = xParameters[ 1 ].uxLoopCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This demo application file demonstrates the use of queues to pass data
|
||||||
|
* between co-routines.
|
||||||
|
*
|
||||||
|
* N represents the number of 'fixed delay' co-routines that are created and
|
||||||
|
* is set during initialisation.
|
||||||
|
*
|
||||||
|
* N 'fixed delay' co-routines are created that just block for a fixed
|
||||||
|
* period then post the number of an LED onto a queue. Each such co-routine
|
||||||
|
* uses a different block period. A single 'flash' co-routine is also created
|
||||||
|
* that blocks on the same queue, waiting for the number of the next LED it
|
||||||
|
* should flash. Upon receiving a number it simply toggle the instructed LED
|
||||||
|
* then blocks on the queue once more. In this manner each LED from LED 0 to
|
||||||
|
* LED N-1 is caused to flash at a different rate.
|
||||||
|
*
|
||||||
|
* The 'fixed delay' co-routines are created with co-routine priority 0. The
|
||||||
|
* flash co-routine is created with co-routine priority 1. This means that
|
||||||
|
* the queue should never contain more than a single item. This is because
|
||||||
|
* posting to the queue will unblock the 'flash' co-routine, and as this has
|
||||||
|
* a priority greater than the tasks posting to the queue it is guaranteed to
|
||||||
|
* have emptied the queue and blocked once again before the queue can contain
|
||||||
|
* any more date. An error is indicated if an attempt to post data to the
|
||||||
|
* queue fails - indicating that the queue is already full.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "croutine.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo application includes. */
|
||||||
|
#include "partest.h"
|
||||||
|
#include "crflash.h"
|
||||||
|
|
||||||
|
/* The queue should only need to be of length 1. See the description at the
|
||||||
|
top of the file. */
|
||||||
|
#define crfQUEUE_LENGTH 1
|
||||||
|
|
||||||
|
#define crfFIXED_DELAY_PRIORITY 0
|
||||||
|
#define crfFLASH_PRIORITY 1
|
||||||
|
|
||||||
|
/* Only one flash co-routine is created so the index is not significant. */
|
||||||
|
#define crfFLASH_INDEX 0
|
||||||
|
|
||||||
|
/* Don't allow more than crfMAX_FLASH_TASKS 'fixed delay' co-routines to be
|
||||||
|
created. */
|
||||||
|
#define crfMAX_FLASH_TASKS 8
|
||||||
|
|
||||||
|
/* We don't want to block when posting to the queue. */
|
||||||
|
#define crfPOSTING_BLOCK_TIME 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'fixed delay' co-routine as described at the top of the file.
|
||||||
|
*/
|
||||||
|
static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'flash' co-routine as described at the top of the file.
|
||||||
|
*/
|
||||||
|
static void prvFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex );
|
||||||
|
|
||||||
|
/* The queue used to pass data between the 'fixed delay' co-routines and the
|
||||||
|
'flash' co-routine. */
|
||||||
|
static QueueHandle_t xFlashQueue;
|
||||||
|
|
||||||
|
/* This will be set to pdFALSE if we detect an error. */
|
||||||
|
static BaseType_t xCoRoutineFlashStatus = pdPASS;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See the header file for details.
|
||||||
|
*/
|
||||||
|
void vStartFlashCoRoutines( UBaseType_t uxNumberToCreate )
|
||||||
|
{
|
||||||
|
UBaseType_t uxIndex;
|
||||||
|
|
||||||
|
if( uxNumberToCreate > crfMAX_FLASH_TASKS )
|
||||||
|
{
|
||||||
|
uxNumberToCreate = crfMAX_FLASH_TASKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the queue used to pass data between the co-routines. */
|
||||||
|
xFlashQueue = xQueueCreate( crfQUEUE_LENGTH, sizeof( UBaseType_t ) );
|
||||||
|
|
||||||
|
if( xFlashQueue )
|
||||||
|
{
|
||||||
|
/* Create uxNumberToCreate 'fixed delay' co-routines. */
|
||||||
|
for( uxIndex = 0; uxIndex < uxNumberToCreate; uxIndex++ )
|
||||||
|
{
|
||||||
|
xCoRoutineCreate( prvFixedDelayCoRoutine, crfFIXED_DELAY_PRIORITY, uxIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the 'flash' co-routine. */
|
||||||
|
xCoRoutineCreate( prvFlashCoRoutine, crfFLASH_PRIORITY, crfFLASH_INDEX );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
|
{
|
||||||
|
/* Even though this is a co-routine the xResult variable does not need to be
|
||||||
|
static as we do not need it to maintain its state between blocks. */
|
||||||
|
BaseType_t xResult;
|
||||||
|
/* The uxIndex parameter of the co-routine function is used as an index into
|
||||||
|
the xFlashRates array to obtain the delay period to use. */
|
||||||
|
static const TickType_t xFlashRates[ crfMAX_FLASH_TASKS ] = { 150 / portTICK_PERIOD_MS,
|
||||||
|
200 / portTICK_PERIOD_MS,
|
||||||
|
250 / portTICK_PERIOD_MS,
|
||||||
|
300 / portTICK_PERIOD_MS,
|
||||||
|
350 / portTICK_PERIOD_MS,
|
||||||
|
400 / portTICK_PERIOD_MS,
|
||||||
|
450 / portTICK_PERIOD_MS,
|
||||||
|
500 / portTICK_PERIOD_MS };
|
||||||
|
|
||||||
|
/* Co-routines MUST start with a call to crSTART. */
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Post our uxIndex value onto the queue. This is used as the LED to
|
||||||
|
flash. */
|
||||||
|
crQUEUE_SEND( xHandle, xFlashQueue, ( void * ) &uxIndex, crfPOSTING_BLOCK_TIME, &xResult );
|
||||||
|
|
||||||
|
if( xResult != pdPASS )
|
||||||
|
{
|
||||||
|
/* For the reasons stated at the top of the file we should always
|
||||||
|
find that we can post to the queue. If we could not then an error
|
||||||
|
has occurred. */
|
||||||
|
xCoRoutineFlashStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
crDELAY( xHandle, xFlashRates[ uxIndex ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Co-routines MUST end with a call to crEND. */
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
|
{
|
||||||
|
/* Even though this is a co-routine the variable do not need to be
|
||||||
|
static as we do not need it to maintain their state between blocks. */
|
||||||
|
BaseType_t xResult;
|
||||||
|
UBaseType_t uxLEDToFlash;
|
||||||
|
|
||||||
|
/* Co-routines MUST start with a call to crSTART. */
|
||||||
|
crSTART( xHandle );
|
||||||
|
( void ) uxIndex;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Block to wait for the number of the LED to flash. */
|
||||||
|
crQUEUE_RECEIVE( xHandle, xFlashQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult != pdPASS )
|
||||||
|
{
|
||||||
|
/* We would not expect to wake unless we received something. */
|
||||||
|
xCoRoutineFlashStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We received the number of an LED to flash - flash it! */
|
||||||
|
vParTestToggleLED( uxLEDToFlash );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Co-routines MUST end with a call to crEND. */
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreFlashCoRoutinesStillRunning( void )
|
||||||
|
{
|
||||||
|
/* Return pdPASS or pdFAIL depending on whether an error has been detected
|
||||||
|
or not. */
|
||||||
|
return xCoRoutineFlashStatus;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,274 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This demo file demonstrates how to send data between an ISR and a
|
||||||
|
* co-routine. A tick hook function is used to periodically pass data between
|
||||||
|
* the RTOS tick and a set of 'hook' co-routines.
|
||||||
|
*
|
||||||
|
* hookNUM_HOOK_CO_ROUTINES co-routines are created. Each co-routine blocks
|
||||||
|
* to wait for a character to be received on a queue from the tick ISR, checks
|
||||||
|
* to ensure the character received was that expected, then sends the number
|
||||||
|
* back to the tick ISR on a different queue.
|
||||||
|
*
|
||||||
|
* The tick ISR checks the numbers received back from the 'hook' co-routines
|
||||||
|
* matches the number previously sent.
|
||||||
|
*
|
||||||
|
* If at any time a queue function returns unexpectedly, or an incorrect value
|
||||||
|
* is received either by the tick hook or a co-routine then an error is
|
||||||
|
* latched.
|
||||||
|
*
|
||||||
|
* This demo relies on each 'hook' co-routine to execute between each
|
||||||
|
* hookTICK_CALLS_BEFORE_POST tick interrupts. This and the heavy use of
|
||||||
|
* queues from within an interrupt may result in an error being detected on
|
||||||
|
* slower targets simply due to timing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "croutine.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/* Demo application includes. */
|
||||||
|
#include "crhook.h"
|
||||||
|
|
||||||
|
/* The number of 'hook' co-routines that are to be created. */
|
||||||
|
#define hookNUM_HOOK_CO_ROUTINES ( 4 )
|
||||||
|
|
||||||
|
/* The number of times the tick hook should be called before a character is
|
||||||
|
posted to the 'hook' co-routines. */
|
||||||
|
#define hookTICK_CALLS_BEFORE_POST ( 500 )
|
||||||
|
|
||||||
|
/* There should never be more than one item in any queue at any time. */
|
||||||
|
#define hookHOOK_QUEUE_LENGTH ( 1 )
|
||||||
|
|
||||||
|
/* Don't block when initially posting to the queue. */
|
||||||
|
#define hookNO_BLOCK_TIME ( 0 )
|
||||||
|
|
||||||
|
/* The priority relative to other co-routines (rather than tasks) that the
|
||||||
|
'hook' co-routines should take. */
|
||||||
|
#define mainHOOK_CR_PRIORITY ( 1 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The co-routine function itself.
|
||||||
|
*/
|
||||||
|
static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The tick hook function. This receives a number from each 'hook' co-routine
|
||||||
|
* then sends a number to each co-routine. An error is flagged if a send or
|
||||||
|
* receive fails, or an unexpected number is received.
|
||||||
|
*/
|
||||||
|
void vApplicationTickHook( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Queues used to send data FROM a co-routine TO the tick hook function.
|
||||||
|
The hook functions received (Rx's) on these queues. One queue per
|
||||||
|
'hook' co-routine. */
|
||||||
|
static QueueHandle_t xHookRxQueues[ hookNUM_HOOK_CO_ROUTINES ];
|
||||||
|
|
||||||
|
/* Queues used to send data FROM the tick hook TO a co-routine function.
|
||||||
|
The hood function transmits (Tx's) on these queues. One queue per
|
||||||
|
'hook' co-routine. */
|
||||||
|
static QueueHandle_t xHookTxQueues[ hookNUM_HOOK_CO_ROUTINES ];
|
||||||
|
|
||||||
|
/* Set to true if an error is detected at any time. */
|
||||||
|
static BaseType_t xCoRoutineErrorDetected = pdFALSE;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartHookCoRoutines( void )
|
||||||
|
{
|
||||||
|
UBaseType_t uxIndex, uxValueToPost = 0;
|
||||||
|
|
||||||
|
for( uxIndex = 0; uxIndex < hookNUM_HOOK_CO_ROUTINES; uxIndex++ )
|
||||||
|
{
|
||||||
|
/* Create a queue to transmit to and receive from each 'hook'
|
||||||
|
co-routine. */
|
||||||
|
xHookRxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) );
|
||||||
|
xHookTxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) );
|
||||||
|
|
||||||
|
/* To start things off the tick hook function expects the queue it
|
||||||
|
uses to receive data to contain a value. */
|
||||||
|
xQueueSend( xHookRxQueues[ uxIndex ], &uxValueToPost, hookNO_BLOCK_TIME );
|
||||||
|
|
||||||
|
/* Create the 'hook' co-routine itself. */
|
||||||
|
xCoRoutineCreate( prvHookCoRoutine, mainHOOK_CR_PRIORITY, uxIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static UBaseType_t uxCallCounter = 0, uxNumberToPost = 0;
|
||||||
|
void vApplicationTickHook( void )
|
||||||
|
{
|
||||||
|
UBaseType_t uxReceivedNumber;
|
||||||
|
BaseType_t xIndex, xCoRoutineWoken;
|
||||||
|
|
||||||
|
/* Is it time to talk to the 'hook' co-routines again? */
|
||||||
|
uxCallCounter++;
|
||||||
|
if( uxCallCounter >= hookTICK_CALLS_BEFORE_POST )
|
||||||
|
{
|
||||||
|
uxCallCounter = 0;
|
||||||
|
|
||||||
|
for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ )
|
||||||
|
{
|
||||||
|
xCoRoutineWoken = pdFALSE;
|
||||||
|
if( crQUEUE_RECEIVE_FROM_ISR( xHookRxQueues[ xIndex ], &uxReceivedNumber, &xCoRoutineWoken ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* There is no reason why we would not expect the queue to
|
||||||
|
contain a value. */
|
||||||
|
xCoRoutineErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Each queue used to receive data from the 'hook' co-routines
|
||||||
|
should contain the number we last posted to the same co-routine. */
|
||||||
|
if( uxReceivedNumber != uxNumberToPost )
|
||||||
|
{
|
||||||
|
xCoRoutineErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing should be blocked waiting to post to the queue. */
|
||||||
|
if( xCoRoutineWoken != pdFALSE )
|
||||||
|
{
|
||||||
|
xCoRoutineErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start the next cycle by posting the next number onto each Tx queue. */
|
||||||
|
uxNumberToPost++;
|
||||||
|
|
||||||
|
for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ )
|
||||||
|
{
|
||||||
|
if( crQUEUE_SEND_FROM_ISR( xHookTxQueues[ xIndex ], &uxNumberToPost, pdFALSE ) != pdTRUE )
|
||||||
|
{
|
||||||
|
/* Posting to the queue should have woken the co-routine that
|
||||||
|
was blocked on the queue. */
|
||||||
|
xCoRoutineErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
|
{
|
||||||
|
static UBaseType_t uxReceivedValue[ hookNUM_HOOK_CO_ROUTINES ];
|
||||||
|
BaseType_t xResult;
|
||||||
|
|
||||||
|
/* Each co-routine MUST start with a call to crSTART(); */
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait to receive a value from the tick hook. */
|
||||||
|
xResult = pdFAIL;
|
||||||
|
crQUEUE_RECEIVE( xHandle, xHookTxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), portMAX_DELAY, &xResult );
|
||||||
|
|
||||||
|
/* There is no reason why we should not have received something on
|
||||||
|
the queue. */
|
||||||
|
if( xResult != pdPASS )
|
||||||
|
{
|
||||||
|
xCoRoutineErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the same number back to the idle hook so it can verify it. */
|
||||||
|
xResult = pdFAIL;
|
||||||
|
crQUEUE_SEND( xHandle, xHookRxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), hookNO_BLOCK_TIME, &xResult );
|
||||||
|
if( xResult != pdPASS )
|
||||||
|
{
|
||||||
|
/* There is no reason why we should not have been able to post to
|
||||||
|
the queue. */
|
||||||
|
xCoRoutineErrorDetected = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Each co-routine MUST end with a call to crEND(). */
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xAreHookCoRoutinesStillRunning( void )
|
||||||
|
{
|
||||||
|
if( xCoRoutineErrorDetected )
|
||||||
|
{
|
||||||
|
return pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single persistent task which periodically dynamically creates another
|
||||||
|
* two tasks. The original task is called the creator task, the two tasks it
|
||||||
|
* creates are called suicidal tasks.
|
||||||
|
*
|
||||||
|
* One of the created suicidal tasks kill one other suicidal task before killing
|
||||||
|
* itself - leaving just the original task remaining.
|
||||||
|
*
|
||||||
|
* The creator task must be spawned after all of the other demo application tasks
|
||||||
|
* as it keeps a check on the number of tasks under the scheduler control. The
|
||||||
|
* number of tasks it expects to see running should never be greater than the
|
||||||
|
* number of tasks that were in existence when the creator task was spawned, plus
|
||||||
|
* one set of four suicidal tasks. If this number is exceeded an error is flagged.
|
||||||
|
*
|
||||||
|
* \page DeathC death.c
|
||||||
|
* \ingroup DemoFiles
|
||||||
|
* <HR>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "death.h"
|
||||||
|
|
||||||
|
#define deathSTACK_SIZE ( configMINIMAL_STACK_SIZE + 60 )
|
||||||
|
|
||||||
|
/* The task originally created which is responsible for periodically dynamically
|
||||||
|
creating another four tasks. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vCreateTasks, pvParameters );
|
||||||
|
|
||||||
|
/* The task function of the dynamically created tasks. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vSuicidalTask, pvParameters );
|
||||||
|
|
||||||
|
/* A variable which is incremented every time the dynamic tasks are created. This
|
||||||
|
is used to check that the task is still running. */
|
||||||
|
static volatile uint16_t usCreationCount = 0;
|
||||||
|
|
||||||
|
/* Used to store the number of tasks that were originally running so the creator
|
||||||
|
task can tell if any of the suicidal tasks have failed to die.
|
||||||
|
*/
|
||||||
|
static volatile UBaseType_t uxTasksRunningAtStart = 0;
|
||||||
|
|
||||||
|
/* When a task deletes itself, it stack and TCB are cleaned up by the Idle task.
|
||||||
|
Under heavy load the idle task might not get much processing time, so it would
|
||||||
|
be legitimate for several tasks to remain undeleted for a short period. There
|
||||||
|
may also be a few other unexpected tasks if, for example, the tasks that test
|
||||||
|
static allocation are also being used. */
|
||||||
|
static const UBaseType_t uxMaxNumberOfExtraTasksRunning = 3;
|
||||||
|
|
||||||
|
/* Used to store a handle to the task that should be killed by a suicidal task,
|
||||||
|
before it kills itself. */
|
||||||
|
TaskHandle_t xCreatedTask;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCreateSuicidalTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) NULL, uxPriority, NULL );
|
||||||
|
|
||||||
|
/* Record the number of tasks that are running now so we know if any of the
|
||||||
|
suicidal tasks have failed to be killed. */
|
||||||
|
uxTasksRunningAtStart = ( UBaseType_t ) uxTaskGetNumberOfTasks();
|
||||||
|
|
||||||
|
/* FreeRTOS.org versions before V3.0 started the idle-task as the very
|
||||||
|
first task. The idle task was then already included in uxTasksRunningAtStart.
|
||||||
|
From FreeRTOS V3.0 on, the idle task is started when the scheduler is
|
||||||
|
started. Therefore the idle task is not yet accounted for. We correct
|
||||||
|
this by increasing uxTasksRunningAtStart by 1. */
|
||||||
|
uxTasksRunningAtStart++;
|
||||||
|
|
||||||
|
/* From FreeRTOS version 7.0.0 can optionally create a timer service task.
|
||||||
|
If this is done, then uxTasksRunningAtStart needs incrementing again as that
|
||||||
|
too is created when the scheduler is started. */
|
||||||
|
#if configUSE_TIMERS == 1
|
||||||
|
{
|
||||||
|
uxTasksRunningAtStart++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vSuicidalTask, pvParameters )
|
||||||
|
{
|
||||||
|
volatile long l1, l2;
|
||||||
|
TaskHandle_t xTaskToKill;
|
||||||
|
const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 200 );
|
||||||
|
|
||||||
|
if( pvParameters != NULL )
|
||||||
|
{
|
||||||
|
/* This task is periodically created four times. Two created tasks are
|
||||||
|
passed a handle to the other task so it can kill it before killing itself.
|
||||||
|
The other task is passed in null. */
|
||||||
|
xTaskToKill = *( TaskHandle_t* )pvParameters;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xTaskToKill = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Do something random just to use some stack and registers. */
|
||||||
|
l1 = 2;
|
||||||
|
l2 = 89;
|
||||||
|
l2 *= l1;
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
|
||||||
|
if( xTaskToKill != NULL )
|
||||||
|
{
|
||||||
|
/* Make sure the other task has a go before we delete it. */
|
||||||
|
vTaskDelay( ( TickType_t ) 0 );
|
||||||
|
|
||||||
|
/* Kill the other task that was created by vCreateTasks(). */
|
||||||
|
vTaskDelete( xTaskToKill );
|
||||||
|
|
||||||
|
/* Kill ourselves. */
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCreateTasks, pvParameters )
|
||||||
|
{
|
||||||
|
const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 1000 );
|
||||||
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
|
/* Remove compiler warning about unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
uxPriority = uxTaskPriorityGet( NULL );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Just loop round, delaying then creating the four suicidal tasks. */
|
||||||
|
vTaskDelay( xDelay );
|
||||||
|
|
||||||
|
xCreatedTask = NULL;
|
||||||
|
|
||||||
|
xTaskCreate( vSuicidalTask, "SUICID1", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xCreatedTask );
|
||||||
|
xTaskCreate( vSuicidalTask, "SUICID2", configMINIMAL_STACK_SIZE, &xCreatedTask, uxPriority, NULL );
|
||||||
|
|
||||||
|
++usCreationCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that the creator task is still running and that there
|
||||||
|
are not any more than four extra tasks. */
|
||||||
|
BaseType_t xIsCreateTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
static uint16_t usLastCreationCount = 0xfff;
|
||||||
|
BaseType_t xReturn = pdTRUE;
|
||||||
|
static UBaseType_t uxTasksRunningNow;
|
||||||
|
|
||||||
|
if( usLastCreationCount == usCreationCount )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usLastCreationCount = usCreationCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uxTasksRunningNow = ( UBaseType_t ) uxTaskGetNumberOfTasks();
|
||||||
|
|
||||||
|
if( uxTasksRunningNow < uxTasksRunningAtStart )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Everything is okay. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,518 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first test creates three tasks - two counter tasks (one continuous count
|
||||||
|
* and one limited count) and one controller. A "count" variable is shared
|
||||||
|
* between all three tasks. The two counter tasks should never be in a "ready"
|
||||||
|
* state at the same time. The controller task runs at the same priority as
|
||||||
|
* the continuous count task, and at a lower priority than the limited count
|
||||||
|
* task.
|
||||||
|
*
|
||||||
|
* One counter task loops indefinitely, incrementing the shared count variable
|
||||||
|
* on each iteration. To ensure it has exclusive access to the variable it
|
||||||
|
* raises its priority above that of the controller task before each
|
||||||
|
* increment, lowering it again to its original priority before starting the
|
||||||
|
* next iteration.
|
||||||
|
*
|
||||||
|
* The other counter task increments the shared count variable on each
|
||||||
|
* iteration of its loop until the count has reached a limit of 0xff - at
|
||||||
|
* which point it suspends itself. It will not start a new loop until the
|
||||||
|
* controller task has made it "ready" again by calling vTaskResume().
|
||||||
|
* This second counter task operates at a higher priority than controller
|
||||||
|
* task so does not need to worry about mutual exclusion of the counter
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* The controller task is in two sections. The first section controls and
|
||||||
|
* monitors the continuous count task. When this section is operational the
|
||||||
|
* limited count task is suspended. Likewise, the second section controls
|
||||||
|
* and monitors the limited count task. When this section is operational the
|
||||||
|
* continuous count task is suspended.
|
||||||
|
*
|
||||||
|
* In the first section the controller task first takes a copy of the shared
|
||||||
|
* count variable. To ensure mutual exclusion on the count variable it
|
||||||
|
* suspends the continuous count task, resuming it again when the copy has been
|
||||||
|
* taken. The controller task then sleeps for a fixed period - during which
|
||||||
|
* the continuous count task will execute and increment the shared variable.
|
||||||
|
* When the controller task wakes it checks that the continuous count task
|
||||||
|
* has executed by comparing the copy of the shared variable with its current
|
||||||
|
* value. This time, to ensure mutual exclusion, the scheduler itself is
|
||||||
|
* suspended with a call to vTaskSuspendAll (). This is for demonstration
|
||||||
|
* purposes only and is not a recommended technique due to its inefficiency.
|
||||||
|
*
|
||||||
|
* After a fixed number of iterations the controller task suspends the
|
||||||
|
* continuous count task, and moves on to its second section.
|
||||||
|
*
|
||||||
|
* At the start of the second section the shared variable is cleared to zero.
|
||||||
|
* The limited count task is then woken from its suspension by a call to
|
||||||
|
* vTaskResume (). As this counter task operates at a higher priority than
|
||||||
|
* the controller task the controller task should not run again until the
|
||||||
|
* shared variable has been counted up to the limited value causing the counter
|
||||||
|
* task to suspend itself. The next line after vTaskResume () is therefore
|
||||||
|
* a check on the shared variable to ensure everything is as expected.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* The second test consists of a couple of very simple tasks that post onto a
|
||||||
|
* queue while the scheduler is suspended. This test was added to test parts
|
||||||
|
* of the scheduler not exercised by the first test.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo app include files. */
|
||||||
|
#include "dynamic.h"
|
||||||
|
|
||||||
|
/* Function that implements the "limited count" task as described above. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters );
|
||||||
|
|
||||||
|
/* Function that implements the "continuous count" task as described above. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters );
|
||||||
|
|
||||||
|
/* Function that implements the controller task as described above. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters );
|
||||||
|
|
||||||
|
static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters );
|
||||||
|
|
||||||
|
/* Demo task specific constants. */
|
||||||
|
#define priSTACK_SIZE ( configMINIMAL_STACK_SIZE )
|
||||||
|
#define priSLEEP_TIME pdMS_TO_TICKS( 128 )
|
||||||
|
#define priLOOPS ( 5 )
|
||||||
|
#define priMAX_COUNT ( ( uint32_t ) 0xff )
|
||||||
|
#define priNO_BLOCK ( ( TickType_t ) 0 )
|
||||||
|
#define priSUSPENDED_QUEUE_LENGTH ( 1 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Handles to the two counter tasks. These could be passed in as parameters
|
||||||
|
to the controller task to prevent them having to be file scope. */
|
||||||
|
static TaskHandle_t xContinuousIncrementHandle, xLimitedIncrementHandle;
|
||||||
|
|
||||||
|
/* The shared counter variable. This is passed in as a parameter to the two
|
||||||
|
counter variables for demonstration purposes. */
|
||||||
|
static volatile uint32_t ulCounter;
|
||||||
|
|
||||||
|
/* Variables used to check that the tasks are still operating without error.
|
||||||
|
Each complete iteration of the controller task increments this variable
|
||||||
|
provided no errors have been found. The variable maintaining the same value
|
||||||
|
is therefore indication of an error. */
|
||||||
|
static volatile uint16_t usCheckVariable = ( uint16_t ) 0;
|
||||||
|
static volatile BaseType_t xSuspendedQueueSendError = pdFALSE;
|
||||||
|
static volatile BaseType_t xSuspendedQueueReceiveError = pdFALSE;
|
||||||
|
|
||||||
|
/* Queue used by the second test. */
|
||||||
|
QueueHandle_t xSuspendedTestQueue;
|
||||||
|
|
||||||
|
/* The value the queue receive task expects to receive next. This is file
|
||||||
|
scope so xAreDynamicPriorityTasksStillRunning() can ensure it is still
|
||||||
|
incrementing. */
|
||||||
|
static uint32_t ulExpectedValue = ( uint32_t ) 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Start the three tasks as described at the top of the file.
|
||||||
|
* Note that the limited count task is given a higher priority.
|
||||||
|
*/
|
||||||
|
void vStartDynamicPriorityTasks( void )
|
||||||
|
{
|
||||||
|
xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( uint32_t ) );
|
||||||
|
|
||||||
|
if( xSuspendedTestQueue != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the queue to the queue registry, if one is
|
||||||
|
in use. The queue registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate queues and has no purpose if a kernel aware debugger
|
||||||
|
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||||
|
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||||
|
defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( xSuspendedTestQueue, "Suspended_Test_Queue" );
|
||||||
|
|
||||||
|
xTaskCreate( vContinuousIncrementTask, "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle );
|
||||||
|
xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );
|
||||||
|
xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just loops around incrementing the shared variable until the limit has been
|
||||||
|
* reached. Once the limit has been reached it suspends itself.
|
||||||
|
*/
|
||||||
|
static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t *pulCounter;
|
||||||
|
|
||||||
|
/* Take a pointer to the shared variable from the parameters passed into
|
||||||
|
the task. */
|
||||||
|
pulCounter = ( uint32_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* This will run before the control task, so the first thing it does is
|
||||||
|
suspend - the control task will resume it when ready. */
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Just count up to a value then suspend. */
|
||||||
|
( *pulCounter )++;
|
||||||
|
|
||||||
|
if( *pulCounter >= priMAX_COUNT )
|
||||||
|
{
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just keep counting the shared variable up. The control task will suspend
|
||||||
|
* this task when it wants.
|
||||||
|
*/
|
||||||
|
static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters )
|
||||||
|
{
|
||||||
|
volatile uint32_t *pulCounter;
|
||||||
|
UBaseType_t uxOurPriority;
|
||||||
|
|
||||||
|
/* Take a pointer to the shared variable from the parameters passed into
|
||||||
|
the task. */
|
||||||
|
pulCounter = ( uint32_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* Query our priority so we can raise it when exclusive access to the
|
||||||
|
shared variable is required. */
|
||||||
|
uxOurPriority = uxTaskPriorityGet( NULL );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Raise the priority above the controller task to ensure a context
|
||||||
|
switch does not occur while the variable is being accessed. */
|
||||||
|
vTaskPrioritySet( NULL, uxOurPriority + 1 );
|
||||||
|
{
|
||||||
|
configASSERT( ( uxTaskPriorityGet( NULL ) == ( uxOurPriority + 1 ) ) );
|
||||||
|
( *pulCounter )++;
|
||||||
|
}
|
||||||
|
vTaskPrioritySet( NULL, uxOurPriority );
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
configASSERT( ( uxTaskPriorityGet( NULL ) == uxOurPriority ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controller task as described above.
|
||||||
|
*/
|
||||||
|
static portTASK_FUNCTION( vCounterControlTask, pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulLastCounter;
|
||||||
|
short sLoops;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Start with the counter at zero. */
|
||||||
|
ulCounter = ( uint32_t ) 0;
|
||||||
|
|
||||||
|
/* First section : */
|
||||||
|
|
||||||
|
/* Check the continuous count task is running. */
|
||||||
|
for( sLoops = 0; sLoops < priLOOPS; sLoops++ )
|
||||||
|
{
|
||||||
|
/* Suspend the continuous count task so we can take a mirror of the
|
||||||
|
shared variable without risk of corruption. This is not really
|
||||||
|
needed as the other task raises its priority above this task's
|
||||||
|
priority. */
|
||||||
|
vTaskSuspend( xContinuousIncrementHandle );
|
||||||
|
{
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
ulLastCounter = ulCounter;
|
||||||
|
}
|
||||||
|
vTaskResume( xContinuousIncrementHandle );
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* Now delay to ensure the other task has processor time. */
|
||||||
|
vTaskDelay( priSLEEP_TIME );
|
||||||
|
|
||||||
|
/* Check the shared variable again. This time to ensure mutual
|
||||||
|
exclusion the whole scheduler will be locked. This is just for
|
||||||
|
demo purposes! */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
if( ulLastCounter == ulCounter )
|
||||||
|
{
|
||||||
|
/* The shared variable has not changed. There is a problem
|
||||||
|
with the continuous count task so flag an error. */
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second section: */
|
||||||
|
|
||||||
|
/* Suspend the continuous counter task so it stops accessing the shared
|
||||||
|
variable. */
|
||||||
|
vTaskSuspend( xContinuousIncrementHandle );
|
||||||
|
|
||||||
|
/* Reset the variable. */
|
||||||
|
ulCounter = ( uint32_t ) 0;
|
||||||
|
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* Resume the limited count task which has a higher priority than us.
|
||||||
|
We should therefore not return from this call until the limited count
|
||||||
|
task has suspended itself with a known value in the counter variable. */
|
||||||
|
vTaskResume( xLimitedIncrementHandle );
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This task should not run again until xLimitedIncrementHandle has
|
||||||
|
suspended itself. */
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* Does the counter variable have the expected value? */
|
||||||
|
if( ulCounter != priMAX_COUNT )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If no errors have occurred then increment the check variable. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
usCheckVariable++;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resume the continuous count task and do it all again. */
|
||||||
|
vTaskResume( xContinuousIncrementHandle );
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters )
|
||||||
|
{
|
||||||
|
static uint32_t ulValueToSend = ( uint32_t ) 0;
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
/* We must not block while the scheduler is suspended! */
|
||||||
|
if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE )
|
||||||
|
{
|
||||||
|
xSuspendedQueueSendError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
vTaskDelay( priSLEEP_TIME );
|
||||||
|
|
||||||
|
++ulValueToSend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters )
|
||||||
|
{
|
||||||
|
uint32_t ulReceivedValue;
|
||||||
|
BaseType_t xGotValue;
|
||||||
|
|
||||||
|
/* Just to stop warning messages. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Suspending the scheduler here is fairly pointless and
|
||||||
|
undesirable for a normal application. It is done here purely
|
||||||
|
to test the scheduler. The inner xTaskResumeAll() should
|
||||||
|
never return pdTRUE as the scheduler is still locked by the
|
||||||
|
outer call. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK );
|
||||||
|
}
|
||||||
|
if( xTaskResumeAll() != pdFALSE )
|
||||||
|
{
|
||||||
|
xSuspendedQueueReceiveError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xTaskResumeAll();
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} while( xGotValue == pdFALSE );
|
||||||
|
|
||||||
|
if( ulReceivedValue != ulExpectedValue )
|
||||||
|
{
|
||||||
|
xSuspendedQueueReceiveError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSuspendedQueueReceiveError != pdTRUE )
|
||||||
|
{
|
||||||
|
/* Only increment the variable if an error has not occurred. This
|
||||||
|
allows xAreDynamicPriorityTasksStillRunning() to check for stalled
|
||||||
|
tasks as well as explicit errors. */
|
||||||
|
++ulExpectedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Called to check that all the created tasks are still running without error. */
|
||||||
|
BaseType_t xAreDynamicPriorityTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
/* Keep a history of the check variables so we know if it has been incremented
|
||||||
|
since the last call. */
|
||||||
|
static uint16_t usLastTaskCheck = ( uint16_t ) 0;
|
||||||
|
static uint32_t ulLastExpectedValue = ( uint32_t ) 0U;
|
||||||
|
BaseType_t xReturn = pdTRUE;
|
||||||
|
|
||||||
|
/* Check the tasks are still running by ensuring the check variable
|
||||||
|
is still incrementing. */
|
||||||
|
|
||||||
|
if( usCheckVariable == usLastTaskCheck )
|
||||||
|
{
|
||||||
|
/* The check has not incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulExpectedValue == ulLastExpectedValue )
|
||||||
|
{
|
||||||
|
/* The value being received by the queue receive task has not
|
||||||
|
incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSuspendedQueueSendError == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xSuspendedQueueReceiveError == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
usLastTaskCheck = usCheckVariable;
|
||||||
|
ulLastExpectedValue = ulExpectedValue;
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This version of flash .c is for use on systems that have limited stack space
|
||||||
|
* and no display facilities. The complete version can be found in the
|
||||||
|
* Demo/Common/Full directory.
|
||||||
|
*
|
||||||
|
* Three tasks are created, each of which flash an LED at a different rate. The first
|
||||||
|
* LED flashes every 200ms, the second every 400ms, the third every 600ms.
|
||||||
|
*
|
||||||
|
* The LED flash tasks provide instant visual feedback. They show that the scheduler
|
||||||
|
* is still operational.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "partest.h"
|
||||||
|
#include "flash.h"
|
||||||
|
|
||||||
|
#define ledSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define ledNUMBER_OF_LEDS ( 3 )
|
||||||
|
#define ledFLASH_RATE_BASE ( ( TickType_t ) 333 )
|
||||||
|
|
||||||
|
/* Variable used by the created tasks to calculate the LED number to use, and
|
||||||
|
the rate at which they should flash the LED. */
|
||||||
|
static volatile UBaseType_t uxFlashTaskNumber = 0;
|
||||||
|
|
||||||
|
/* The task that is created three times. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartLEDFlashTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
BaseType_t xLEDTask;
|
||||||
|
|
||||||
|
/* Create the three tasks. */
|
||||||
|
for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )
|
||||||
|
{
|
||||||
|
/* Spawn the task. */
|
||||||
|
xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vLEDFlashTask, pvParameters )
|
||||||
|
{
|
||||||
|
TickType_t xFlashRate, xLastFlashTime;
|
||||||
|
UBaseType_t uxLED;
|
||||||
|
|
||||||
|
/* The parameters are not used. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Calculate the LED and flash rate. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* See which of the eight LED's we should use. */
|
||||||
|
uxLED = uxFlashTaskNumber;
|
||||||
|
|
||||||
|
/* Update so the next task uses the next LED. */
|
||||||
|
uxFlashTaskNumber++;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( TickType_t ) uxLED );
|
||||||
|
xFlashRate /= portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
/* We will turn the LED on and off again in the delay period, so each
|
||||||
|
delay is only half the total period. */
|
||||||
|
xFlashRate /= ( TickType_t ) 2;
|
||||||
|
|
||||||
|
/* We need to initialise xLastFlashTime prior to the first call to
|
||||||
|
vTaskDelayUntil(). */
|
||||||
|
xLastFlashTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
/* Delay for half the flash period then turn the LED on. */
|
||||||
|
vTaskDelayUntil( &xLastFlashTime, xFlashRate );
|
||||||
|
vParTestToggleLED( uxLED );
|
||||||
|
|
||||||
|
/* Delay for half the flash period then turn the LED off. */
|
||||||
|
vTaskDelayUntil( &xLastFlashTime, xFlashRate );
|
||||||
|
vParTestToggleLED( uxLED );
|
||||||
|
}
|
||||||
|
} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeatedly toggles one or more LEDs using software timers - one timer per
|
||||||
|
* LED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "partest.h"
|
||||||
|
#include "flash_timer.h"
|
||||||
|
|
||||||
|
/* The toggle rates are all a multple of ledFLASH_RATE_BASE. */
|
||||||
|
#define ledFLASH_RATE_BASE ( ( ( TickType_t ) 333 ) / portTICK_PERIOD_MS )
|
||||||
|
|
||||||
|
/* A block time of zero simple means "don't block". */
|
||||||
|
#define ledDONT_BLOCK ( ( TickType_t ) 0 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The callback function used by each LED flashing timer. All the timers use
|
||||||
|
* this function, and the timer ID is used within the function to determine
|
||||||
|
* which timer has actually expired.
|
||||||
|
*/
|
||||||
|
static void prvLEDTimerCallback( TimerHandle_t xTimer );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartLEDFlashTimers( UBaseType_t uxNumberOfLEDs )
|
||||||
|
{
|
||||||
|
UBaseType_t uxLEDTimer;
|
||||||
|
TimerHandle_t xTimer;
|
||||||
|
|
||||||
|
/* Create and start the requested number of timers. */
|
||||||
|
for( uxLEDTimer = 0; uxLEDTimer < uxNumberOfLEDs; ++uxLEDTimer )
|
||||||
|
{
|
||||||
|
/* Create the timer. */
|
||||||
|
xTimer = xTimerCreate( "Flasher", /* A text name, purely to help debugging. */
|
||||||
|
ledFLASH_RATE_BASE * ( uxLEDTimer + 1 ),/* The timer period, which is a multiple of ledFLASH_RATE_BASE. */
|
||||||
|
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
||||||
|
( void * ) uxLEDTimer, /* The ID is used to identify the timer within the timer callback function, as each timer uses the same callback. */
|
||||||
|
prvLEDTimerCallback /* Each timer uses the same callback. */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* If the timer was created successfully, attempt to start it. If the
|
||||||
|
scheduler has not yet been started then the timer command queue must
|
||||||
|
be long enough to hold each command sent to it until such time that the
|
||||||
|
scheduler is started. The timer command queue length is set by
|
||||||
|
configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h. */
|
||||||
|
if( xTimer != NULL )
|
||||||
|
{
|
||||||
|
xTimerStart( xTimer, ledDONT_BLOCK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvLEDTimerCallback( TimerHandle_t xTimer )
|
||||||
|
{
|
||||||
|
BaseType_t xTimerID;
|
||||||
|
|
||||||
|
/* The timer ID is used to identify the timer that has actually expired as
|
||||||
|
each timer uses the same callback. The ID is then also used as the number
|
||||||
|
of the LED that is to be toggled. */
|
||||||
|
xTimerID = ( BaseType_t ) pvTimerGetTimerID( xTimer );
|
||||||
|
vParTestToggleLED( xTimerID );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,391 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates eight tasks, each of which loops continuously performing a floating
|
||||||
|
* point calculation.
|
||||||
|
*
|
||||||
|
* All the tasks run at the idle priority and never block or yield. This causes
|
||||||
|
* all eight tasks to time slice with the idle task. Running at the idle
|
||||||
|
* priority means that these tasks will get pre-empted any time another task is
|
||||||
|
* ready to run or a time slice occurs. More often than not the pre-emption
|
||||||
|
* will occur mid calculation, creating a good test of the schedulers context
|
||||||
|
* switch mechanism - a calculation producing an unexpected result could be a
|
||||||
|
* symptom of a corruption in the context of a task.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "flop.h"
|
||||||
|
|
||||||
|
#ifndef mathSTACK_SIZE
|
||||||
|
#define mathSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define mathNUMBER_OF_TASKS ( 4 )
|
||||||
|
|
||||||
|
/* Four tasks, each of which performs a different floating point calculation.
|
||||||
|
Each of the four is created twice. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );
|
||||||
|
|
||||||
|
/* These variables are used to check that all the tasks are still running. If a
|
||||||
|
task gets a calculation wrong it will stop setting its check variable. */
|
||||||
|
static volatile uint16_t usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 };
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartMathTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )
|
||||||
|
{
|
||||||
|
volatile portDOUBLE d1, d2, d3, d4;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
volatile portDOUBLE dAnswer;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Some ports require that tasks that use a hardware floating point unit
|
||||||
|
tell the kernel that they require a floating point context before any
|
||||||
|
floating point instructions are executed. */
|
||||||
|
portTASK_USES_FLOATING_POINT();
|
||||||
|
|
||||||
|
d1 = 123.4567;
|
||||||
|
d2 = 2345.6789;
|
||||||
|
d3 = -918.222;
|
||||||
|
|
||||||
|
dAnswer = ( d1 + d2 ) * d3;
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
d1 = 123.4567;
|
||||||
|
d2 = 2345.6789;
|
||||||
|
d3 = -918.222;
|
||||||
|
|
||||||
|
d4 = ( d1 + d2 ) * d3;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( fabs( d4 - dAnswer ) > 0.001 )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct then set set the check
|
||||||
|
variable. The check variable will get set to pdFALSE each time
|
||||||
|
xAreMathsTaskStillRunning() is executed. */
|
||||||
|
( *pusTaskCheckVariable ) = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )
|
||||||
|
{
|
||||||
|
volatile portDOUBLE d1, d2, d3, d4;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
volatile portDOUBLE dAnswer;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Some ports require that tasks that use a hardware floating point unit
|
||||||
|
tell the kernel that they require a floating point context before any
|
||||||
|
floating point instructions are executed. */
|
||||||
|
portTASK_USES_FLOATING_POINT();
|
||||||
|
|
||||||
|
d1 = -389.38;
|
||||||
|
d2 = 32498.2;
|
||||||
|
d3 = -2.0001;
|
||||||
|
|
||||||
|
dAnswer = ( d1 / d2 ) * d3;
|
||||||
|
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
d1 = -389.38;
|
||||||
|
d2 = 32498.2;
|
||||||
|
d3 = -2.0001;
|
||||||
|
|
||||||
|
d4 = ( d1 / d2 ) * d3;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( fabs( d4 - dAnswer ) > 0.001 )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct then set set the check
|
||||||
|
variable. The check variable will get set to pdFALSE each time
|
||||||
|
xAreMathsTaskStillRunning() is executed. */
|
||||||
|
( *pusTaskCheckVariable ) = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )
|
||||||
|
{
|
||||||
|
volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
const size_t xArraySize = 10;
|
||||||
|
size_t xPosition;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Some ports require that tasks that use a hardware floating point unit
|
||||||
|
tell the kernel that they require a floating point context before any
|
||||||
|
floating point instructions are executed. */
|
||||||
|
portTASK_USES_FLOATING_POINT();
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
|
||||||
|
|
||||||
|
/* Keep filling an array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
dTotal1 = 0.0;
|
||||||
|
dTotal2 = 0.0;
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;
|
||||||
|
dTotal1 += ( portDOUBLE ) xPosition + 5.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
dTotal2 += pdArray[ xPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
dDifference = dTotal1 - dTotal2;
|
||||||
|
if( fabs( dDifference ) > 0.001 )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct then set set the check
|
||||||
|
variable. The check variable will get set to pdFALSE each time
|
||||||
|
xAreMathsTaskStillRunning() is executed. */
|
||||||
|
( *pusTaskCheckVariable ) = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )
|
||||||
|
{
|
||||||
|
volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
const size_t xArraySize = 10;
|
||||||
|
size_t xPosition;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* Some ports require that tasks that use a hardware floating point unit
|
||||||
|
tell the kernel that they require a floating point context before any
|
||||||
|
floating point instructions are executed. */
|
||||||
|
portTASK_USES_FLOATING_POINT();
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );
|
||||||
|
|
||||||
|
/* Keep filling an array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
dTotal1 = 0.0;
|
||||||
|
dTotal2 = 0.0;
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;
|
||||||
|
dTotal1 += ( portDOUBLE ) xPosition * 12.123;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
dTotal2 += pdArray[ xPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
dDifference = dTotal1 - dTotal2;
|
||||||
|
if( fabs( dDifference ) > 0.001 )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct then set set the check
|
||||||
|
variable. The check variable will get set to pdFALSE each time
|
||||||
|
xAreMathsTaskStillRunning() is executed. */
|
||||||
|
( *pusTaskCheckVariable ) = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreMathsTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn = pdPASS, xTask;
|
||||||
|
|
||||||
|
/* Check the maths tasks are still running by ensuring their check variables
|
||||||
|
have been set to pdPASS. */
|
||||||
|
for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
|
||||||
|
{
|
||||||
|
if( usTaskCheck[ xTask ] != pdTRUE )
|
||||||
|
{
|
||||||
|
/* The check has not been set so the associated task has either
|
||||||
|
stalled or detected an error. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reset the variable so it can be checked again the next time this
|
||||||
|
function is executed. */
|
||||||
|
usTaskCheck[ xTask ] = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates one or more tasks that repeatedly perform a set of integer
|
||||||
|
* calculations. The result of each run-time calculation is compared to the
|
||||||
|
* known expected result - with a mismatch being indicative of an error in the
|
||||||
|
* context switch mechanism.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "integer.h"
|
||||||
|
|
||||||
|
/* The constants used in the calculation. */
|
||||||
|
#define intgCONST1 ( ( long ) 123 )
|
||||||
|
#define intgCONST2 ( ( long ) 234567 )
|
||||||
|
#define intgCONST3 ( ( long ) -3 )
|
||||||
|
#define intgCONST4 ( ( long ) 7 )
|
||||||
|
#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 )
|
||||||
|
|
||||||
|
#define intgSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
/* As this is the minimal version, we will only create one task. */
|
||||||
|
#define intgNUMBER_OF_TASKS ( 1 )
|
||||||
|
|
||||||
|
/* The task function. Repeatedly performs a 32 bit calculation, checking the
|
||||||
|
result against the expected result. If the result is incorrect then the
|
||||||
|
context switch must have caused some corruption. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompeteingIntMathTask, pvParameters );
|
||||||
|
|
||||||
|
/* Variables that are set to true within the calculation task to indicate
|
||||||
|
that the task is still executing. The check task sets the variable back to
|
||||||
|
false, flagging an error if the variable is still false the next time it
|
||||||
|
is called. */
|
||||||
|
static volatile BaseType_t xTaskCheck[ intgNUMBER_OF_TASKS ] = { ( BaseType_t ) pdFALSE };
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartIntegerMathTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
short sTask;
|
||||||
|
|
||||||
|
for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ )
|
||||||
|
{
|
||||||
|
xTaskCreate( vCompeteingIntMathTask, "IntMath", intgSTACK_SIZE, ( void * ) &( xTaskCheck[ sTask ] ), uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompeteingIntMathTask, pvParameters )
|
||||||
|
{
|
||||||
|
/* These variables are all effectively set to constants so they are volatile to
|
||||||
|
ensure the compiler does not just get rid of them. */
|
||||||
|
volatile long lValue;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
volatile BaseType_t *pxTaskHasExecuted;
|
||||||
|
|
||||||
|
/* Set a pointer to the variable we are going to set to true each
|
||||||
|
iteration. This is also a good test of the parameter passing mechanism
|
||||||
|
within each port. */
|
||||||
|
pxTaskHasExecuted = ( volatile BaseType_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Perform the calculation. This will store partial value in
|
||||||
|
registers, resulting in a good test of the context switch mechanism. */
|
||||||
|
lValue = intgCONST1;
|
||||||
|
lValue += intgCONST2;
|
||||||
|
|
||||||
|
/* Yield in case cooperative scheduling is being used. */
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Finish off the calculation. */
|
||||||
|
lValue *= intgCONST3;
|
||||||
|
lValue /= intgCONST4;
|
||||||
|
|
||||||
|
/* If the calculation is found to be incorrect we stop setting the
|
||||||
|
TaskHasExecuted variable so the check task can see an error has
|
||||||
|
occurred. */
|
||||||
|
if( lValue != intgEXPECTED_ANSWER ) /*lint !e774 volatile used to prevent this being optimised out. */
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* We have not encountered any errors, so set the flag that show
|
||||||
|
we are still executing. This will be periodically cleared by
|
||||||
|
the check task. */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
*pxTaskHasExecuted = pdTRUE;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yield in case cooperative scheduling is being used. */
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreIntegerMathsTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn = pdTRUE;
|
||||||
|
short sTask;
|
||||||
|
|
||||||
|
/* Check the maths tasks are still running by ensuring their check variables
|
||||||
|
are still being set to true. */
|
||||||
|
for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ )
|
||||||
|
{
|
||||||
|
if( xTaskCheck[ sTask ] == pdFALSE )
|
||||||
|
{
|
||||||
|
/* The check has not incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the check variable so we can tell if it has been set by
|
||||||
|
the next time around. */
|
||||||
|
xTaskCheck[ sTask ] = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
This directory contains the implementation of the "common demo tasks". These
|
||||||
|
are test tasks and demo tasks that are used by nearly all the demo applications.
|
|
@ -0,0 +1,454 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The tasks defined on this page demonstrate the use of recursive mutexes.
|
||||||
|
|
||||||
|
For recursive mutex functionality the created mutex should be created using
|
||||||
|
xSemaphoreCreateRecursiveMutex(), then be manipulated
|
||||||
|
using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API
|
||||||
|
functions.
|
||||||
|
|
||||||
|
This demo creates three tasks all of which access the same recursive mutex:
|
||||||
|
|
||||||
|
prvRecursiveMutexControllingTask() has the highest priority so executes
|
||||||
|
first and grabs the mutex. It then performs some recursive accesses -
|
||||||
|
between each of which it sleeps for a short period to let the lower
|
||||||
|
priority tasks execute. When it has completed its demo functionality
|
||||||
|
it gives the mutex back before suspending itself.
|
||||||
|
|
||||||
|
prvRecursiveMutexBlockingTask() attempts to access the mutex by performing
|
||||||
|
a blocking 'take'. The blocking task has a lower priority than the
|
||||||
|
controlling task so by the time it executes the mutex has already been
|
||||||
|
taken by the controlling task, causing the blocking task to block. It
|
||||||
|
does not unblock until the controlling task has given the mutex back,
|
||||||
|
and it does not actually run until the controlling task has suspended
|
||||||
|
itself (due to the relative priorities). When it eventually does obtain
|
||||||
|
the mutex all it does is give the mutex back prior to also suspending
|
||||||
|
itself. At this point both the controlling task and the blocking task are
|
||||||
|
suspended.
|
||||||
|
|
||||||
|
prvRecursiveMutexPollingTask() runs at the idle priority. It spins round
|
||||||
|
a tight loop attempting to obtain the mutex with a non-blocking call. As
|
||||||
|
the lowest priority task it will not successfully obtain the mutex until
|
||||||
|
both the controlling and blocking tasks are suspended. Once it eventually
|
||||||
|
does obtain the mutex it first unsuspends both the controlling task and
|
||||||
|
blocking task prior to giving the mutex back - resulting in the polling
|
||||||
|
task temporarily inheriting the controlling tasks priority.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo app include files. */
|
||||||
|
#include "recmutex.h"
|
||||||
|
|
||||||
|
/* Priorities assigned to the three tasks. recmuCONTROLLING_TASK_PRIORITY can
|
||||||
|
be overridden by a definition in FreeRTOSConfig.h. */
|
||||||
|
#ifndef recmuCONTROLLING_TASK_PRIORITY
|
||||||
|
#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#endif
|
||||||
|
#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 )
|
||||||
|
|
||||||
|
/* The recursive call depth. */
|
||||||
|
#define recmuMAX_COUNT ( 10 )
|
||||||
|
|
||||||
|
/* Misc. */
|
||||||
|
#define recmuSHORT_DELAY ( pdMS_TO_TICKS( 20 ) )
|
||||||
|
#define recmuNO_DELAY ( ( TickType_t ) 0 )
|
||||||
|
#define recmu15ms_DELAY ( pdMS_TO_TICKS( 15 ) )
|
||||||
|
|
||||||
|
/* The three tasks as described at the top of this file. */
|
||||||
|
static void prvRecursiveMutexControllingTask( void *pvParameters );
|
||||||
|
static void prvRecursiveMutexBlockingTask( void *pvParameters );
|
||||||
|
static void prvRecursiveMutexPollingTask( void *pvParameters );
|
||||||
|
|
||||||
|
/* The mutex used by the demo. */
|
||||||
|
static SemaphoreHandle_t xMutex;
|
||||||
|
|
||||||
|
/* Variables used to detect and latch errors. */
|
||||||
|
static volatile BaseType_t xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE;
|
||||||
|
static volatile UBaseType_t uxControllingCycles = 0, uxBlockingCycles = 0, uxPollingCycles = 0;
|
||||||
|
|
||||||
|
/* Handles of the two higher priority tasks, required so they can be resumed
|
||||||
|
(unsuspended). */
|
||||||
|
static TaskHandle_t xControllingTaskHandle, xBlockingTaskHandle;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartRecursiveMutexTasks( void )
|
||||||
|
{
|
||||||
|
/* Just creates the mutex and the three tasks. */
|
||||||
|
|
||||||
|
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
|
|
||||||
|
if( xMutex != NULL )
|
||||||
|
{
|
||||||
|
/* vQueueAddToRegistry() adds the mutex to the registry, if one is
|
||||||
|
in use. The registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate mutex and has no purpose if a kernel aware debugger
|
||||||
|
is not being used. The call to vQueueAddToRegistry() will be removed
|
||||||
|
by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
|
||||||
|
defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Recursive_Mutex" );
|
||||||
|
|
||||||
|
xTaskCreate( prvRecursiveMutexControllingTask, "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle );
|
||||||
|
xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );
|
||||||
|
xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRecursiveMutexControllingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
UBaseType_t ux;
|
||||||
|
|
||||||
|
/* Just to remove compiler warning. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Should not be able to 'give' the mutex, as we have not yet 'taken'
|
||||||
|
it. The first time through, the mutex will not have been used yet,
|
||||||
|
subsequent times through, at this point the mutex will be held by the
|
||||||
|
polling task. */
|
||||||
|
if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ux = 0; ux < recmuMAX_COUNT; ux++ )
|
||||||
|
{
|
||||||
|
/* We should now be able to take the mutex as many times as
|
||||||
|
we like.
|
||||||
|
|
||||||
|
The first time through the mutex will be immediately available, on
|
||||||
|
subsequent times through the mutex will be held by the polling task
|
||||||
|
at this point and this Take will cause the polling task to inherit
|
||||||
|
the priority of this task. In this case the block time must be
|
||||||
|
long enough to ensure the polling task will execute again before the
|
||||||
|
block time expires. If the block time does expire then the error
|
||||||
|
flag will be set here. */
|
||||||
|
if( xSemaphoreTakeRecursive( xMutex, recmu15ms_DELAY ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the other task attempting to access the mutex (and the
|
||||||
|
other demo tasks) are able to execute to ensure they either block
|
||||||
|
(where a block time is specified) or return an error (where no
|
||||||
|
block time is specified) as the mutex is held by this task. */
|
||||||
|
vTaskDelay( recmuSHORT_DELAY );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For each time we took the mutex, give it back. */
|
||||||
|
for( ux = 0; ux < recmuMAX_COUNT; ux++ )
|
||||||
|
{
|
||||||
|
/* Ensure the other task attempting to access the mutex (and the
|
||||||
|
other demo tasks) are able to execute. */
|
||||||
|
vTaskDelay( recmuSHORT_DELAY );
|
||||||
|
|
||||||
|
/* We should now be able to give the mutex as many times as we
|
||||||
|
took it. When the mutex is available again the Blocking task
|
||||||
|
should be unblocked but not run because it has a lower priority
|
||||||
|
than this task. The polling task should also not run at this point
|
||||||
|
as it too has a lower priority than this task. */
|
||||||
|
if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Having given it back the same number of times as it was taken, we
|
||||||
|
should no longer be the mutex owner, so the next give should fail. */
|
||||||
|
if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep count of the number of cycles this task has performed so a
|
||||||
|
stall can be detected. */
|
||||||
|
uxControllingCycles++;
|
||||||
|
|
||||||
|
/* Suspend ourselves so the blocking task can execute. */
|
||||||
|
xControllingIsSuspended = pdTRUE;
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
xControllingIsSuspended = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRecursiveMutexBlockingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Just to remove compiler warning. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* This task will run while the controlling task is blocked, and the
|
||||||
|
controlling task will block only once it has the mutex - therefore
|
||||||
|
this call should block until the controlling task has given up the
|
||||||
|
mutex, and not actually execute past this call until the controlling
|
||||||
|
task is suspended. portMAX_DELAY - 1 is used instead of portMAX_DELAY
|
||||||
|
to ensure the task's state is reported as Blocked and not Suspended in
|
||||||
|
a later call to configASSERT() (within the polling task). */
|
||||||
|
if( xSemaphoreTakeRecursive( xMutex, ( portMAX_DELAY - 1 ) ) == pdPASS )
|
||||||
|
{
|
||||||
|
if( xControllingIsSuspended != pdTRUE )
|
||||||
|
{
|
||||||
|
/* Did not expect to execute until the controlling task was
|
||||||
|
suspended. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Give the mutex back before suspending ourselves to allow
|
||||||
|
the polling task to obtain the mutex. */
|
||||||
|
if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xBlockingIsSuspended = pdTRUE;
|
||||||
|
vTaskSuspend( NULL );
|
||||||
|
xBlockingIsSuspended = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We should not leave the xSemaphoreTakeRecursive() function
|
||||||
|
until the mutex was obtained. */
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The controlling and blocking tasks should be in lock step. */
|
||||||
|
if( uxControllingCycles != ( uxBlockingCycles + 1 ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep count of the number of cycles this task has performed so a
|
||||||
|
stall can be detected. */
|
||||||
|
uxBlockingCycles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRecursiveMutexPollingTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Just to remove compiler warning. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Keep attempting to obtain the mutex. We should only obtain it when
|
||||||
|
the blocking task has suspended itself, which in turn should only
|
||||||
|
happen when the controlling task is also suspended. */
|
||||||
|
if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS )
|
||||||
|
{
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xControllingTaskHandle ) == eSuspended );
|
||||||
|
configASSERT( eTaskGetState( xBlockingTaskHandle ) == eSuspended );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* Is the blocking task suspended? */
|
||||||
|
if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Keep count of the number of cycles this task has performed
|
||||||
|
so a stall can be detected. */
|
||||||
|
uxPollingCycles++;
|
||||||
|
|
||||||
|
/* We can resume the other tasks here even though they have a
|
||||||
|
higher priority than the polling task. When they execute they
|
||||||
|
will attempt to obtain the mutex but fail because the polling
|
||||||
|
task is still the mutex holder. The polling task (this task)
|
||||||
|
will then inherit the higher priority. The Blocking task will
|
||||||
|
block indefinitely when it attempts to obtain the mutex, the
|
||||||
|
Controlling task will only block for a fixed period and an
|
||||||
|
error will be latched if the polling task has not returned the
|
||||||
|
mutex by the time this fixed period has expired. */
|
||||||
|
vTaskResume( xBlockingTaskHandle );
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskResume( xControllingTaskHandle );
|
||||||
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The other two tasks should now have executed and no longer
|
||||||
|
be suspended. */
|
||||||
|
if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( INCLUDE_uxTaskPriorityGet == 1 )
|
||||||
|
{
|
||||||
|
/* Check priority inherited. */
|
||||||
|
configASSERT( uxTaskPriorityGet( NULL ) == recmuCONTROLLING_TASK_PRIORITY );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_uxTaskPriorityGet */
|
||||||
|
|
||||||
|
#if( INCLUDE_eTaskGetState == 1 )
|
||||||
|
{
|
||||||
|
configASSERT( eTaskGetState( xControllingTaskHandle ) == eBlocked );
|
||||||
|
configASSERT( eTaskGetState( xBlockingTaskHandle ) == eBlocked );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_eTaskGetState */
|
||||||
|
|
||||||
|
/* Release the mutex, disinheriting the higher priority again. */
|
||||||
|
if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( INCLUDE_uxTaskPriorityGet == 1 )
|
||||||
|
{
|
||||||
|
/* Check priority disinherited. */
|
||||||
|
configASSERT( uxTaskPriorityGet( NULL ) == recmuPOLLING_TASK_PRIORITY );
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_uxTaskPriorityGet */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreRecursiveMutexTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
static UBaseType_t uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0;
|
||||||
|
|
||||||
|
/* Is the controlling task still cycling? */
|
||||||
|
if( uxLastControllingCycles == uxControllingCycles )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxLastControllingCycles = uxControllingCycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the blocking task still cycling? */
|
||||||
|
if( uxLastBlockingCycles == uxBlockingCycles )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxLastBlockingCycles = uxBlockingCycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the polling task still cycling? */
|
||||||
|
if( uxLastPollingCycles == uxPollingCycles )
|
||||||
|
{
|
||||||
|
xErrorOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uxLastPollingCycles = uxPollingCycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xErrorOccurred == pdTRUE )
|
||||||
|
{
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,311 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates two sets of two tasks. The tasks within a set share a variable, access
|
||||||
|
* to which is guarded by a semaphore.
|
||||||
|
*
|
||||||
|
* Each task starts by attempting to obtain the semaphore. On obtaining a
|
||||||
|
* semaphore a task checks to ensure that the guarded variable has an expected
|
||||||
|
* value. It then clears the variable to zero before counting it back up to the
|
||||||
|
* expected value in increments of 1. After each increment the variable is checked
|
||||||
|
* to ensure it contains the value to which it was just set. When the starting
|
||||||
|
* value is again reached the task releases the semaphore giving the other task in
|
||||||
|
* the set a chance to do exactly the same thing. The starting value is high
|
||||||
|
* enough to ensure that a tick is likely to occur during the incrementing loop.
|
||||||
|
*
|
||||||
|
* An error is flagged if at any time during the process a shared variable is
|
||||||
|
* found to have a value other than that expected. Such an occurrence would
|
||||||
|
* suggest an error in the mutual exclusion mechanism by which access to the
|
||||||
|
* variable is restricted.
|
||||||
|
*
|
||||||
|
* The first set of two tasks poll their semaphore. The second set use blocking
|
||||||
|
* calls.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Demo app include files. */
|
||||||
|
#include "semtest.h"
|
||||||
|
|
||||||
|
/* The value to which the shared variables are counted. */
|
||||||
|
#define semtstBLOCKING_EXPECTED_VALUE ( ( uint32_t ) 0xfff )
|
||||||
|
#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( uint32_t ) 0xff )
|
||||||
|
|
||||||
|
#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
|
||||||
|
#define semtstNUM_TASKS ( 4 )
|
||||||
|
|
||||||
|
#define semtstDELAY_FACTOR ( ( TickType_t ) 10 )
|
||||||
|
|
||||||
|
/* The task function as described at the top of the file. */
|
||||||
|
static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters );
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to each task. */
|
||||||
|
typedef struct SEMAPHORE_PARAMETERS
|
||||||
|
{
|
||||||
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
volatile uint32_t *pulSharedVariable;
|
||||||
|
TickType_t xBlockTime;
|
||||||
|
} xSemaphoreParameters;
|
||||||
|
|
||||||
|
/* Variables used to check that all the tasks are still running without errors. */
|
||||||
|
static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };
|
||||||
|
static volatile short sNextCheckVariable = 0;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartSemaphoreTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;
|
||||||
|
const TickType_t xBlockTime = ( TickType_t ) 100;
|
||||||
|
|
||||||
|
/* Create the structure used to pass parameters to the first two tasks. */
|
||||||
|
pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
|
||||||
|
|
||||||
|
if( pxFirstSemaphoreParameters != NULL )
|
||||||
|
{
|
||||||
|
/* Create the semaphore used by the first two tasks. */
|
||||||
|
pxFirstSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary();
|
||||||
|
|
||||||
|
if( pxFirstSemaphoreParameters->xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
xSemaphoreGive( pxFirstSemaphoreParameters->xSemaphore );
|
||||||
|
|
||||||
|
/* Create the variable which is to be shared by the first two tasks. */
|
||||||
|
pxFirstSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) );
|
||||||
|
|
||||||
|
/* Initialise the share variable to the value the tasks expect. */
|
||||||
|
*( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE;
|
||||||
|
|
||||||
|
/* The first two tasks do not block on semaphore calls. */
|
||||||
|
pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Spawn the first two tasks. As they poll they operate at the idle priority. */
|
||||||
|
xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
|
||||||
|
xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL );
|
||||||
|
|
||||||
|
/* vQueueAddToRegistry() adds the semaphore to the registry, if one
|
||||||
|
is in use. The registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate semaphores and has no purpose if a kernel aware
|
||||||
|
debugger is not being used. The call to vQueueAddToRegistry() will
|
||||||
|
be removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||||
|
defined or is defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) pxFirstSemaphoreParameters->xSemaphore, "Counting_Sem_1" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do exactly the same to create the second set of tasks, only this time
|
||||||
|
provide a block time for the semaphore calls. */
|
||||||
|
pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );
|
||||||
|
if( pxSecondSemaphoreParameters != NULL )
|
||||||
|
{
|
||||||
|
pxSecondSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary();
|
||||||
|
|
||||||
|
if( pxSecondSemaphoreParameters->xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
xSemaphoreGive( pxSecondSemaphoreParameters->xSemaphore );
|
||||||
|
|
||||||
|
pxSecondSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) );
|
||||||
|
*( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;
|
||||||
|
pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL );
|
||||||
|
|
||||||
|
/* vQueueAddToRegistry() adds the semaphore to the registry, if one
|
||||||
|
is in use. The registry is provided as a means for kernel aware
|
||||||
|
debuggers to locate semaphores and has no purpose if a kernel aware
|
||||||
|
debugger is not being used. The call to vQueueAddToRegistry() will
|
||||||
|
be removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not
|
||||||
|
defined or is defined to be less than 1. */
|
||||||
|
vQueueAddToRegistry( ( QueueHandle_t ) pxSecondSemaphoreParameters->xSemaphore, "Counting_Sem_2" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( prvSemaphoreTest, pvParameters )
|
||||||
|
{
|
||||||
|
xSemaphoreParameters *pxParameters;
|
||||||
|
volatile uint32_t *pulSharedVariable, ulExpectedValue;
|
||||||
|
uint32_t ulCounter;
|
||||||
|
short sError = pdFALSE, sCheckVariableToUse;
|
||||||
|
|
||||||
|
/* See which check variable to use. sNextCheckVariable is not semaphore
|
||||||
|
protected! */
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
sCheckVariableToUse = sNextCheckVariable;
|
||||||
|
sNextCheckVariable++;
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
|
||||||
|
/* A structure is passed in as the parameter. This contains the shared
|
||||||
|
variable being guarded. */
|
||||||
|
pxParameters = ( xSemaphoreParameters * ) pvParameters;
|
||||||
|
pulSharedVariable = pxParameters->pulSharedVariable;
|
||||||
|
|
||||||
|
/* If we are blocking we use a much higher count to ensure loads of context
|
||||||
|
switches occur during the count. */
|
||||||
|
if( pxParameters->xBlockTime > ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Try to obtain the semaphore. */
|
||||||
|
if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )
|
||||||
|
{
|
||||||
|
/* We have the semaphore and so expect any other tasks using the
|
||||||
|
shared variable to have left it in the state we expect to find
|
||||||
|
it. */
|
||||||
|
if( *pulSharedVariable != ulExpectedValue )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the variable, then count it back up to the expected value
|
||||||
|
before releasing the semaphore. Would expect a context switch or
|
||||||
|
two during this time. */
|
||||||
|
for( ulCounter = ( uint32_t ) 0; ulCounter <= ulExpectedValue; ulCounter++ )
|
||||||
|
{
|
||||||
|
*pulSharedVariable = ulCounter;
|
||||||
|
if( *pulSharedVariable != ulCounter )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the semaphore, and if no errors have occurred increment the check
|
||||||
|
variable. */
|
||||||
|
if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
if( sCheckVariableToUse < semtstNUM_TASKS )
|
||||||
|
{
|
||||||
|
( sCheckVariables[ sCheckVariableToUse ] )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have a block time then we are running at a priority higher
|
||||||
|
than the idle priority. This task takes a long time to complete
|
||||||
|
a cycle (deliberately so to test the guarding) so will be starving
|
||||||
|
out lower priority tasks. Block for some time to allow give lower
|
||||||
|
priority tasks some processor time. */
|
||||||
|
vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( pxParameters->xBlockTime == ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* We have not got the semaphore yet, so no point using the
|
||||||
|
processor. We are not blocking when attempting to obtain the
|
||||||
|
semaphore. */
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreSemaphoreTasksStillRunning( void )
|
||||||
|
{
|
||||||
|
static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };
|
||||||
|
BaseType_t xTask, xReturn = pdTRUE;
|
||||||
|
|
||||||
|
for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ )
|
||||||
|
{
|
||||||
|
if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,369 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates eight tasks, each of which loops continuously performing a floating
|
||||||
|
* point calculation - using single precision variables.
|
||||||
|
*
|
||||||
|
* All the tasks run at the idle priority and never block or yield. This causes
|
||||||
|
* all eight tasks to time slice with the idle task. Running at the idle priority
|
||||||
|
* means that these tasks will get pre-empted any time another task is ready to run
|
||||||
|
* or a time slice occurs. More often than not the pre-emption will occur mid
|
||||||
|
* calculation, creating a good test of the schedulers context switch mechanism - a
|
||||||
|
* calculation producing an unexpected result could be a symptom of a corruption in
|
||||||
|
* the context of a task.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/* Scheduler include files. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
/* Demo program include files. */
|
||||||
|
#include "flop.h"
|
||||||
|
|
||||||
|
#define mathSTACK_SIZE configMINIMAL_STACK_SIZE
|
||||||
|
#define mathNUMBER_OF_TASKS ( 8 )
|
||||||
|
|
||||||
|
/* Four tasks, each of which performs a different floating point calculation.
|
||||||
|
Each of the four is created twice. */
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );
|
||||||
|
static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );
|
||||||
|
|
||||||
|
/* These variables are used to check that all the tasks are still running. If a
|
||||||
|
task gets a calculation wrong it will
|
||||||
|
stop incrementing its check variable. */
|
||||||
|
static volatile uint16_t usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 };
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartMathTasks( UBaseType_t uxPriority )
|
||||||
|
{
|
||||||
|
xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
|
||||||
|
xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )
|
||||||
|
{
|
||||||
|
volatile float f1, f2, f3, f4;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
volatile float fAnswer;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
f1 = 123.4567F;
|
||||||
|
f2 = 2345.6789F;
|
||||||
|
f3 = -918.222F;
|
||||||
|
|
||||||
|
fAnswer = ( f1 + f2 ) * f3;
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
f1 = 123.4567F;
|
||||||
|
f2 = 2345.6789F;
|
||||||
|
f3 = -918.222F;
|
||||||
|
|
||||||
|
f4 = ( f1 + f2 ) * f3;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( fabs( f4 - fAnswer ) > 0.001F )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )
|
||||||
|
{
|
||||||
|
volatile float f1, f2, f3, f4;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
volatile float fAnswer;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
f1 = -389.38F;
|
||||||
|
f2 = 32498.2F;
|
||||||
|
f3 = -2.0001F;
|
||||||
|
|
||||||
|
fAnswer = ( f1 / f2 ) * f3;
|
||||||
|
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
/* Keep performing a calculation and checking the result against a constant. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
f1 = -389.38F;
|
||||||
|
f2 = 32498.2F;
|
||||||
|
f3 = -2.0001F;
|
||||||
|
|
||||||
|
f4 = ( f1 / f2 ) * f3;
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the calculation does not match the expected constant, stop the
|
||||||
|
increment of the check variable. */
|
||||||
|
if( fabs( f4 - fAnswer ) > 0.001F )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know
|
||||||
|
this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )
|
||||||
|
{
|
||||||
|
volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
const size_t xArraySize = 10;
|
||||||
|
size_t xPosition;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) );
|
||||||
|
|
||||||
|
/* Keep filling an array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
fTotal1 = 0.0F;
|
||||||
|
fTotal2 = 0.0F;
|
||||||
|
fPosition = 0.0F;
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
pfArray[ xPosition ] = fPosition + 5.5F;
|
||||||
|
fTotal1 += fPosition + 5.5F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
fTotal2 += pfArray[ xPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
fDifference = fTotal1 - fTotal2;
|
||||||
|
if( fabs( fDifference ) > 0.001F )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )
|
||||||
|
{
|
||||||
|
volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition;
|
||||||
|
volatile uint16_t *pusTaskCheckVariable;
|
||||||
|
const size_t xArraySize = 10;
|
||||||
|
size_t xPosition;
|
||||||
|
short sError = pdFALSE;
|
||||||
|
|
||||||
|
/* The variable this task increments to show it is still running is passed in
|
||||||
|
as the parameter. */
|
||||||
|
pusTaskCheckVariable = ( uint16_t * ) pvParameters;
|
||||||
|
|
||||||
|
pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) );
|
||||||
|
|
||||||
|
/* Keep filling an array, keeping a running total of the values placed in the
|
||||||
|
array. Then run through the array adding up all the values. If the two totals
|
||||||
|
do not match, stop the check variable from incrementing. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
fTotal1 = 0.0F;
|
||||||
|
fTotal2 = 0.0F;
|
||||||
|
fPosition = 0.0F;
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
pfArray[ xPosition ] = fPosition * 12.123F;
|
||||||
|
fTotal1 += fPosition * 12.123F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( xPosition = 0; xPosition < xArraySize; xPosition++ )
|
||||||
|
{
|
||||||
|
fTotal2 += pfArray[ xPosition ];
|
||||||
|
}
|
||||||
|
|
||||||
|
fDifference = fTotal1 - fTotal2;
|
||||||
|
if( fabs( fDifference ) > 0.001F )
|
||||||
|
{
|
||||||
|
sError = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if configUSE_PREEMPTION == 0
|
||||||
|
taskYIELD();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( sError == pdFALSE )
|
||||||
|
{
|
||||||
|
/* If the calculation has always been correct, increment the check
|
||||||
|
variable so we know this task is still running okay. */
|
||||||
|
( *pusTaskCheckVariable )++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is called to check that all the created tasks are still running. */
|
||||||
|
BaseType_t xAreMathsTaskStillRunning( void )
|
||||||
|
{
|
||||||
|
/* Keep a history of the check variables so we know if they have been incremented
|
||||||
|
since the last call. */
|
||||||
|
static uint16_t usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 };
|
||||||
|
BaseType_t xReturn = pdTRUE, xTask;
|
||||||
|
|
||||||
|
/* Check the maths tasks are still running by ensuring their check variables
|
||||||
|
are still incrementing. */
|
||||||
|
for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )
|
||||||
|
{
|
||||||
|
if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
|
||||||
|
{
|
||||||
|
/* The check has not incremented so an error exists. */
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
Contains the files that are not specific to any one demo, but are instead used
|
||||||
|
by all the demo applications.
|
||||||
|
|
||||||
|
Most of the directories are now obsolete, and only maintained for backward
|
||||||
|
compatibility. The directories in active use are:
|
||||||
|
|
||||||
|
+ Minimal - this contains the implementation of what are referred to as the
|
||||||
|
"Standard Demo Tasks". These are used by all the demo applications. Their only
|
||||||
|
purpose is to demonstrate the FreeRTOS API and test the FreeRTOS features. The
|
||||||
|
directory is called 'Minimal' as it contains a minimal implementation of files
|
||||||
|
contained in the 'Full' directory - but the 'Full' directory is no longer used.
|
||||||
|
|
||||||
|
+ include - contains header files for the C source files located in the Minimal
|
||||||
|
directory.
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ABORT_DELAY_H
|
||||||
|
#define ABORT_DELAY_H
|
||||||
|
|
||||||
|
void vCreateAbortDelayTasks( void );
|
||||||
|
BaseType_t xAreAbortDelayTestTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLOCK_Q_H
|
||||||
|
#define BLOCK_Q_H
|
||||||
|
|
||||||
|
void vStartBlockingQueueTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xAreBlockingQueuesStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains fairly comprehensive checks on the behaviour of event
|
||||||
|
* groups. It is not intended to be a user friendly demonstration of the event
|
||||||
|
* groups API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EVENT_GROUPS_DEMO_H
|
||||||
|
#define EVENT_GROUPS_DEMO_H
|
||||||
|
|
||||||
|
void vStartEventGroupTasks( void );
|
||||||
|
BaseType_t xAreEventGroupTasksStillRunning( void );
|
||||||
|
void vPeriodicEventGroupsProcessing( void );
|
||||||
|
|
||||||
|
#endif /* EVENT_GROUPS_DEMO_H */
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GEN_Q_TEST_H
|
||||||
|
#define GEN_Q_TEST_H
|
||||||
|
|
||||||
|
void vStartGenericQueueTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xAreGenericQueueTasksStillRunning( void );
|
||||||
|
void vMutexISRInteractionTest( void );
|
||||||
|
|
||||||
|
#endif /* GEN_Q_TEST_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUEUE_ACCESS_TEST
|
||||||
|
#define QUEUE_ACCESS_TEST
|
||||||
|
|
||||||
|
void vStartInterruptQueueTasks( void );
|
||||||
|
BaseType_t xAreIntQueueTasksStillRunning( void );
|
||||||
|
BaseType_t xFirstTimerHandler( void );
|
||||||
|
BaseType_t xSecondTimerHandler( void );
|
||||||
|
|
||||||
|
#endif /* QUEUE_ACCESS_TEST */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INT_SEM_TEST_H
|
||||||
|
#define INT_SEM_TEST_H
|
||||||
|
|
||||||
|
void vStartInterruptSemaphoreTasks( void );
|
||||||
|
BaseType_t xAreInterruptSemaphoreTasksStillRunning( void );
|
||||||
|
void vInterruptSemaphorePeriodicTest( void );
|
||||||
|
|
||||||
|
#endif /* INT_SEM_TEST_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef POLLED_Q_H
|
||||||
|
#define POLLED_Q_H
|
||||||
|
|
||||||
|
void vStartPolledQueueTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xArePollingQueuesStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Q_PEEK_TEST_H
|
||||||
|
#define Q_PEEK_TEST_H
|
||||||
|
|
||||||
|
void vStartQueuePeekTasks( void );
|
||||||
|
BaseType_t xAreQueuePeekTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif /* Q_PEEK_TEST_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUEUE_OVERWRITE_H
|
||||||
|
#define QUEUE_OVERWRITE_H
|
||||||
|
|
||||||
|
void vStartQueueOverwriteTask( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xIsQueueOverwriteTaskStillRunning( void );
|
||||||
|
void vQueueOverwritePeriodicISRDemo( void );
|
||||||
|
|
||||||
|
#endif /* QUEUE_OVERWRITE_H */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUEUE_WAIT_MULTIPLE_H
|
||||||
|
#define QUEUE_WAIT_MULTIPLE_H
|
||||||
|
|
||||||
|
void vStartQueueSetTasks( void );
|
||||||
|
BaseType_t xAreQueueSetTasksStillRunning( void );
|
||||||
|
void vQueueSetAccessQueueSetFromISR( void );
|
||||||
|
|
||||||
|
#endif /* QUEUE_WAIT_MULTIPLE_H */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUEUE_SET_POLLING_H
|
||||||
|
#define QUEUE_SET_POLLING_H
|
||||||
|
|
||||||
|
void vStartQueueSetPollingTask( void );
|
||||||
|
BaseType_t xAreQueueSetPollTasksStillRunning( void );
|
||||||
|
void vQueueSetPollingInterruptAccess( void );
|
||||||
|
|
||||||
|
#endif /* QUEUE_SET_POLLING_H */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STATIC_ALLOCATION_H
|
||||||
|
#define STATIC_ALLOCATION_H
|
||||||
|
|
||||||
|
void vStartStaticallyAllocatedTasks( void );
|
||||||
|
BaseType_t xAreStaticAllocationTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif /* STATIC_ALLOCATION_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TASK_NOTIFY_H
|
||||||
|
#define TASK_NOTIFY_H
|
||||||
|
|
||||||
|
void vStartTaskNotifyTask( void );
|
||||||
|
BaseType_t xAreTaskNotificationTasksStillRunning( void );
|
||||||
|
void xNotifyTaskFromISR( void );
|
||||||
|
|
||||||
|
#endif /* TASK_NOTIFY_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIMER_DEMO_H
|
||||||
|
#define TIMER_DEMO_H
|
||||||
|
|
||||||
|
void vStartTimerDemoTask( TickType_t xBaseFrequencyIn );
|
||||||
|
BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency );
|
||||||
|
void vTimerPeriodicISRTests( void );
|
||||||
|
|
||||||
|
#endif /* TIMER_DEMO_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLOCK_TIME_TEST_H
|
||||||
|
#define BLOCK_TIME_TEST_H
|
||||||
|
|
||||||
|
void vCreateBlockTimeTasks( void );
|
||||||
|
BaseType_t xAreBlockTimeTestTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMTEST_H
|
||||||
|
#define COMTEST_H
|
||||||
|
|
||||||
|
void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED );
|
||||||
|
void vStartComTestTasks( UBaseType_t uxPriority, eCOMPort ePort, eBaud eBaudRate );
|
||||||
|
BaseType_t xAreComTestTasksStillRunning( void );
|
||||||
|
void vComTestUnsuspendTask( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMTEST_H
|
||||||
|
#define COMTEST_H
|
||||||
|
|
||||||
|
void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED );
|
||||||
|
BaseType_t xAreComTestTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMTEST_STRINGS_H
|
||||||
|
#define COMTEST_STRINGS_H
|
||||||
|
|
||||||
|
void vStartComTestStringsTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED );
|
||||||
|
BaseType_t xAreComTestTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COUNT_SEMAPHORE_TEST_H
|
||||||
|
#define COUNT_SEMAPHORE_TEST_H
|
||||||
|
|
||||||
|
void vStartCountingSemaphoreTasks( void );
|
||||||
|
BaseType_t xAreCountingSemaphoreTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRFLASH_LED_H
|
||||||
|
#define CRFLASH_LED_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the co-routines used to flash the LED's at different rates.
|
||||||
|
*
|
||||||
|
* @param uxPriority The number of 'fixed delay' co-routines to create. This
|
||||||
|
* also effects the number of LED's that will be utilised. For example,
|
||||||
|
* passing in 3 will cause LED's 0 to 2 to be utilised.
|
||||||
|
*/
|
||||||
|
void vStartFlashCoRoutines( UBaseType_t uxPriority );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return pdPASS or pdFAIL depending on whether an error has been detected
|
||||||
|
* or not.
|
||||||
|
*/
|
||||||
|
BaseType_t xAreFlashCoRoutinesStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRHOOK_H
|
||||||
|
#define CRHOOK_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the co-routines used to communicate wit the tick hook.
|
||||||
|
*/
|
||||||
|
void vStartHookCoRoutines( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return pdPASS or pdFAIL depending on whether an error has been detected
|
||||||
|
* or not.
|
||||||
|
*/
|
||||||
|
BaseType_t xAreHookCoRoutinesStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SUICIDE_TASK_H
|
||||||
|
#define SUICIDE_TASK_H
|
||||||
|
|
||||||
|
void vCreateSuicidalTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xIsCreateTaskStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DYNAMIC_MANIPULATION_H
|
||||||
|
#define DYNAMIC_MANIPULATION_H
|
||||||
|
|
||||||
|
void vStartDynamicPriorityTasks( void );
|
||||||
|
BaseType_t xAreDynamicPriorityTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FILE_IO_H
|
||||||
|
#define FILE_IO_H
|
||||||
|
|
||||||
|
void vDisplayMessage( const char * const pcMessageToPrint );
|
||||||
|
void vWriteMessageToDisk( const char * const pcMessage );
|
||||||
|
void vWriteBufferToDisk( const char * const pcBuffer, uint32_t ulBufferLength );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLASH_LED_H
|
||||||
|
#define FLASH_LED_H
|
||||||
|
|
||||||
|
void vStartLEDFlashTasks( UBaseType_t uxPriority );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLASH_TIMER_H
|
||||||
|
#define FLASH_TIMER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates the LED flashing timers. xNumberOfLEDs specifies how many timers to
|
||||||
|
* create, with each timer toggling a different LED. The first LED to be
|
||||||
|
* toggled is LED 0, with subsequent LEDs following on in numerical order. Each
|
||||||
|
* timer uses the exact same callback function, with the timer ID being used
|
||||||
|
* within the callback function to determine which timer has actually expired
|
||||||
|
* (and therefore which LED to toggle).
|
||||||
|
*/
|
||||||
|
void vStartLEDFlashTimers( UBaseType_t uxNumberOfLEDs );
|
||||||
|
|
||||||
|
#endif /* FLASH_TIMER_H */
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLOP_TASKS_H
|
||||||
|
#define FLOP_TASKS_H
|
||||||
|
|
||||||
|
void vStartMathTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xAreMathsTaskStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INTEGER_TASKS_H
|
||||||
|
#define INTEGER_TASKS_H
|
||||||
|
|
||||||
|
void vStartIntegerMathTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xAreIntegerMathsTaskStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EVENTS_TEST_H
|
||||||
|
#define EVENTS_TEST_H
|
||||||
|
|
||||||
|
void vStartMultiEventTasks( void );
|
||||||
|
BaseType_t xAreMultiEventTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PARTEST_H
|
||||||
|
#define PARTEST_H
|
||||||
|
|
||||||
|
#define partstDEFAULT_PORT_ADDRESS ( ( uint16_t ) 0x378 )
|
||||||
|
|
||||||
|
void vParTestInitialise( void );
|
||||||
|
void vParTestSetLED( UBaseType_t uxLED, BaseType_t xValue );
|
||||||
|
void vParTestToggleLED( UBaseType_t uxLED );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PRINT_H
|
||||||
|
#define PRINT_H
|
||||||
|
|
||||||
|
void vPrintInitialise( void );
|
||||||
|
void vPrintDisplayMessage( const char * const * pcMessageToSend );
|
||||||
|
const char *pcPrintGetNextMessage( TickType_t xPrintRate );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECURSIVE_MUTEX_TEST_H
|
||||||
|
#define RECURSIVE_MUTEX_TEST_H
|
||||||
|
|
||||||
|
void vStartRecursiveMutexTasks( void );
|
||||||
|
BaseType_t xAreRecursiveMutexTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMAPHORE_TEST_H
|
||||||
|
#define SEMAPHORE_TEST_H
|
||||||
|
|
||||||
|
void vStartSemaphoreTasks( UBaseType_t uxPriority );
|
||||||
|
BaseType_t xAreSemaphoreTasksStillRunning( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SERIAL_COMMS_H
|
||||||
|
#define SERIAL_COMMS_H
|
||||||
|
|
||||||
|
typedef void * xComPortHandle;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serCOM1,
|
||||||
|
serCOM2,
|
||||||
|
serCOM3,
|
||||||
|
serCOM4,
|
||||||
|
serCOM5,
|
||||||
|
serCOM6,
|
||||||
|
serCOM7,
|
||||||
|
serCOM8
|
||||||
|
} eCOMPort;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serNO_PARITY,
|
||||||
|
serODD_PARITY,
|
||||||
|
serEVEN_PARITY,
|
||||||
|
serMARK_PARITY,
|
||||||
|
serSPACE_PARITY
|
||||||
|
} eParity;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serSTOP_1,
|
||||||
|
serSTOP_2
|
||||||
|
} eStopBits;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
serBITS_5,
|
||||||
|
serBITS_6,
|
||||||
|
serBITS_7,
|
||||||
|
serBITS_8
|
||||||
|
} eDataBits;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ser50,
|
||||||
|
ser75,
|
||||||
|
ser110,
|
||||||
|
ser134,
|
||||||
|
ser150,
|
||||||
|
ser200,
|
||||||
|
ser300,
|
||||||
|
ser600,
|
||||||
|
ser1200,
|
||||||
|
ser1800,
|
||||||
|
ser2400,
|
||||||
|
ser4800,
|
||||||
|
ser9600,
|
||||||
|
ser19200,
|
||||||
|
ser38400,
|
||||||
|
ser57600,
|
||||||
|
ser115200
|
||||||
|
} eBaud;
|
||||||
|
|
||||||
|
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength );
|
||||||
|
xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength );
|
||||||
|
void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength );
|
||||||
|
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime );
|
||||||
|
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime );
|
||||||
|
portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort );
|
||||||
|
void vSerialClose( xComPortHandle xPort );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
The FreeRTOS open source license covers the FreeRTOS source files,
|
||||||
|
which are located in the /FreeRTOS/Source directory of the official FreeRTOS
|
||||||
|
download. It also covers most of the source files in the demo application
|
||||||
|
projects, which are located in the /FreeRTOS/Demo directory of the official
|
||||||
|
FreeRTOS download. The demo projects may also include third party software that
|
||||||
|
is not part of FreeRTOS and is licensed separately to FreeRTOS. Examples of
|
||||||
|
third party software includes header files provided by chip or tools vendors,
|
||||||
|
linker scripts, peripheral drivers, etc. All the software in subdirectories of
|
||||||
|
the /FreeRTOS directory is either open source or distributed with permission,
|
||||||
|
and is free for use. For the avoidance of doubt, refer to the comments at the
|
||||||
|
top of each source file.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NOTE: The modification to the GPL is included to allow you to distribute a
|
||||||
|
combined work that includes FreeRTOS without being obliged to provide the source
|
||||||
|
code for proprietary components.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Applying to FreeRTOS V8.2.3 up to the latest version, the FreeRTOS GPL Exception
|
||||||
|
Text follows:
|
||||||
|
|
||||||
|
Any FreeRTOS *source code*, whether modified or in it's original release form,
|
||||||
|
or whether in whole or in part, can only be distributed by you under the terms
|
||||||
|
of the GNU General Public License plus this exception. An independent module is
|
||||||
|
a module which is not derived from or based on FreeRTOS.
|
||||||
|
|
||||||
|
Clause 1:
|
||||||
|
|
||||||
|
Linking FreeRTOS with other modules is making a combined work based on FreeRTOS.
|
||||||
|
Thus, the terms and conditions of the GNU General Public License V2 cover the
|
||||||
|
whole combination.
|
||||||
|
|
||||||
|
As a special exception, the copyright holders of FreeRTOS give you permission to
|
||||||
|
link FreeRTOS with independent modules to produce a statically linked
|
||||||
|
executable, regardless of the license terms of these independent modules, and to
|
||||||
|
copy and distribute the resulting executable under terms of your choice,
|
||||||
|
provided that you also meet, for each linked independent module, the terms and
|
||||||
|
conditions of the license of that module. An independent module is a module
|
||||||
|
which is not derived from or based on FreeRTOS.
|
||||||
|
|
||||||
|
Clause 2:
|
||||||
|
|
||||||
|
FreeRTOS may not be used for any competitive or comparative purpose, including
|
||||||
|
the publication of any form of run time or compile time metric, without the
|
||||||
|
express permission of Real Time Engineers Ltd. (this is the norm within the
|
||||||
|
industry and is intended to ensure information accuracy).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The standard GPL V2 text:
|
||||||
|
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License** as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
|
|
|
@ -0,0 +1,395 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "croutine.h"
|
||||||
|
|
||||||
|
/* Remove the whole file is co-routines are not being used. */
|
||||||
|
#if( configUSE_CO_ROUTINES != 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
|
* than file scope.
|
||||||
|
*/
|
||||||
|
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||||
|
#define static
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
|
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||||
|
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||||
|
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
|
static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
||||||
|
static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
|
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
||||||
|
|
||||||
|
/* Other file private variables. --------------------------------*/
|
||||||
|
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||||
|
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||||
|
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
|
/* The initial state of the co-routine when it is created. */
|
||||||
|
#define corINITIAL_STATE ( 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||||
|
* for the priority. It is inserted at the end of the list.
|
||||||
|
*
|
||||||
|
* This macro accesses the co-routine ready lists and therefore must not be
|
||||||
|
* used from within an ISR.
|
||||||
|
*/
|
||||||
|
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
||||||
|
{ \
|
||||||
|
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
||||||
|
{ \
|
||||||
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
|
} \
|
||||||
|
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
|
* automatically upon the creation of the first co-routine.
|
||||||
|
*/
|
||||||
|
static void prvInitialiseCoRoutineLists( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||||
|
* the ready lists (there is no mutual exclusion). Instead they are placed in
|
||||||
|
* in the pending ready list in order that they can later be moved to the ready
|
||||||
|
* list by the co-routine scheduler.
|
||||||
|
*/
|
||||||
|
static void prvCheckPendingReadyList( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro that looks at the list of co-routines that are currently delayed to
|
||||||
|
* see if any require waking.
|
||||||
|
*
|
||||||
|
* Co-routines are stored in the queue in the order of their wake time -
|
||||||
|
* meaning once one co-routine has been found whose timer has not expired
|
||||||
|
* we need not look any further down the list.
|
||||||
|
*/
|
||||||
|
static void prvCheckDelayedList( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
CRCB_t *pxCoRoutine;
|
||||||
|
|
||||||
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
|
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||||
|
if( pxCoRoutine )
|
||||||
|
{
|
||||||
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
|
be created and the co-routine data structures need initialising. */
|
||||||
|
if( pxCurrentCoRoutine == NULL )
|
||||||
|
{
|
||||||
|
pxCurrentCoRoutine = pxCoRoutine;
|
||||||
|
prvInitialiseCoRoutineLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the priority is within limits. */
|
||||||
|
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
|
||||||
|
{
|
||||||
|
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill out the co-routine control block from the function parameters. */
|
||||||
|
pxCoRoutine->uxState = corINITIAL_STATE;
|
||||||
|
pxCoRoutine->uxPriority = uxPriority;
|
||||||
|
pxCoRoutine->uxIndex = uxIndex;
|
||||||
|
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
|
||||||
|
|
||||||
|
/* Initialise all the other co-routine control block parameters. */
|
||||||
|
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
||||||
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
|
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||||
|
This is so we can get back to the containing CRCB from a generic item
|
||||||
|
in a list. */
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
|
/* Event lists are always in priority order. */
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||||
|
|
||||||
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
|
list at the correct priority. */
|
||||||
|
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||||
|
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
||||||
|
{
|
||||||
|
TickType_t xTimeToWake;
|
||||||
|
|
||||||
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
|
not a problem. */
|
||||||
|
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||||
|
|
||||||
|
/* We must remove ourselves from the ready list before adding
|
||||||
|
ourselves to the blocked list as the same list item is used for
|
||||||
|
both lists. */
|
||||||
|
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* The list item will be inserted in wake time order. */
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
||||||
|
|
||||||
|
if( xTimeToWake < xCoRoutineTickCount )
|
||||||
|
{
|
||||||
|
/* Wake time has overflowed. Place this item in the
|
||||||
|
overflow list. */
|
||||||
|
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The wake time has not overflowed, so we can use the
|
||||||
|
current block list. */
|
||||||
|
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pxEventList )
|
||||||
|
{
|
||||||
|
/* Also add the co-routine to an event list. If this is done then the
|
||||||
|
function must be called with interrupts disabled. */
|
||||||
|
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckPendingReadyList( void )
|
||||||
|
{
|
||||||
|
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||||
|
are co-routines that have been readied by an ISR. The ISR cannot access
|
||||||
|
the ready lists itself. */
|
||||||
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
CRCB_t *pxUnblockedCRCB;
|
||||||
|
|
||||||
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
||||||
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||||
|
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckDelayedList( void )
|
||||||
|
{
|
||||||
|
CRCB_t *pxCRCB;
|
||||||
|
|
||||||
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
|
while( xPassedTicks )
|
||||||
|
{
|
||||||
|
xCoRoutineTickCount++;
|
||||||
|
xPassedTicks--;
|
||||||
|
|
||||||
|
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||||
|
if( xCoRoutineTickCount == 0 )
|
||||||
|
{
|
||||||
|
List_t * pxTemp;
|
||||||
|
|
||||||
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
|
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
|
pxTemp = pxDelayedCoRoutineList;
|
||||||
|
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||||
|
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if this tick has made a timeout expire. */
|
||||||
|
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||||
|
|
||||||
|
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||||
|
{
|
||||||
|
/* Timeout not yet expired. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* The event could have occurred just before this critical
|
||||||
|
section. If this is the case then the generic list item will
|
||||||
|
have been moved to the pending ready list and the following
|
||||||
|
line is still valid. Also the pvContainer parameter will have
|
||||||
|
been set to NULL so the following lines are also valid. */
|
||||||
|
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* Is the co-routine waiting on an event also? */
|
||||||
|
if( pxCRCB->xEventListItem.pvContainer )
|
||||||
|
{
|
||||||
|
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
prvAddCoRoutineToReadyQueue( pxCRCB );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCoRoutineSchedule( void )
|
||||||
|
{
|
||||||
|
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||||
|
prvCheckPendingReadyList();
|
||||||
|
|
||||||
|
/* See if any delayed co-routines have timed out. */
|
||||||
|
prvCheckDelayedList();
|
||||||
|
|
||||||
|
/* Find the highest priority queue that contains ready co-routines. */
|
||||||
|
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
|
||||||
|
{
|
||||||
|
if( uxTopCoRoutineReadyPriority == 0 )
|
||||||
|
{
|
||||||
|
/* No more co-routines to check. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--uxTopCoRoutineReadyPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||||
|
of the same priority get an equal share of the processor time. */
|
||||||
|
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||||
|
|
||||||
|
/* Call the co-routine. */
|
||||||
|
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
|
{
|
||||||
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
|
{
|
||||||
|
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
|
||||||
|
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
|
||||||
|
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
|
pxOverflowDelayedCoRoutineList using list2. */
|
||||||
|
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||||
|
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
|
||||||
|
{
|
||||||
|
CRCB_t *pxUnblockedCRCB;
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
/* This function is called from within an interrupt. It can only access
|
||||||
|
event lists and the pending ready list. This function assumes that a
|
||||||
|
check has already been made to ensure pxEventList is not empty. */
|
||||||
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
|
||||||
|
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_CO_ROUTINES == 0 */
|
||||||
|
|
|
@ -0,0 +1,752 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||||
|
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||||
|
>>! obliged to provide the source code for proprietary components !<<
|
||||||
|
>>! outside of the FreeRTOS kernel. !<<
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available on the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that is more than just the market leader, it *
|
||||||
|
* is the industry's de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly while simultaneously helping *
|
||||||
|
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||||
|
* tutorial book, reference manual, or both: *
|
||||||
|
* http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||||
|
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||||
|
defined configASSERT()?
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||||
|
embedded software for free we request you assist our global community by
|
||||||
|
participating in the support forum.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||||
|
be as productive as possible as early as possible. Now you can receive
|
||||||
|
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||||
|
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||||
|
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||||
|
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and commercial middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
|
all the API functions to use the MPU wrappers. That should only be done when
|
||||||
|
task.h is included from an application file. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "event_groups.h"
|
||||||
|
|
||||||
|
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
|
||||||
|
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
|
||||||
|
header files above, but not in this file, in order to generate the correct
|
||||||
|
privileged Vs unprivileged linkage and placement. */
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
||||||
|
|
||||||
|
/* The following bit fields convey control information in a task's event list
|
||||||
|
item value. It is important they don't clash with the
|
||||||
|
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
||||||
|
#if configUSE_16_BIT_TICKS == 1
|
||||||
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
||||||
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
||||||
|
#define eventWAIT_FOR_ALL_BITS 0x0400U
|
||||||
|
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
|
||||||
|
#else
|
||||||
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
|
||||||
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
|
||||||
|
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
|
||||||
|
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct xEventGroupDefinition
|
||||||
|
{
|
||||||
|
EventBits_t uxEventBits;
|
||||||
|
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||||
|
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
UBaseType_t uxEventGroupNumber;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
|
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||||
|
#endif
|
||||||
|
} EventGroup_t;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test the bits set in uxCurrentEventBits to see if the wait condition is met.
|
||||||
|
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||||
|
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
||||||
|
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
||||||
|
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||||
|
* in uxCurrentEventBits.
|
||||||
|
*/
|
||||||
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits;
|
||||||
|
|
||||||
|
/* A StaticEventGroup_t object must be provided. */
|
||||||
|
configASSERT( pxEventGroupBuffer );
|
||||||
|
|
||||||
|
/* The user has provided a statically allocated event group - use it. */
|
||||||
|
pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
|
||||||
|
|
||||||
|
if( pxEventBits != NULL )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits = 0;
|
||||||
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Both static and dynamic allocation can be used, so note that
|
||||||
|
this event group was created statically in case the event group
|
||||||
|
is later deleted. */
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdTRUE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( EventGroupHandle_t ) pxEventBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||||
|
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits;
|
||||||
|
|
||||||
|
/* Allocate the event group. */
|
||||||
|
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
|
||||||
|
|
||||||
|
if( pxEventBits != NULL )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits = 0;
|
||||||
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
|
||||||
|
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Both static and dynamic allocation can be used, so note this
|
||||||
|
event group was allocated statically in case the event group is
|
||||||
|
later deleted. */
|
||||||
|
pxEventBits->ucStaticallyAllocated = pdFALSE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( EventGroupHandle_t ) pxEventBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
EventBits_t uxOriginalBitValue, uxReturn;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
BaseType_t xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
{
|
||||||
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
uxOriginalBitValue = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
|
if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
/* All the rendezvous bits are now set - no need to block. */
|
||||||
|
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||||
|
|
||||||
|
/* Rendezvous always clear the bits. They will have been cleared
|
||||||
|
already unless this is the only task in the rendezvous. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
|
||||||
|
xTicksToWait = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||||
|
|
||||||
|
/* Store the bits that the calling task is waiting for in the
|
||||||
|
task's event list item so the kernel knows when a match is
|
||||||
|
found. Then enter the blocked state. */
|
||||||
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||||
|
|
||||||
|
/* This assignment is obsolete as uxReturn will get set after
|
||||||
|
the task unblocks, but some compilers mistakenly generate a
|
||||||
|
warning about uxReturn being returned without being set if the
|
||||||
|
assignment is omitted. */
|
||||||
|
uxReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The rendezvous bits were not set, but no block time was
|
||||||
|
specified - just return the current event bit value. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
if( xAlreadyYielded == pdFALSE )
|
||||||
|
{
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
|
point either the required bits were set or the block time expired. If
|
||||||
|
the required bits were set they will have been stored in the task's
|
||||||
|
event list item, and they should now be retrieved then cleared. */
|
||||||
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The task timed out, just return the current event bit value. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Although the task got here because it timed out before the
|
||||||
|
bits it was waiting for were set, it is possible that since it
|
||||||
|
unblocked another task has set the bits. If this is the case
|
||||||
|
then it needs to clear the bits before exiting. */
|
||||||
|
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task unblocked because the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Control bits might be set as the task had blocked should not be
|
||||||
|
returned. */
|
||||||
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn, uxControlBits = 0;
|
||||||
|
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||||
|
itself, and that at least one bit is being requested. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
{
|
||||||
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Check to see if the wait condition is already met or not. */
|
||||||
|
xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
|
||||||
|
|
||||||
|
if( xWaitConditionMet != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The wait condition has already been met so there is no need to
|
||||||
|
block. */
|
||||||
|
uxReturn = uxCurrentEventBits;
|
||||||
|
xTicksToWait = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Clear the wait bits if requested to do so. */
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The wait condition has not been met, but no block time was
|
||||||
|
specified, so just return the current value. */
|
||||||
|
uxReturn = uxCurrentEventBits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task is going to block to wait for its required bits to be
|
||||||
|
set. uxControlBits are used to remember the specified behaviour of
|
||||||
|
this call to xEventGroupWaitBits() - for use when the event bits
|
||||||
|
unblock the task. */
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWaitForAllBits != pdFALSE )
|
||||||
|
{
|
||||||
|
uxControlBits |= eventWAIT_FOR_ALL_BITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the bits that the calling task is waiting for in the
|
||||||
|
task's event list item so the kernel knows when a match is
|
||||||
|
found. Then enter the blocked state. */
|
||||||
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||||
|
|
||||||
|
/* This is obsolete as it will get set after the task unblocks, but
|
||||||
|
some compilers mistakenly generate a warning about the variable
|
||||||
|
being returned without being set if it is not done. */
|
||||||
|
uxReturn = 0;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
if( xAlreadyYielded == pdFALSE )
|
||||||
|
{
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
|
point either the required bits were set or the block time expired. If
|
||||||
|
the required bits were set they will have been stored in the task's
|
||||||
|
event list item, and they should now be retrieved then cleared. */
|
||||||
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* The task timed out, just return the current event bit value. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* It is possible that the event bits were updated between this
|
||||||
|
task leaving the Blocked state and running again. */
|
||||||
|
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||||
|
{
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
xTimeoutOccurred = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task unblocked because the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked so control bits may have been set. */
|
||||||
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
}
|
||||||
|
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
|
/* The value returned is the event group value prior to the bits being
|
||||||
|
cleared. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Clear the bits. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
|
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||||
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
||||||
|
{
|
||||||
|
ListItem_t *pxListItem, *pxNext;
|
||||||
|
ListItem_t const *pxListEnd;
|
||||||
|
List_t *pxList;
|
||||||
|
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to set the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( xEventGroup );
|
||||||
|
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
|
pxListItem = listGET_HEAD_ENTRY( pxList );
|
||||||
|
|
||||||
|
/* Set the bits. */
|
||||||
|
pxEventBits->uxEventBits |= uxBitsToSet;
|
||||||
|
|
||||||
|
/* See if the new bit value should unblock any tasks. */
|
||||||
|
while( pxListItem != pxListEnd )
|
||||||
|
{
|
||||||
|
pxNext = listGET_NEXT( pxListItem );
|
||||||
|
uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
|
||||||
|
xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Split the bits waited for from the control bits. */
|
||||||
|
uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
|
||||||
|
if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Just looking for single bit being set. */
|
||||||
|
if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
xMatchFound = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
|
||||||
|
{
|
||||||
|
/* All bits are set. */
|
||||||
|
xMatchFound = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Need all bits to be set, but not all the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xMatchFound != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The bits match. Should the bits be cleared on exit? */
|
||||||
|
if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
uxBitsToClear |= uxBitsWaitedFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the actual event flag value in the task's event list
|
||||||
|
item before removing the task from the event list. The
|
||||||
|
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||||
|
that is was unblocked due to its required bits matching, rather
|
||||||
|
than because it timed out. */
|
||||||
|
( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||||
|
used here as the list item may have been removed from the event list
|
||||||
|
and inserted into the ready/pending reading list. */
|
||||||
|
pxListItem = pxNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||||
|
bit was set in the control word. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
return pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||||
|
|
||||||
|
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Unblock the task, returning 0 as the event list is being deleted
|
||||||
|
and cannot therefore have any bits set. */
|
||||||
|
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||||
|
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
|
||||||
|
{
|
||||||
|
/* The event group can only have been allocated dynamically - free
|
||||||
|
it again. */
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
#elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||||
|
{
|
||||||
|
/* The event group could have been allocated statically or
|
||||||
|
dynamically, so check before attempting to free the memory. */
|
||||||
|
if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
|
||||||
|
{
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For internal use only - execute a 'set bits' command that was pended from
|
||||||
|
an interrupt. */
|
||||||
|
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
||||||
|
{
|
||||||
|
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For internal use only - execute a 'clear bits' command that was pended from
|
||||||
|
an interrupt. */
|
||||||
|
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
|
||||||
|
{
|
||||||
|
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
|
||||||
|
{
|
||||||
|
BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
|
if( xWaitForAllBits == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||||
|
set. Is one already set? */
|
||||||
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
xWaitConditionMet = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||||
|
Are they set already? */
|
||||||
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
xWaitConditionMet = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xWaitConditionMet;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||||
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (configUSE_TRACE_FACILITY == 1)
|
||||||
|
|
||||||
|
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
||||||
|
{
|
||||||
|
UBaseType_t xReturn;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
|
||||||
|
if( xEventGroup == NULL )
|
||||||
|
{
|
||||||
|
xReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pxEventBits->uxEventGroupNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue