mirror of
https://github.com/drasko/open-ameba.git
synced 2025-01-12 08:15:21 +00:00
up freertos v9.0.0
This commit is contained in:
parent
abb51466bd
commit
b882fe7efb
132 changed files with 50587 additions and 2707 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}/${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/freertos_v8.1.2/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/include}""/>
|
||||
<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/soc/realtek/8195a/misc/driver}""/>
|
||||
<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}/${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/freertos_v8.1.2/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/include}""/>
|
||||
<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/soc/realtek/8195a/misc/driver}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
||||
|
@ -257,7 +257,7 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<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>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
@ -378,8 +378,8 @@
|
|||
<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/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_v8.1.2/Source/portable/GCC/ARM_CM3}""/>
|
||||
<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_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/soc/realtek/8195a/misc/driver}""/>
|
||||
<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}/${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/freertos_v8.1.2/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/include}""/>
|
||||
<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/soc/realtek/8195a/misc/driver}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/${ProjSDK}/component/common/api/network/include}""/>
|
||||
|
@ -613,8 +613,8 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<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="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="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_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>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
@ -797,7 +797,7 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<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>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -510,7 +510,7 @@ void fATWx(void *arg){
|
|||
printf("\tMAC => "MAC_FMT"\n",
|
||||
MAC_ARG(client_info.mac_list[client_number].octet));
|
||||
#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
|
||||
#if CONFIG_INIC_CMD_RSP
|
||||
if(info){
|
||||
|
|
|
@ -447,7 +447,7 @@ void start_log_service(void)
|
|||
|
||||
result = xTaskGenericCreate(
|
||||
log_service,
|
||||
( signed portCHAR * ) "log_service",
|
||||
( signed portCHAR * ) "log_srv",
|
||||
STACKSIZE,
|
||||
NULL,
|
||||
tskIDLE_PRIORITY + 5,
|
||||
|
@ -455,7 +455,7 @@ void start_log_service(void)
|
|||
stack_addr,
|
||||
NULL);
|
||||
#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
|
||||
|
||||
if(result != pdPASS) {
|
||||
|
|
|
@ -1378,13 +1378,13 @@ int wifi_show_setting(const char *ifname, rtw_wifi_setting_t *pSetting) {
|
|||
switch (pSetting->mode) {
|
||||
case RTW_MODE_AP:
|
||||
#if CONFIG_EXAMPLE_UART_ATCMD
|
||||
at_printf("AP,");
|
||||
at_printf("AP:");
|
||||
#endif
|
||||
printf("\tMODE => AP\n");
|
||||
break;
|
||||
case RTW_MODE_STA:
|
||||
#if CONFIG_EXAMPLE_UART_ATCMD
|
||||
at_printf("STA,");
|
||||
at_printf("STA:");
|
||||
#endif
|
||||
printf("\tMODE => STATION\n");
|
||||
break;
|
||||
|
|
|
@ -455,9 +455,6 @@ int result;
|
|||
{
|
||||
void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int));
|
||||
|
||||
if(stack_addr == NULL){
|
||||
}
|
||||
|
||||
result = xTaskGenericCreate(
|
||||
thread,
|
||||
( signed portCHAR * ) name,
|
||||
|
|
|
@ -90,9 +90,27 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _PLATFORM_AUTOCONFIG_H_
|
||||
#include "platform_autoconf.h"
|
||||
#endif
|
||||
|
||||
/* Application specific configuration options. */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
//-----------
|
||||
#if defined(CONFIG_PLATFORM_8195A)
|
||||
#ifndef CONFIG_USE_TCM_HEAP
|
||||
#define CONFIG_USE_TCM_HEAP
|
||||
#endif
|
||||
#ifndef configUSE_STACK_TCM_HEAP
|
||||
#define configUSE_STACK_TCM_HEAP 1
|
||||
#endif
|
||||
#else
|
||||
#undef configUSE_STACK_TCM_HEAP
|
||||
#define configUSE_STACK_TCM_HEAP 0
|
||||
#endif
|
||||
//-----------
|
||||
|
||||
/* Basic FreeRTOS definitions. */
|
||||
#include "projdefs.h"
|
||||
|
||||
|
|
|
@ -724,12 +724,18 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
|||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
#if configUSE_IDLE_HOOK
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
/* 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. */
|
||||
#ifdef CONFIG_WDG_ON_IDLE
|
||||
WDGRefresh();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if configCHECK_FOR_STACK_OVERFLOW
|
||||
#include "diag.h"
|
||||
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);
|
||||
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;
|
||||
TCB_t * pxNewTCB;
|
||||
|
@ -2753,9 +2760,6 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
|||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
#ifdef CONFIG_WDG_ON_IDLE
|
||||
WDGRefresh();
|
||||
#endif
|
||||
}
|
||||
#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 )
|
||||
{
|
||||
TCB_t *pxNewTCB;
|
||||
|
@ -3033,12 +3036,12 @@ TCB_t *pxNewTCB;
|
|||
/* 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
|
||||
be deleted later if required. */
|
||||
//pvvx
|
||||
#if CONFIG_USE_TCM_HEAP
|
||||
#if configUSE_STACK_TCM_HEAP
|
||||
if(puxStackBuffer == NULL) {
|
||||
pxNewTCB->pxStack = ( StackType_t * ) tcm_heap_malloc((( size_t ) puxStackBuffer) * sizeof(StackType_t));
|
||||
if(pxNewTCB->pxStack == NULL) pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc((( 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 ) usStackDepth) * sizeof(StackType_t));
|
||||
}
|
||||
else pxNewTCB->pxStack = puxStackBuffer;
|
||||
#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. */
|
||||
#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
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
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 STACK_MACROS_H
|
||||
#define STACK_MACROS_H
|
||||
|
||||
/*
|
||||
* Call the stack overflow hook function if the stack of the task being swapped
|
||||
* out is currently overflowed, or looks like it might have overflowed in the
|
||||
* past.
|
||||
*
|
||||
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
|
||||
* the current stack state only - comparing the current top of stack value to
|
||||
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
|
||||
* will also cause the last few stack bytes to be checked to ensure the value
|
||||
* to which the bytes were set when the task was created have not been
|
||||
* overwritten. Note this second test does not guarantee that an overflowed
|
||||
* stack will always be recognised.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
\
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||
\
|
||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||
\
|
||||
\
|
||||
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||
\
|
||||
/* Has the extremity of the task stack ever been written over? */ \
|
||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Remove stack overflow macro if not being used. */
|
||||
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* STACK_MACROS_H */
|
||||
|
|
@ -0,0 +1,762 @@
|
|||
/*
|
||||
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 CO_ROUTINE_H
|
||||
#define CO_ROUTINE_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
||||
#endif
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Used to hide the implementation of the co-routine control block. The
|
||||
control block structure however has to be included in the header due to
|
||||
the macro implementation of the co-routine functionality. */
|
||||
typedef void * CoRoutineHandle_t;
|
||||
|
||||
/* Defines the prototype to which co-routine functions must conform. */
|
||||
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
|
||||
|
||||
typedef struct corCoRoutineControlBlock
|
||||
{
|
||||
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||
ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||
ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||
UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||
UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||
uint16_t uxState; /*< Used internally by the co-routine implementation. */
|
||||
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
BaseType_t xCoRoutineCreate(
|
||||
crCOROUTINE_CODE pxCoRoutineCode,
|
||||
UBaseType_t uxPriority,
|
||||
UBaseType_t uxIndex
|
||||
);</pre>
|
||||
*
|
||||
* Create a new co-routine and add it to the list of co-routines that are
|
||||
* ready to run.
|
||||
*
|
||||
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
|
||||
* functions require special syntax - see the co-routine section of the WEB
|
||||
* documentation for more information.
|
||||
*
|
||||
* @param uxPriority The priority with respect to other co-routines at which
|
||||
* the co-routine will run.
|
||||
*
|
||||
* @param uxIndex Used to distinguish between different co-routines that
|
||||
* execute the same function. See the example below and the co-routine section
|
||||
* of the WEB documentation for further information.
|
||||
*
|
||||
* @return pdPASS if the co-routine was successfully created and added to a ready
|
||||
* list, otherwise an error code defined with ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
// This may not be necessary for const variables.
|
||||
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// This co-routine just delays for a fixed period, then toggles
|
||||
// an LED. Two co-routines are created using this function, so
|
||||
// the uxIndex parameter is used to tell the co-routine which
|
||||
// LED to flash and how int32_t to delay. This assumes xQueue has
|
||||
// already been created.
|
||||
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}
|
||||
|
||||
// Function that creates two co-routines.
|
||||
void vOtherFunction( void )
|
||||
{
|
||||
uint8_t ucParameterToPass;
|
||||
TaskHandle_t xHandle;
|
||||
|
||||
// Create two co-routines at priority 0. The first is given index 0
|
||||
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||
{
|
||||
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
void vCoRoutineSchedule( void );</pre>
|
||||
*
|
||||
* Run a co-routine.
|
||||
*
|
||||
* vCoRoutineSchedule() executes the highest priority co-routine that is able
|
||||
* to run. The co-routine will execute until it either blocks, yields or is
|
||||
* preempted by a task. Co-routines execute cooperatively so one
|
||||
* co-routine cannot be preempted by another, but can be preempted by a task.
|
||||
*
|
||||
* If an application comprises of both tasks and co-routines then
|
||||
* vCoRoutineSchedule should be called from the idle task (in an idle task
|
||||
* hook).
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// This idle task hook will schedule a co-routine each time it is called.
|
||||
// The rest of the idle task will execute between co-routine calls.
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
vCoRoutineSchedule();
|
||||
}
|
||||
|
||||
// Alternatively, if you do not require any other part of the idle task to
|
||||
// execute, the idle task hook can call vCoRoutineScheduler() within an
|
||||
// infinite loop.
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
vCoRoutineSchedule();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
void vCoRoutineSchedule( void );
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crSTART( CoRoutineHandle_t xHandle );</pre>
|
||||
*
|
||||
* This macro MUST always be called at the start of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static int32_t ulAVariable;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Co-routine functionality goes here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crEND();</pre>
|
||||
*
|
||||
* This macro MUST always be called at the end of a co-routine function.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static int32_t ulAVariable;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Co-routine functionality goes here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crSTART crSTART
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crEND() }
|
||||
|
||||
/*
|
||||
* These macros are intended for internal use by the co-routine implementation
|
||||
* only. The macros should not be used directly by application writers.
|
||||
*/
|
||||
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
*<pre>
|
||||
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
||||
*
|
||||
* Delay a co-routine for a fixed period of time.
|
||||
*
|
||||
* crDELAY can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* @param xHandle The handle of the co-routine to delay. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||
* for. The actual amount of time this equates to is defined by
|
||||
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS
|
||||
* can be used to convert ticks to milliseconds.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine to be created.
|
||||
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
// This may not be necessary for const variables.
|
||||
// We are to delay for 200ms.
|
||||
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||
|
||||
// Must start every co-routine with a call to crSTART();
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Delay for 200ms.
|
||||
crDELAY( xHandle, xDelayTime );
|
||||
|
||||
// Do something here.
|
||||
}
|
||||
|
||||
// Must end every co-routine with a call to crEND();
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crDELAY crDELAY
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crDELAY( xHandle, xTicksToDelay ) \
|
||||
if( ( xTicksToDelay ) > 0 ) \
|
||||
{ \
|
||||
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
|
||||
} \
|
||||
crSET_STATE0( ( xHandle ) );
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
crQUEUE_SEND(
|
||||
CoRoutineHandle_t xHandle,
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t *pxResult
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||
*
|
||||
* crQUEUE_SEND can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param pxQueue The handle of the queue on which the data will be posted.
|
||||
* The handle is obtained as the return value when the queue is created using
|
||||
* the xQueueCreate() API function.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the data being posted onto the queue.
|
||||
* The number of bytes of each queued item is specified when the queue is
|
||||
* created. This number of bytes is copied from pvItemToQueue into the queue
|
||||
* itself.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||
* to wait for space to become available on the queue, should space not be
|
||||
* available immediately. The actual amount of time this equates to is defined
|
||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
|
||||
* below).
|
||||
*
|
||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||
* data was successfully posted onto the queue, otherwise it will be set to an
|
||||
* error defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||
// a queue.
|
||||
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static BaseType_t xNumberToPost = 0;
|
||||
static BaseType_t xResult;
|
||||
|
||||
// Co-routines must begin with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// This assumes the queue has already been created.
|
||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||
|
||||
if( xResult != pdPASS )
|
||||
{
|
||||
// The message was not posted!
|
||||
}
|
||||
|
||||
// Increment the number to be posted onto the queue.
|
||||
xNumberToPost++;
|
||||
|
||||
// Delay for 100 ticks.
|
||||
crDELAY( xHandle, 100 );
|
||||
}
|
||||
|
||||
// Co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
||||
{ \
|
||||
*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \
|
||||
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||
{ \
|
||||
crSET_STATE0( ( xHandle ) ); \
|
||||
*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \
|
||||
} \
|
||||
if( *pxResult == errQUEUE_YIELD ) \
|
||||
{ \
|
||||
crSET_STATE1( ( xHandle ) ); \
|
||||
*pxResult = pdPASS; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_RECEIVE(
|
||||
CoRoutineHandle_t xHandle,
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvBuffer,
|
||||
TickType_t xTicksToWait,
|
||||
BaseType_t *pxResult
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||
*
|
||||
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
|
||||
* from within a function called by the co-routine function. This is because
|
||||
* co-routines do not maintain their own stack.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||
* parameter of the co-routine function.
|
||||
*
|
||||
* @param pxQueue The handle of the queue from which the data will be received.
|
||||
* The handle is obtained as the return value when the queue is created using
|
||||
* the xQueueCreate() API function.
|
||||
*
|
||||
* @param pvBuffer The buffer into which the received item is to be copied.
|
||||
* The number of bytes of each queued item is specified when the queue is
|
||||
* created. This number of bytes is copied into pvBuffer.
|
||||
*
|
||||
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||
* to wait for data to become available from the queue, should data not be
|
||||
* available immediately. The actual amount of time this equates to is defined
|
||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
|
||||
* crQUEUE_SEND example).
|
||||
*
|
||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||
* data was successfully retrieved from the queue, otherwise it will be set to
|
||||
* an error code as defined within ProjDefs.h.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine receives the number of an LED to flash from a queue. It
|
||||
// blocks on the queue until the number is received.
|
||||
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||
static BaseType_t xResult;
|
||||
static UBaseType_t uxLEDToFlash;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for data to become available on the queue.
|
||||
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// We received the LED to flash - flash it!
|
||||
vParTestToggleLED( uxLEDToFlash );
|
||||
}
|
||||
}
|
||||
|
||||
crEND();
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
||||
{ \
|
||||
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \
|
||||
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||
{ \
|
||||
crSET_STATE0( ( xHandle ) ); \
|
||||
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \
|
||||
} \
|
||||
if( *( pxResult ) == errQUEUE_YIELD ) \
|
||||
{ \
|
||||
crSET_STATE1( ( xHandle ) ); \
|
||||
*( pxResult ) = pdPASS; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_SEND_FROM_ISR(
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvItemToQueue,
|
||||
BaseType_t xCoRoutinePreviouslyWoken
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
* functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||
* ISR.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
|
||||
* that is being used from within a co-routine.
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||
* queue. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||
* into the queue storage area.
|
||||
*
|
||||
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
|
||||
* the same queue multiple times from a single interrupt. The first call
|
||||
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||
* the value returned from the previous call.
|
||||
*
|
||||
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
|
||||
* used by the ISR to determine if a context switch may be required following
|
||||
* the ISR.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
char cRxedChar;
|
||||
BaseType_t xResult;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Wait for data to become available on the queue. This assumes the
|
||||
// queue xCommsRxQueue has already been created!
|
||||
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||
|
||||
// Was a character received?
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// Process the character here.
|
||||
}
|
||||
}
|
||||
|
||||
// All co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}
|
||||
|
||||
// An ISR that uses a queue to send characters received on a serial port to
|
||||
// a co-routine.
|
||||
void vUART_ISR( void )
|
||||
{
|
||||
char cRxedChar;
|
||||
BaseType_t xCRWokenByPost = pdFALSE;
|
||||
|
||||
// We loop around reading characters until there are none left in the UART.
|
||||
while( UART_RX_REG_NOT_EMPTY() )
|
||||
{
|
||||
// Obtain the character from the UART.
|
||||
cRxedChar = UART_RX_REG;
|
||||
|
||||
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||
// the first time around the loop. If the post causes a co-routine
|
||||
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||
// In this manner we can ensure that if more than one co-routine is
|
||||
// blocked on the queue only one is woken by this ISR no matter how
|
||||
// many characters are posted to the queue.
|
||||
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||
}
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
|
||||
|
||||
|
||||
/**
|
||||
* croutine. h
|
||||
* <pre>
|
||||
crQUEUE_SEND_FROM_ISR(
|
||||
QueueHandle_t pxQueue,
|
||||
void *pvBuffer,
|
||||
BaseType_t * pxCoRoutineWoken
|
||||
)</pre>
|
||||
*
|
||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||
* functions used by tasks.
|
||||
*
|
||||
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||
* ISR.
|
||||
*
|
||||
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
|
||||
* from a queue that is being used from within a co-routine (a co-routine
|
||||
* posted to the queue).
|
||||
*
|
||||
* See the co-routine section of the WEB documentation for information on
|
||||
* passing data between tasks and co-routines and between ISR's and
|
||||
* co-routines.
|
||||
*
|
||||
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||
*
|
||||
* @param pvBuffer A pointer to a buffer into which the received item will be
|
||||
* placed. The size of the items the queue will hold was defined when the
|
||||
* queue was created, so this many bytes will be copied from the queue into
|
||||
* pvBuffer.
|
||||
*
|
||||
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
|
||||
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
|
||||
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
|
||||
* *pxCoRoutineWoken will remain unchanged.
|
||||
*
|
||||
* @return pdTRUE an item was successfully received from the queue, otherwise
|
||||
* pdFALSE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||
// period. The character is incremented each time.
|
||||
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||
{
|
||||
// cChar holds its value while this co-routine is blocked and must therefore
|
||||
// be declared static.
|
||||
static char cCharToTx = 'a';
|
||||
BaseType_t xResult;
|
||||
|
||||
// All co-routines must start with a call to crSTART().
|
||||
crSTART( xHandle );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Send the next character to the queue.
|
||||
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// The character was successfully posted to the queue.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could not post the character to the queue.
|
||||
}
|
||||
|
||||
// Enable the UART Tx interrupt to cause an interrupt in this
|
||||
// hypothetical UART. The interrupt will obtain the character
|
||||
// from the queue and send it.
|
||||
ENABLE_RX_INTERRUPT();
|
||||
|
||||
// Increment to the next character then block for a fixed period.
|
||||
// cCharToTx will maintain its value across the delay as it is
|
||||
// declared static.
|
||||
cCharToTx++;
|
||||
if( cCharToTx > 'x' )
|
||||
{
|
||||
cCharToTx = 'a';
|
||||
}
|
||||
crDELAY( 100 );
|
||||
}
|
||||
|
||||
// All co-routines must end with a call to crEND().
|
||||
crEND();
|
||||
}
|
||||
|
||||
// An ISR that uses a queue to receive characters to send on a UART.
|
||||
void vUART_ISR( void )
|
||||
{
|
||||
char cCharToTx;
|
||||
BaseType_t xCRWokenByPost = pdFALSE;
|
||||
|
||||
while( UART_TX_REG_EMPTY() )
|
||||
{
|
||||
// Are there any characters in the queue waiting to be sent?
|
||||
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||
// is woken by the post - ensuring that only a single co-routine is
|
||||
// woken no matter how many times we go around this loop.
|
||||
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||
{
|
||||
SEND_CHARACTER( cCharToTx );
|
||||
}
|
||||
}
|
||||
}</pre>
|
||||
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the co-routine macros only.
|
||||
* The macro nature of the co-routine implementation requires that the
|
||||
* prototype appears here. The function should not be used by application
|
||||
* writers.
|
||||
*
|
||||
* Removes the current co-routine from its ready list and places it in the
|
||||
* appropriate delayed list.
|
||||
*/
|
||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
|
||||
|
||||
/*
|
||||
* This function is intended for internal use by the queue implementation only.
|
||||
* The function should not be used by application writers.
|
||||
*
|
||||
* Removes the highest priority co-routine from the event list and places it in
|
||||
* the pending ready list.
|
||||
*/
|
||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CO_ROUTINE_H */
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
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 DEPRECATED_DEFINITIONS_H
|
||||
#define DEPRECATED_DEFINITIONS_H
|
||||
|
||||
|
||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||
pre-processor definition was used to ensure the pre-processor found the correct
|
||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||
of setting the compiler's include path such that it found the correct
|
||||
portmacro.h file - removing the need for the constant and allowing the
|
||||
portmacro.h file to be located anywhere in relation to the port being used. The
|
||||
definitions below remain in the code for backward compatibility only. New
|
||||
projects should not use them. */
|
||||
|
||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MEGA_AVR
|
||||
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC24_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_DSPIC_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC18F_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MPLAB_PIC32MX_PORT
|
||||
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _FEDPICC
|
||||
#include "libFreeRTOS/Include/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDCC_CYGNAL
|
||||
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7
|
||||
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARM7_ECLIPSE
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_LPC23xx
|
||||
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_MSP430
|
||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MSP430
|
||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ROWLEY_MSP430
|
||||
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_GCC
|
||||
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM7_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef SAM9XE_IAR
|
||||
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef LPC2000_IAR
|
||||
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR71X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR75X_GCC
|
||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef STR91X_IAR
|
||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_H8S
|
||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_AT91FR40008
|
||||
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef RVDS_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3_LM3S102
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_ARMCM3
|
||||
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARM_CM3
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef IAR_ARMCM3_LM
|
||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef HCS12_CODE_WARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef MICROBLAZE_GCC
|
||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef TERN_EE
|
||||
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_HCS12
|
||||
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_MCF5235
|
||||
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_GCC
|
||||
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC405
|
||||
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef GCC_PPC440
|
||||
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef _16FX_SOFTUNE
|
||||
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef BCC_FLASH_LITE_186_PORT
|
||||
/* A short file name has to be used in place of the normal
|
||||
FreeRTOSConfig.h when using the Borland compiler. */
|
||||
#include "frconfig.h"
|
||||
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||
typedef void ( __interrupt __far *pxISR )();
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __AVR32_AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __ICCAVR32__
|
||||
#ifdef __CORE__
|
||||
#if __CORE__ == __AVR32A__
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __91467D
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __96340
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __IAR_V850ES_Fx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx3_L__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Jx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_V850ES_Hx2__
|
||||
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#ifdef __IAR_78K0R_Kx3L__
|
||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||
#endif
|
||||
|
||||
#endif /* DEPRECATED_DEFINITIONS_H */
|
||||
|
|
@ -0,0 +1,797 @@
|
|||
/*
|
||||
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 EVENT_GROUPS_H
|
||||
#define EVENT_GROUPS_H
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
||||
#endif
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "timers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An event group is a collection of bits to which an application can assign a
|
||||
* meaning. For example, an application may create an event group to convey
|
||||
* the status of various CAN bus related events in which bit 0 might mean "A CAN
|
||||
* message has been received and is ready for processing", bit 1 might mean "The
|
||||
* application has queued a message that is ready for sending onto the CAN
|
||||
* network", and bit 2 might mean "It is time to send a SYNC message onto the
|
||||
* CAN network" etc. A task can then test the bit values to see which events
|
||||
* are active, and optionally enter the Blocked state to wait for a specified
|
||||
* bit or a group of specified bits to be active. To continue the CAN bus
|
||||
* example, a CAN controlling task can enter the Blocked state (and therefore
|
||||
* not consume any processing time) until either bit 0, bit 1 or bit 2 are
|
||||
* active, at which time the bit that was actually active would inform the task
|
||||
* which action it had to take (process a received message, send a message, or
|
||||
* send a SYNC).
|
||||
*
|
||||
* The event groups implementation contains intelligence to avoid race
|
||||
* conditions that would otherwise occur were an application to use a simple
|
||||
* variable for the same purpose. This is particularly important with respect
|
||||
* to when a bit within an event group is to be cleared, and when bits have to
|
||||
* be set and then tested atomically - as is the case where event groups are
|
||||
* used to create a synchronisation point between multiple tasks (a
|
||||
* 'rendezvous').
|
||||
*
|
||||
* \defgroup EventGroup
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*
|
||||
* Type by which event groups are referenced. For example, a call to
|
||||
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then
|
||||
* be used as a parameter to other event group functions.
|
||||
*
|
||||
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
typedef void * EventGroupHandle_t;
|
||||
|
||||
/*
|
||||
* The type that holds event bits always matches TickType_t - therefore the
|
||||
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
|
||||
* 32 bits if set to 0.
|
||||
*
|
||||
* \defgroup EventBits_t EventBits_t
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventGroupHandle_t xEventGroupCreate( void );
|
||||
</pre>
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||
* block of memory, in which the event group's structure is stored. If an event
|
||||
* groups is created using xEventGropuCreate() then the required memory is
|
||||
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||
* (see http://www.freertos.org/a00111.html). If an event group is created
|
||||
* using xEventGropuCreateStatic() then the application writer must instead
|
||||
* provide the memory that will get used by the event group.
|
||||
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||
* without using any dynamic memory allocation.
|
||||
*
|
||||
* Although event groups are not related to ticks, for internal implementation
|
||||
* reasons the number of bits available for use in an event group is dependent
|
||||
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||
* event bits within an event group.
|
||||
*
|
||||
* @return If the event group was created then a handle to the event group is
|
||||
* returned. If there was insufficient FreeRTOS heap available to create the
|
||||
* event group then NULL is returned. See http://www.freertos.org/a00111.html
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Declare a variable to hold the created event group.
|
||||
EventGroupHandle_t xCreatedEventGroup;
|
||||
|
||||
// Attempt to create the event group.
|
||||
xCreatedEventGroup = xEventGroupCreate();
|
||||
|
||||
// Was the event group created successfully?
|
||||
if( xCreatedEventGroup == NULL )
|
||||
{
|
||||
// The event group was not created because there was insufficient
|
||||
// FreeRTOS heap available.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The event group was created.
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupCreate xEventGroupCreate
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
|
||||
</pre>
|
||||
*
|
||||
* Create a new event group.
|
||||
*
|
||||
* Internally, within the FreeRTOS implementation, event groups use a [small]
|
||||
* block of memory, in which the event group's structure is stored. If an event
|
||||
* groups is created using xEventGropuCreate() then the required memory is
|
||||
* automatically dynamically allocated inside the xEventGroupCreate() function.
|
||||
* (see http://www.freertos.org/a00111.html). If an event group is created
|
||||
* using xEventGropuCreateStatic() then the application writer must instead
|
||||
* provide the memory that will get used by the event group.
|
||||
* xEventGroupCreateStatic() therefore allows an event group to be created
|
||||
* without using any dynamic memory allocation.
|
||||
*
|
||||
* Although event groups are not related to ticks, for internal implementation
|
||||
* reasons the number of bits available for use in an event group is dependent
|
||||
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||
* event bits within an event group.
|
||||
*
|
||||
* @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
|
||||
* StaticEventGroup_t, which will be then be used to hold the event group's data
|
||||
* structures, removing the need for the memory to be allocated dynamically.
|
||||
*
|
||||
* @return If the event group was created then a handle to the event group is
|
||||
* returned. If pxEventGroupBuffer was NULL then NULL is returned.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// StaticEventGroup_t is a publicly accessible structure that has the same
|
||||
// size and alignment requirements as the real event group structure. It is
|
||||
// provided as a mechanism for applications to know the size of the event
|
||||
// group (which is dependent on the architecture and configuration file
|
||||
// settings) without breaking the strict data hiding policy by exposing the
|
||||
// real event group internals. This StaticEventGroup_t variable is passed
|
||||
// into the xSemaphoreCreateEventGroupStatic() function and is used to store
|
||||
// the event group's data structures
|
||||
StaticEventGroup_t xEventGroupBuffer;
|
||||
|
||||
// Create the event group without dynamically allocating any memory.
|
||||
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
|
||||
</pre>
|
||||
*/
|
||||
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
const TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* [Potentially] block to wait for one or more bits to be set within a
|
||||
* previously created event group.
|
||||
*
|
||||
* This function cannot be called from an interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are being tested. The
|
||||
* event group must have previously been created using a call to
|
||||
* xEventGroupCreate().
|
||||
*
|
||||
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. For example, to wait for bit 0 and/or bit 2 set
|
||||
* uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
|
||||
* uxBitsToWaitFor to 0x07. Etc.
|
||||
*
|
||||
* @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
|
||||
* uxBitsToWaitFor that are set within the event group will be cleared before
|
||||
* xEventGroupWaitBits() returns if the wait condition was met (if the function
|
||||
* returns for a reason other than a timeout). If xClearOnExit is set to
|
||||
* pdFALSE then the bits set in the event group are not altered when the call to
|
||||
* xEventGroupWaitBits() returns.
|
||||
*
|
||||
* @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
|
||||
* xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
|
||||
* are set or the specified block time expires. If xWaitForAllBits is set to
|
||||
* pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
|
||||
* in uxBitsToWaitFor is set or the specified block time expires. The block
|
||||
* time is specified by the xTicksToWait parameter.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||
* for one/all (depending on the xWaitForAllBits value) of the bits specified by
|
||||
* uxBitsToWaitFor to become set.
|
||||
*
|
||||
* @return The value of the event group at the time either the bits being waited
|
||||
* for became set, or the block time expired. Test the return value to know
|
||||
* which bits were set. If xEventGroupWaitBits() returned because its timeout
|
||||
* expired then not all the bits being waited for will be set. If
|
||||
* xEventGroupWaitBits() returned because the bits it was waiting for were set
|
||||
* then the returned value is the event group value before any bits were
|
||||
* automatically cleared in the case that xClearOnExit parameter was set to
|
||||
* pdTRUE.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
void aFunction( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||
|
||||
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
||||
// the event group. Clear the bits before exiting.
|
||||
uxBits = xEventGroupWaitBits(
|
||||
xEventGroup, // The event group being tested.
|
||||
BIT_0 | BIT_4, // The bits within the event group to wait for.
|
||||
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
||||
|
||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
{
|
||||
// xEventGroupWaitBits() returned because both bits were set.
|
||||
}
|
||||
else if( ( uxBits & BIT_0 ) != 0 )
|
||||
{
|
||||
// xEventGroupWaitBits() returned because just BIT_0 was set.
|
||||
}
|
||||
else if( ( uxBits & BIT_4 ) != 0 )
|
||||
{
|
||||
// xEventGroupWaitBits() returned because just BIT_4 was set.
|
||||
}
|
||||
else
|
||||
{
|
||||
// xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
||||
// without either BIT_0 or BIT_4 becoming set.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||
</pre>
|
||||
*
|
||||
* Clear bits within an event group. This function cannot be called from an
|
||||
* interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||
*
|
||||
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
|
||||
* in the event group. For example, to clear bit 3 only, set uxBitsToClear to
|
||||
* 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
|
||||
*
|
||||
* @return The value of the event group before the specified bits were cleared.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
void aFunction( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
|
||||
// Clear bit 0 and bit 4 in xEventGroup.
|
||||
uxBits = xEventGroupClearBits(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 );// The bits being cleared.
|
||||
|
||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
{
|
||||
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
||||
// called. Both will now be clear (not set).
|
||||
}
|
||||
else if( ( uxBits & BIT_0 ) != 0 )
|
||||
{
|
||||
// Bit 0 was set before xEventGroupClearBits() was called. It will
|
||||
// now be clear.
|
||||
}
|
||||
else if( ( uxBits & BIT_4 ) != 0 )
|
||||
{
|
||||
// Bit 4 was set before xEventGroupClearBits() was called. It will
|
||||
// now be clear.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither bit 0 nor bit 4 were set in the first place.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
</pre>
|
||||
*
|
||||
* A version of xEventGroupClearBits() that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because there
|
||||
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||
* set. FreeRTOS does not allow nondeterministic operations to be performed
|
||||
* while interrupts are disabled, so protects event groups that are accessed
|
||||
* from tasks by suspending the scheduler rather than disabling interrupts. As
|
||||
* a result event groups cannot be accessed directly from an interrupt service
|
||||
* routine. Therefore xEventGroupClearBitsFromISR() sends a message to the
|
||||
* timer task to have the clear operation performed in the context of the timer
|
||||
* task.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||
*
|
||||
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
|
||||
* For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3
|
||||
* and bit 0 set uxBitsToClear to 0x09.
|
||||
*
|
||||
* @return If the request to execute the function was posted successfully then
|
||||
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
// An event group which it is assumed has already been created by a call to
|
||||
// xEventGroupCreate().
|
||||
EventGroupHandle_t xEventGroup;
|
||||
|
||||
void anInterruptHandler( void )
|
||||
{
|
||||
// Clear bit 0 and bit 4 in xEventGroup.
|
||||
xResult = xEventGroupClearBitsFromISR(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 ); // The bits being set.
|
||||
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// The message was posted successfully.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
</pre>
|
||||
*
|
||||
* Set bits within an event group.
|
||||
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
||||
* is a version that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group will automatically unblock tasks that are
|
||||
* blocked waiting for the bits.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be set.
|
||||
*
|
||||
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||
* and bit 0 set uxBitsToSet to 0x09.
|
||||
*
|
||||
* @return The value of the event group at the time the call to
|
||||
* xEventGroupSetBits() returns. There are two reasons why the returned value
|
||||
* might have the bits specified by the uxBitsToSet parameter cleared. First,
|
||||
* if setting a bit results in a task that was waiting for the bit leaving the
|
||||
* blocked state then it is possible the bit will be cleared automatically
|
||||
* (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
|
||||
* unblocked (or otherwise Ready state) task that has a priority above that of
|
||||
* the task that called xEventGroupSetBits() will execute and may change the
|
||||
* event group value before the call to xEventGroupSetBits() returns.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
void aFunction( EventGroupHandle_t xEventGroup )
|
||||
{
|
||||
EventBits_t uxBits;
|
||||
|
||||
// Set bit 0 and bit 4 in xEventGroup.
|
||||
uxBits = xEventGroupSetBits(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 );// The bits being set.
|
||||
|
||||
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||
{
|
||||
// Both bit 0 and bit 4 remained set when the function returned.
|
||||
}
|
||||
else if( ( uxBits & BIT_0 ) != 0 )
|
||||
{
|
||||
// Bit 0 remained set when the function returned, but bit 4 was
|
||||
// cleared. It might be that bit 4 was cleared automatically as a
|
||||
// task that was waiting for bit 4 was removed from the Blocked
|
||||
// state.
|
||||
}
|
||||
else if( ( uxBits & BIT_4 ) != 0 )
|
||||
{
|
||||
// Bit 4 remained set when the function returned, but bit 0 was
|
||||
// cleared. It might be that bit 0 was cleared automatically as a
|
||||
// task that was waiting for bit 0 was removed from the Blocked
|
||||
// state.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither bit 0 nor bit 4 remained set. It might be that a task
|
||||
// was waiting for both of the bits to be set, and the bits were
|
||||
// cleared as the task left the Blocked state.
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||
</pre>
|
||||
*
|
||||
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
||||
*
|
||||
* Setting bits in an event group is not a deterministic operation because there
|
||||
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||
* set. FreeRTOS does not allow nondeterministic operations to be performed in
|
||||
* interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR()
|
||||
* sends a message to the timer task to have the set operation performed in the
|
||||
* context of the timer task - where a scheduler lock is used in place of a
|
||||
* critical section.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are to be set.
|
||||
*
|
||||
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||
* and bit 0 set uxBitsToSet to 0x09.
|
||||
*
|
||||
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function
|
||||
* will result in a message being sent to the timer daemon task. If the
|
||||
* priority of the timer daemon task is higher than the priority of the
|
||||
* currently running task (the task the interrupt interrupted) then
|
||||
* *pxHigherPriorityTaskWoken will be set to pdTRUE by
|
||||
* xEventGroupSetBitsFromISR(), indicating that a context switch should be
|
||||
* requested before the interrupt exits. For that reason
|
||||
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
|
||||
* example code below.
|
||||
*
|
||||
* @return If the request to execute the function was posted successfully then
|
||||
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||
* if the timer service queue was full.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
#define BIT_0 ( 1 << 0 )
|
||||
#define BIT_4 ( 1 << 4 )
|
||||
|
||||
// An event group which it is assumed has already been created by a call to
|
||||
// xEventGroupCreate().
|
||||
EventGroupHandle_t xEventGroup;
|
||||
|
||||
void anInterruptHandler( void )
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||
|
||||
// xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
// Set bit 0 and bit 4 in xEventGroup.
|
||||
xResult = xEventGroupSetBitsFromISR(
|
||||
xEventGroup, // The event group being updated.
|
||||
BIT_0 | BIT_4 // The bits being set.
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
// Was the message posted successfully?
|
||||
if( xResult == pdPASS )
|
||||
{
|
||||
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||
// switch should be requested. The macro used is port specific and
|
||||
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||
// refer to the documentation page for the port being used.
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait );
|
||||
</pre>
|
||||
*
|
||||
* Atomically set bits within an event group, then wait for a combination of
|
||||
* bits to be set within the same event group. This functionality is typically
|
||||
* used to synchronise multiple tasks, where each task has to wait for the other
|
||||
* tasks to reach a synchronisation point before proceeding.
|
||||
*
|
||||
* This function cannot be used from an interrupt.
|
||||
*
|
||||
* The function will return before its block time expires if the bits specified
|
||||
* by the uxBitsToWait parameter are set, or become set within that time. In
|
||||
* this case all the bits specified by uxBitsToWait will be automatically
|
||||
* cleared before the function returns.
|
||||
*
|
||||
* @param xEventGroup The event group in which the bits are being tested. The
|
||||
* event group must have previously been created using a call to
|
||||
* xEventGroupCreate().
|
||||
*
|
||||
* @param uxBitsToSet The bits to set in the event group before determining
|
||||
* if, and possibly waiting for, all the bits specified by the uxBitsToWait
|
||||
* parameter are set.
|
||||
*
|
||||
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||
* inside the event group. For example, to wait for bit 0 and bit 2 set
|
||||
* uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set
|
||||
* uxBitsToWaitFor to 0x07. Etc.
|
||||
*
|
||||
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||
* for all of the bits specified by uxBitsToWaitFor to become set.
|
||||
*
|
||||
* @return The value of the event group at the time either the bits being waited
|
||||
* for became set, or the block time expired. Test the return value to know
|
||||
* which bits were set. If xEventGroupSync() returned because its timeout
|
||||
* expired then not all the bits being waited for will be set. If
|
||||
* xEventGroupSync() returned because all the bits it was waiting for were
|
||||
* set then the returned value is the event group value before any bits were
|
||||
* automatically cleared.
|
||||
*
|
||||
* Example usage:
|
||||
<pre>
|
||||
// Bits used by the three tasks.
|
||||
#define TASK_0_BIT ( 1 << 0 )
|
||||
#define TASK_1_BIT ( 1 << 1 )
|
||||
#define TASK_2_BIT ( 1 << 2 )
|
||||
|
||||
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
||||
|
||||
// Use an event group to synchronise three tasks. It is assumed this event
|
||||
// group has already been created elsewhere.
|
||||
EventGroupHandle_t xEventBits;
|
||||
|
||||
void vTask0( void *pvParameters )
|
||||
{
|
||||
EventBits_t uxReturn;
|
||||
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
// Perform task functionality here.
|
||||
|
||||
// Set bit 0 in the event flag to note this task has reached the
|
||||
// sync point. The other two tasks will set the other two bits defined
|
||||
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
||||
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
||||
// for this to happen.
|
||||
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
||||
|
||||
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
||||
{
|
||||
// All three tasks reached the synchronisation point before the call
|
||||
// to xEventGroupSync() timed out.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vTask1( void *pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Perform task functionality here.
|
||||
|
||||
// Set bit 1 in the event flag to note this task has reached the
|
||||
// synchronisation point. The other two tasks will set the other two
|
||||
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||
// indefinitely for this to happen.
|
||||
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||
|
||||
// xEventGroupSync() was called with an indefinite block time, so
|
||||
// this task will only reach here if the syncrhonisation was made by all
|
||||
// three tasks, so there is no need to test the return value.
|
||||
}
|
||||
}
|
||||
|
||||
void vTask2( void *pvParameters )
|
||||
{
|
||||
for( ;; )
|
||||
{
|
||||
// Perform task functionality here.
|
||||
|
||||
// Set bit 2 in the event flag to note this task has reached the
|
||||
// synchronisation point. The other two tasks will set the other two
|
||||
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||
// indefinitely for this to happen.
|
||||
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||
|
||||
// xEventGroupSync() was called with an indefinite block time, so
|
||||
// this task will only reach here if the syncrhonisation was made by all
|
||||
// three tasks, so there is no need to test the return value.
|
||||
}
|
||||
}
|
||||
|
||||
</pre>
|
||||
* \defgroup xEventGroupSync xEventGroupSync
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
*
|
||||
* Returns the current value of the bits in an event group. This function
|
||||
* cannot be used from an interrupt.
|
||||
*
|
||||
* @param xEventGroup The event group being queried.
|
||||
*
|
||||
* @return The event group bits at the time xEventGroupGetBits() was called.
|
||||
*
|
||||
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
*
|
||||
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||
*
|
||||
* @param xEventGroup The event group being queried.
|
||||
*
|
||||
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
|
||||
*
|
||||
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
||||
* \ingroup EventGroup
|
||||
*/
|
||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* event_groups.h
|
||||
*<pre>
|
||||
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||
</pre>
|
||||
*
|
||||
* Delete an event group that was previously created by a call to
|
||||
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
||||
* unblocked and obtain 0 as the event group's value.
|
||||
*
|
||||
* @param xEventGroup The event group being deleted.
|
||||
*/
|
||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* For internal use only. */
|
||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
|
||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
#if (configUSE_TRACE_FACILITY == 1)
|
||||
UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EVENT_GROUPS_H */
|
||||
|
||||
|
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
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 the list implementation used by the scheduler. While it is tailored
|
||||
* heavily for the schedulers needs, it is also available for use by
|
||||
* application code.
|
||||
*
|
||||
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||
* descending item value order.
|
||||
*
|
||||
* Lists are created already containing one list item. The value of this
|
||||
* item is the maximum possible that can be stored, it is therefore always at
|
||||
* the end of the list and acts as a marker. The list member pxHead always
|
||||
* points to this marker - even though it is at the tail of the list. This
|
||||
* is because the tail contains a wrap back pointer to the true head of
|
||||
* the list.
|
||||
*
|
||||
* In addition to it's value, each list item contains a pointer to the next
|
||||
* item in the list (pxNext), a pointer to the list it is in (pxContainer)
|
||||
* and a pointer to back to the object that contains it. These later two
|
||||
* pointers are included for efficiency of list manipulation. There is
|
||||
* effectively a two way link between the object containing the list item and
|
||||
* the list item itself.
|
||||
*
|
||||
*
|
||||
* \page ListIntroduction List Implementation
|
||||
* \ingroup FreeRTOSIntro
|
||||
*/
|
||||
|
||||
#ifndef INC_FREERTOS_H
|
||||
#error FreeRTOS.h must be included before list.h
|
||||
#endif
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
/*
|
||||
* The list structure members are modified from within interrupts, and therefore
|
||||
* by rights should be declared volatile. However, they are only modified in a
|
||||
* functionally atomic way (within critical sections of with the scheduler
|
||||
* suspended) and are either passed by reference into a function or indexed via
|
||||
* a volatile variable. Therefore, in all use cases tested so far, the volatile
|
||||
* qualifier can be omitted in order to provide a moderate performance
|
||||
* improvement without adversely affecting functional behaviour. The assembly
|
||||
* instructions generated by the IAR, ARM and GCC compilers when the respective
|
||||
* compiler's options were set for maximum optimisation has been inspected and
|
||||
* deemed to be as intended. That said, as compiler technology advances, and
|
||||
* especially if aggressive cross module optimisation is used (a use case that
|
||||
* has not been exercised to any great extend) then it is feasible that the
|
||||
* volatile qualifier will be needed for correct optimisation. It is expected
|
||||
* that a compiler removing essential code because, without the volatile
|
||||
* qualifier on the list structure members and with aggressive cross module
|
||||
* optimisation, the compiler deemed the code unnecessary will result in
|
||||
* complete and obvious failure of the scheduler. If this is ever experienced
|
||||
* then the volatile qualifier can be inserted in the relevant places within the
|
||||
* list structures by simply defining configLIST_VOLATILE to volatile in
|
||||
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
||||
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
||||
* will simply #define configLIST_VOLATILE away completely.
|
||||
*
|
||||
* To use volatile list structure members then add the following line to
|
||||
* FreeRTOSConfig.h (without the quotes):
|
||||
* "#define configLIST_VOLATILE volatile"
|
||||
*/
|
||||
#ifndef configLIST_VOLATILE
|
||||
#define configLIST_VOLATILE
|
||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Macros that can be used to place known values within the list structures,
|
||||
then check that the known values do not get corrupted during the execution of
|
||||
the application. These may catch the list data structures being overwritten in
|
||||
memory. They will not catch data errors caused by incorrect configuration or
|
||||
use of FreeRTOS.*/
|
||||
#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
|
||||
/* Define the macros to do nothing. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
|
||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE
|
||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE
|
||||
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
|
||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
|
||||
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
|
||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
|
||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem )
|
||||
#define listTEST_LIST_INTEGRITY( pxList )
|
||||
#else
|
||||
/* Define macros that add new members into the list structures. */
|
||||
#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
|
||||
#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
|
||||
#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
|
||||
#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
|
||||
|
||||
/* Define macros that set the new structure members to known values. */
|
||||
#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||
#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
|
||||
#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
|
||||
|
||||
/* Define macros that will assert if one of the structure members does not
|
||||
contain its expected value. */
|
||||
#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||
#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
|
||||
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
|
||||
|
||||
|
||||
/*
|
||||
* Definition of the only type of object that a list can contain.
|
||||
*/
|
||||
struct xLIST_ITEM
|
||||
{
|
||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||
listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
};
|
||||
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||
|
||||
struct xMINI_LIST_ITEM
|
||||
{
|
||||
listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
configLIST_VOLATILE TickType_t xItemValue;
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||
};
|
||||
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||
|
||||
/*
|
||||
* Definition of the type of queue used by the scheduler.
|
||||
*/
|
||||
typedef struct xLIST
|
||||
{
|
||||
listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
|
||||
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||
listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
|
||||
} List_t;
|
||||
|
||||
/*
|
||||
* Access macro to set the owner of a list item. The owner of a list item
|
||||
* is the object (usually a TCB) that contains the list item.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
|
||||
|
||||
/*
|
||||
* Access macro to get the owner of a list item. The owner of a list item
|
||||
* is the object (usually a TCB) that contains the list item.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||
|
||||
/*
|
||||
* Access macro to set the value of the list item. In most cases the value is
|
||||
* used to sort the list in descending order.
|
||||
*
|
||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
||||
|
||||
/*
|
||||
* Access macro to retrieve the value of the list item. The value can
|
||||
* represent anything - for example the priority of a task, or the time at
|
||||
* which a task should be unblocked.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||
|
||||
/*
|
||||
* Access macro to retrieve the value of the list item at the head of a given
|
||||
* list.
|
||||
*
|
||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
||||
|
||||
/*
|
||||
* Return the list item at the head of the list.
|
||||
*
|
||||
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||
|
||||
/*
|
||||
* Return the list item at the head of the list.
|
||||
*
|
||||
* \page listGET_NEXT listGET_NEXT
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
||||
|
||||
/*
|
||||
* Return the list item that marks the end of the list
|
||||
*
|
||||
* \page listGET_END_MARKER listGET_END_MARKER
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
||||
|
||||
/*
|
||||
* Access macro to determine if a list contains any items. The macro will
|
||||
* only have the value true if the list is empty.
|
||||
*
|
||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
|
||||
|
||||
/*
|
||||
* Access macro to return the number of items in the list.
|
||||
*/
|
||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the next entry in a list.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
||||
* and returns that entry's pxOwner parameter. Using multiple calls to this
|
||||
* function it is therefore possible to move through every item contained in
|
||||
* a list.
|
||||
*
|
||||
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||
* the list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxTCB pxTCB is set to the address of the owner of the next list item.
|
||||
* @param pxList The list from which the next item owner is to be returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||
{ \
|
||||
List_t * const pxConstList = ( pxList ); \
|
||||
/* Increment the index to the next item and return the item, ensuring */ \
|
||||
/* we don't return the marker used at the end of the list. */ \
|
||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
|
||||
{ \
|
||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||
} \
|
||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Access function to obtain the owner of the first entry in a list. Lists
|
||||
* are normally sorted in ascending item value order.
|
||||
*
|
||||
* This function returns the pxOwner member of the first item in the list.
|
||||
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||
* the list item. In the scheduler this is normally a task control block.
|
||||
* The pxOwner parameter effectively creates a two way link between the list
|
||||
* item and its owner.
|
||||
*
|
||||
* @param pxList The list from which the owner of the head item is to be
|
||||
* returned.
|
||||
*
|
||||
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
|
||||
|
||||
/*
|
||||
* Check to see if a list item is within a list. The list item maintains a
|
||||
* "container" pointer that points to the list it is in. All this macro does
|
||||
* is check to see if the container and the list match.
|
||||
*
|
||||
* @param pxList The list we want to know if the list item is within.
|
||||
* @param pxListItem The list item we want to know if is in the list.
|
||||
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||
*/
|
||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
|
||||
|
||||
/*
|
||||
* Return the list a list item is contained within (referenced from).
|
||||
*
|
||||
* @param pxListItem The list item being queried.
|
||||
* @return A pointer to the List_t object that references the pxListItem
|
||||
*/
|
||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
||||
|
||||
/*
|
||||
* This provides a crude means of knowing if a list has been initialised, as
|
||||
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
|
||||
* function.
|
||||
*/
|
||||
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
||||
|
||||
/*
|
||||
* Must be called before a list is used! This initialises all the members
|
||||
* of the list structure and inserts the xListEnd item into the list as a
|
||||
* marker to the back of the list.
|
||||
*
|
||||
* @param pxList Pointer to the list being initialised.
|
||||
*
|
||||
* \page vListInitialise vListInitialise
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Must be called before a list item is used. This sets the list container to
|
||||
* null so the item does not think that it is already contained in a list.
|
||||
*
|
||||
* @param pxItem Pointer to the list item being initialised.
|
||||
*
|
||||
* \page vListInitialiseItem vListInitialiseItem
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted into the list in
|
||||
* a position determined by its item value (descending item value order).
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The item that is to be placed in the list.
|
||||
*
|
||||
* \page vListInsert vListInsert
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Insert a list item into a list. The item will be inserted in a position
|
||||
* such that it will be the last item within the list returned by multiple
|
||||
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||
*
|
||||
* The list member pxIndex is used to walk through a list. Calling
|
||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
|
||||
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||
* in the list position pointed to by pxIndex. This means that every other
|
||||
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||
* the pxIndex parameter again points to the item being inserted.
|
||||
*
|
||||
* @param pxList The list into which the item is to be inserted.
|
||||
*
|
||||
* @param pxNewListItem The list item to be inserted into the list.
|
||||
*
|
||||
* \page vListInsertEnd vListInsertEnd
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Remove an item from a list. The list item has a pointer to the list that
|
||||
* it is in, so only the list item need be passed into the function.
|
||||
*
|
||||
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||
* the list pointed to by it's pxContainer parameter.
|
||||
*
|
||||
* @return The number of items that remain in the list after the list item has
|
||||
* been removed.
|
||||
*
|
||||
* \page uxListRemove uxListRemove
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
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!
|
||||
*/
|
||||
|
||||
/*
|
||||
* When the MPU is used the standard (non MPU) API functions are mapped to
|
||||
* equivalents that start "MPU_", the prototypes for which are defined in this
|
||||
* header files. This will cause the application code to call the MPU_ version
|
||||
* which wraps the non-MPU version with privilege promoting then demoting code,
|
||||
* so the kernel code always runs will full privileges.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MPU_PROTOTYPES_H
|
||||
#define MPU_PROTOTYPES_H
|
||||
|
||||
/* MPU versions of tasks.h API function. */
|
||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask );
|
||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer );
|
||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask );
|
||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
|
||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete );
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay );
|
||||
void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement );
|
||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask );
|
||||
UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t xTask );
|
||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask );
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
|
||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
|
||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend );
|
||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume );
|
||||
void MPU_vTaskStartScheduler( void );
|
||||
void MPU_vTaskSuspendAll( void );
|
||||
BaseType_t MPU_xTaskResumeAll( void );
|
||||
TickType_t MPU_xTaskGetTickCount( void );
|
||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void );
|
||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery );
|
||||
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery );
|
||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
|
||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask );
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue );
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex );
|
||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
|
||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void );
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime );
|
||||
void MPU_vTaskList( char * pcWriteBuffer );
|
||||
void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer );
|
||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue );
|
||||
BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
|
||||
uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
|
||||
BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask );
|
||||
BaseType_t MPU_xTaskIncrementTick( void );
|
||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void );
|
||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut );
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait );
|
||||
void MPU_vTaskMissedYield( void );
|
||||
BaseType_t MPU_xTaskGetSchedulerState( void );
|
||||
|
||||
/* MPU versions of queue.h API function. */
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition );
|
||||
BaseType_t MPU_xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek );
|
||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue );
|
||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue );
|
||||
void MPU_vQueueDelete( QueueHandle_t xQueue );
|
||||
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType );
|
||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue );
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount );
|
||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue );
|
||||
void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore );
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait );
|
||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex );
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName );
|
||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue );
|
||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue );
|
||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType );
|
||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType );
|
||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength );
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
|
||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet );
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait );
|
||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue );
|
||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber );
|
||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue );
|
||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue );
|
||||
|
||||
/* MPU versions of timers.h API function. */
|
||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction );
|
||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer );
|
||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer );
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );
|
||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void );
|
||||
BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );
|
||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer );
|
||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer );
|
||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer );
|
||||
BaseType_t MPU_xTimerCreateTimerTask( void );
|
||||
BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait );
|
||||
|
||||
/* MPU versions of event_group.h API function. */
|
||||
EventGroupHandle_t MPU_xEventGroupCreate( void );
|
||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer );
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait );
|
||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||
UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup );
|
||||
|
||||
#endif /* MPU_PROTOTYPES_H */
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
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 MPU_WRAPPERS_H
|
||||
#define MPU_WRAPPERS_H
|
||||
|
||||
/* This file redefines API functions to be called through a wrapper macro, but
|
||||
only for ports that are using the MPU. */
|
||||
#ifdef portUSING_MPU_WRAPPERS
|
||||
|
||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||
included from queue.c or task.c to prevent it from having an effect within
|
||||
those files. */
|
||||
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
/*
|
||||
* Map standard (non MPU) API functions to equivalents that start
|
||||
* "MPU_". This will cause the application code to call the MPU_
|
||||
* version, which wraps the non-MPU version with privilege promoting
|
||||
* then demoting code, so the kernel code always runs will full
|
||||
* privileges.
|
||||
*/
|
||||
|
||||
/* Map standard tasks.h API functions to the MPU equivalents. */
|
||||
#define xTaskCreate MPU_xTaskCreate
|
||||
#define xTaskCreateStatic MPU_xTaskCreateStatic
|
||||
#define xTaskCreateRestricted MPU_xTaskCreateRestricted
|
||||
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||
#define vTaskDelete MPU_vTaskDelete
|
||||
#define vTaskDelay MPU_vTaskDelay
|
||||
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
||||
#define xTaskAbortDelay MPU_xTaskAbortDelay
|
||||
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||
#define eTaskGetState MPU_eTaskGetState
|
||||
#define vTaskGetInfo MPU_vTaskGetInfo
|
||||
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||
#define vTaskSuspend MPU_vTaskSuspend
|
||||
#define vTaskResume MPU_vTaskResume
|
||||
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||
#define pcTaskGetName MPU_pcTaskGetName
|
||||
#define xTaskGetHandle MPU_xTaskGetHandle
|
||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer
|
||||
#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer
|
||||
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||
#define vTaskList MPU_vTaskList
|
||||
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||
#define xTaskGenericNotify MPU_xTaskGenericNotify
|
||||
#define xTaskNotifyWait MPU_xTaskNotifyWait
|
||||
#define ulTaskNotifyTake MPU_ulTaskNotifyTake
|
||||
#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear
|
||||
|
||||
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||
#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState
|
||||
#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut
|
||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||
|
||||
/* Map standard queue.h API functions to the MPU equivalents. */
|
||||
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||
#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable
|
||||
#define vQueueDelete MPU_vQueueDelete
|
||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||
#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic
|
||||
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||
#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic
|
||||
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder
|
||||
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||
#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic
|
||||
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||
|
||||
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||
#define pcQueueGetName MPU_pcQueueGetName
|
||||
#endif
|
||||
|
||||
/* Map standard timer.h API functions to the MPU equivalents. */
|
||||
#define xTimerCreate MPU_xTimerCreate
|
||||
#define xTimerCreateStatic MPU_xTimerCreateStatic
|
||||
#define pvTimerGetTimerID MPU_pvTimerGetTimerID
|
||||
#define vTimerSetTimerID MPU_vTimerSetTimerID
|
||||
#define xTimerIsTimerActive MPU_xTimerIsTimerActive
|
||||
#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle
|
||||
#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall
|
||||
#define pcTimerGetName MPU_pcTimerGetName
|
||||
#define xTimerGetPeriod MPU_xTimerGetPeriod
|
||||
#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime
|
||||
#define xTimerGenericCommand MPU_xTimerGenericCommand
|
||||
|
||||
/* Map standard event_group.h API functions to the MPU equivalents. */
|
||||
#define xEventGroupCreate MPU_xEventGroupCreate
|
||||
#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic
|
||||
#define xEventGroupWaitBits MPU_xEventGroupWaitBits
|
||||
#define xEventGroupClearBits MPU_xEventGroupClearBits
|
||||
#define xEventGroupSetBits MPU_xEventGroupSetBits
|
||||
#define xEventGroupSync MPU_xEventGroupSync
|
||||
#define vEventGroupDelete MPU_vEventGroupDelete
|
||||
|
||||
/* Remove the privileged function macro. */
|
||||
#define PRIVILEGED_FUNCTION
|
||||
|
||||
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
/* Ensure API functions go in the privileged execution section. */
|
||||
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||
|
||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||
|
||||
#else /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
#define PRIVILEGED_FUNCTION
|
||||
#define PRIVILEGED_DATA
|
||||
#define portUSING_MPU_WRAPPERS 0
|
||||
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
|
||||
|
||||
#endif /* MPU_WRAPPERS_H */
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
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!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Portable layer API. Each function must be defined for each port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#ifndef PORTABLE_H
|
||||
#define PORTABLE_H
|
||||
|
||||
/* Each FreeRTOS port has a unique portmacro.h header file. Originally a
|
||||
pre-processor definition was used to ensure the pre-processor found the correct
|
||||
portmacro.h file for the port being used. That scheme was deprecated in favour
|
||||
of setting the compiler's include path such that it found the correct
|
||||
portmacro.h file - removing the need for the constant and allowing the
|
||||
portmacro.h file to be located anywhere in relation to the port being used.
|
||||
Purely for reasons of backward compatibility the old method is still valid, but
|
||||
to make it clear that new projects should not use it, support for the port
|
||||
specific constants has been moved into the deprecated_definitions.h header
|
||||
file. */
|
||||
#include "deprecated_definitions.h"
|
||||
|
||||
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
|
||||
did not result in a portmacro.h header file being included - and it should be
|
||||
included here. In this case the path to the correct portmacro.h header file
|
||||
must be set in the compiler's include path. */
|
||||
#ifndef portENTER_CRITICAL
|
||||
#include "portmacro.h"
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 32
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x001f )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 16
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x000f )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 8
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 4
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 2
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||
#endif
|
||||
|
||||
#if portBYTE_ALIGNMENT == 1
|
||||
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||
#endif
|
||||
|
||||
#ifndef portBYTE_ALIGNMENT_MASK
|
||||
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||
#endif
|
||||
|
||||
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mpu_wrappers.h"
|
||||
|
||||
/*
|
||||
* Setup the stack of a new task so it is ready to be placed under the
|
||||
* scheduler control. The registers have to be placed on the stack in
|
||||
* the order that the port expects to find them.
|
||||
*
|
||||
*/
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||
#else
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* Used by heap_5.c. */
|
||||
typedef struct HeapRegion
|
||||
{
|
||||
uint8_t *pucStartAddress;
|
||||
size_t xSizeInBytes;
|
||||
} HeapRegion_t;
|
||||
|
||||
/*
|
||||
* Used to define multiple heap regions for use by heap_5.c. This function
|
||||
* must be called before any calls to pvPortMalloc() - not creating a task,
|
||||
* queue, semaphore, mutex, software timer, event group, etc. will result in
|
||||
* pvPortMalloc being called.
|
||||
*
|
||||
* pxHeapRegions passes in an array of HeapRegion_t structures - each of which
|
||||
* defines a region of memory that can be used as the heap. The array is
|
||||
* terminated by a HeapRegions_t structure that has a size of 0. The region
|
||||
* with the lowest start address must appear first in the array.
|
||||
*/
|
||||
static void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/*
|
||||
* Map to the memory management routines required for the port.
|
||||
*/
|
||||
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Setup the hardware ready for the scheduler to take control. This generally
|
||||
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||
* the hardware is left in its original condition after the scheduler stops
|
||||
* executing.
|
||||
*/
|
||||
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* The structures and methods of manipulating the MPU are contained within the
|
||||
* port layer.
|
||||
*
|
||||
* Fills the xMPUSettings structure with the memory region information
|
||||
* contained in xRegions.
|
||||
*/
|
||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||
struct xMEMORY_REGION;
|
||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTABLE_H */
|
||||
|
|
@ -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!
|
||||
*/
|
||||
|
||||
#ifndef PROJDEFS_H
|
||||
#define PROJDEFS_H
|
||||
|
||||
/*
|
||||
* Defines the prototype to which task functions must conform. Defined in this
|
||||
* file to ensure the type is known before portable.h is included.
|
||||
*/
|
||||
typedef void (*TaskFunction_t)( void * );
|
||||
|
||||
/* Converts a time in milliseconds to a time in ticks. This macro can be
|
||||
overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
|
||||
definition here is not suitable for your application. */
|
||||
#ifndef pdMS_TO_TICKS
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
||||
#endif
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||
|
||||
/* FreeRTOS error definitions. */
|
||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||
#define errQUEUE_BLOCKED ( -4 )
|
||||
#define errQUEUE_YIELD ( -5 )
|
||||
|
||||
/* Macros used for basic data corruption checks. */
|
||||
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
|
||||
#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0
|
||||
#endif
|
||||
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a
|
||||
#else
|
||||
#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL
|
||||
#endif
|
||||
|
||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
|
||||
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
|
||||
#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
|
||||
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
|
||||
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
|
||||
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
|
||||
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
|
||||
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
|
||||
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
|
||||
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
|
||||
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
|
||||
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
|
||||
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
|
||||
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
|
||||
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
|
||||
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
|
||||
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
|
||||
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
|
||||
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
|
||||
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
|
||||
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
|
||||
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
|
||||
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
|
||||
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
|
||||
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
|
||||
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
|
||||
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
|
||||
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
|
||||
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
|
||||
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
|
||||
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
|
||||
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
|
||||
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
|
||||
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
|
||||
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
|
||||
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
|
||||
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
|
||||
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
|
||||
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
|
||||
|
||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
|
||||
itself. */
|
||||
#define pdFREERTOS_LITTLE_ENDIAN 0
|
||||
#define pdFREERTOS_BIG_ENDIAN 1
|
||||
|
||||
#endif /* PROJDEFS_H */
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
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